From d5bf18d324106b4cc03486348e1b45311c98938a Mon Sep 17 00:00:00 2001 From: zhuxiaojiong <645680426@qq.com> Date: Sat, 28 Jun 2025 09:51:49 +0800 Subject: [PATCH] init --- .gitattributes | 5 + .gitignore | 258 +++ README.md | 2 + code/.dockerignore | 25 + code/CommonWorker/CommonWorker.csproj | 71 + code/CommonWorker/Config/SystemConfig.cs | 15 + code/CommonWorker/Dockerfile | 23 + code/CommonWorker/Dto/ResPassTimeDto.cs | 21 + code/CommonWorker/Dto/UserModuleApiModel.cs | 23 + code/CommonWorker/Program.cs | 85 + .../Properties/launchSettings.json | 16 + code/CommonWorker/Serilog.Production.json | 33 + code/CommonWorker/Serilog.json | 33 + .../Workers/CustomerPassTimeWorker.cs | 251 ++ code/CommonWorker/appsettings.Disaster.json | 30 + code/CommonWorker/appsettings.Production.json | 30 + code/CommonWorker/appsettings.json | 31 + code/DG.Kafka.Worker/BatchKafkaWorkerBase.cs | 67 + code/DG.Kafka.Worker/DG.Kafka.Worker.csproj | 21 + code/DG.Kafka.Worker/IKafkaWorkerManager.cs | 15 + code/DG.Kafka.Worker/IWorkerManager.cs | 15 + code/DG.Kafka.Worker/KafkaWorkerBase.cs | 70 + code/DG.Kafka.Worker/KafkaWorkerManager.cs | 63 + .../ServiceCollectionExtensions.cs | 45 + code/DG.Kafka.Worker/TaskConfig.cs | 31 + code/DG.Kafka.Worker/WorkerManager.cs | 69 + code/DG.Kafka/Consumer.cs | 18 + code/DG.Kafka/DG.Kafka.csproj | 21 + code/DG.Kafka/IKafkaProducer.cs | 13 + code/DG.Kafka/KafkaClient.cs | 220 ++ code/DG.Kafka/KafkaProducer.cs | 47 + code/DG.Kafka/ServiceCollectionExtensions.cs | 25 + .../Config/SystemConfig.cs | 16 + .../EmployeeDepartmentDetailServices.csproj | 57 + .../EmployeeDepartmentDetailWorker/Program.cs | 91 + .../Properties/launchSettings.json | 16 + .../Serilog.PreProduction.json | 33 + .../Serilog.Production.json | 33 + .../Serilog.json | 33 + .../Worker/SynchronousWorker.cs | 452 ++++ .../appsettings.PreProduction.json | 27 + .../appsettings.Production.json | 27 + .../appsettings.json | 28 + code/NuGet.Config | 6 + .../Config/Properties/launchSettings.json | 16 + .../ResourceFlowWorker/Config/SystemConfig.cs | 13 + code/ResourceFlowWorker/Dockerfile | 23 + code/ResourceFlowWorker/Dockerfile.original | 23 + code/ResourceFlowWorker/Dto/LivePageDto.cs | 35 + .../Dto/ResourceFlowCustomerAndUserDto.cs | 17 + .../Dto/ResourceFlowWorkerDto.cs | 72 + code/ResourceFlowWorker/Program.cs | 67 + .../Properties/launchSettings.json | 16 + .../ResourceFlowWorker.csproj | 82 + .../Serilog.Production.json | 33 + code/ResourceFlowWorker/Serilog.json | 33 + .../Workers/ResourceWorker.cs | 306 +++ .../appsettings.Disaster.json | 23 + .../appsettings.Production.json | 22 + code/ResourceFlowWorker/appsettings.json | 22 + code/ToDoWorker/Config/SystemConfig.cs | 14 + code/ToDoWorker/Dockerfile | 23 + code/ToDoWorker/Domain/EventDomain.cs | 495 ++++ code/ToDoWorker/Domain/IEventDomain.cs | 35 + code/ToDoWorker/Dto/CustomerEmployeeMap.cs | 28 + code/ToDoWorker/Dto/EventDto.cs | 58 + code/ToDoWorker/Dto/ToDoItemSetting.cs | 109 + code/ToDoWorker/Helper/EventEnum.cs | 36 + code/ToDoWorker/Helper/SeqIdGen.cs | 165 ++ code/ToDoWorker/Program.cs | 79 + .../ToDoWorker/Properties/launchSettings.json | 16 + code/ToDoWorker/Serilog.Production.json | 33 + code/ToDoWorker/Serilog.json | 33 + code/ToDoWorker/ToDoWorker - Backup.csproj | 10 + code/ToDoWorker/ToDoWorker.csproj | 75 + .../ToDoWorker/Workers/ActionConsumeWorker.cs | 157 ++ code/ToDoWorker/Workers/RepairDataWorker.cs | 76 + code/ToDoWorker/Workers/ToDoWorker.cs | 84 + code/ToDoWorker/appsettings.Production.json | 43 + code/ToDoWorker/appsettings.json | 50 + code/WeworkUserWorker/Config/SystemConfig.cs | 14 + code/WeworkUserWorker/Dockerfile | 23 + code/WeworkUserWorker/Dto/ZXDApiResult.cs | 15 + code/WeworkUserWorker/Program.cs | 89 + .../Properties/launchSettings.json | 16 + code/WeworkUserWorker/Serilog.Production.json | 33 + code/WeworkUserWorker/Serilog.json | 33 + code/WeworkUserWorker/WeworkUserWorker.csproj | 71 + .../Workers/WeworkTagWorker.cs | 723 ++++++ code/WeworkUserWorker/Workers/WeworkWorker.cs | 723 ++++++ .../appsettings.Disaster.json | 30 + .../appsettings.Production.json | 46 + code/WeworkUserWorker/appsettings.json | 52 + code/Zxd.Core.Domain/ActivityDomain.cs | 31 + code/Zxd.Core.Domain/CacheDomain.cs | 76 + code/Zxd.Core.Domain/Config/CacheKeys.cs | 33 + code/Zxd.Core.Domain/Config/ClientKey.cs | 13 + code/Zxd.Core.Domain/Config/Enum.cs | 191 ++ code/Zxd.Core.Domain/Config/SystemConfig.cs | 177 ++ code/Zxd.Core.Domain/CustomerDomain.cs | 338 +++ code/Zxd.Core.Domain/DeptmentDomain.cs | 100 + .../Dto/Activity/GetActivityNameRequest.cs | 13 + .../Dto/AddVirtualProductDto.cs | 33 + code/Zxd.Core.Domain/Dto/AssignQuery.cs | 94 + .../Dto/Contract/ContractResultView.cs | 87 + .../Dto/Crm/BaseProductInfoDto.cs | 51 + .../Dto/Crm/ChangeProductStatusDto.cs | 16 + .../Dto/Crm/CreateFinishedProductDetailDto.cs | 36 + .../Dto/Crm/CreateFinishedProductDto.cs | 138 ++ .../Dto/Crm/CreateProductCodeDto.cs | 15 + .../Dto/Crm/CreateProductDto.cs | 150 ++ .../Dto/Crm/CreateProductPackageDto.cs | 101 + .../Dto/Crm/CreateProductTeacherDto.cs | 45 + .../Dto/Crm/CreateStandardProductDto.cs | 18 + .../Dto/Crm/CreateSuperProductPackageDto.cs | 58 + .../Dto/Crm/DroplistEnumDto.cs | 19 + .../Dto/Crm/EditFinishedProductDto.cs | 128 ++ .../Dto/Crm/FinishedCustomPriceDto.cs | 15 + .../Dto/Crm/FinishedGiveProductDto.cs | 19 + .../Dto/Crm/FinishedProductDetailDto.cs | 235 ++ .../Dto/Crm/FinishedProductDto.cs | 87 + code/Zxd.Core.Domain/Dto/Crm/ProductDto.cs | 67 + .../Dto/Crm/ProductModuleInfo.cs | 15 + .../Dto/Crm/ProductPackageDto.cs | 52 + code/Zxd.Core.Domain/Dto/Crm/ResTagAddDto.cs | 21 + .../Dto/Crm/SearchFinishedProductDto.cs | 47 + .../Dto/Crm/SearchProductDto.cs | 19 + .../Dto/Crm/SearchProductPackageDto.cs | 19 + .../Dto/Crm/SearchStandardProductDto.cs | 17 + .../Dto/Crm/StandardProductDto.cs | 65 + .../Dto/Crm/StandardProductInfoDto.cs | 47 + .../Zxd.Core.Domain/Dto/Crm/WwHhuserEidDto.cs | 15 + .../Dto/Dncmsbase/DeptStatistcsDto.cs | 19 + .../Dto/Dncmsbase/MonthAttentionDto.cs | 17 + .../Dto/Dncmsbase/WeWorkUser2EidDto.cs | 25 + .../ImportanceItem/CustomerBehaviorLogDto.cs | 29 + .../CustomerBehaviorStatisticsDto.cs | 17 + .../SearchCustomerBehaviorLogDto.cs | 22 + .../Dto/Resource/GroupPageDto.cs | 61 + .../Dto/Resource/WxworkResponse.cs | 20 + code/Zxd.Core.Domain/Dto/SalesLeadDto.cs | 31 + .../Zxd.Core.Domain/Dto/SsoOrganizationDto.cs | 42 + code/Zxd.Core.Domain/Dto/SsoStaffDto.cs | 15 + .../Dto/TodoItem/EditReadRequest.cs | 13 + .../Dto/TodoItem/GetEventTypeSelectRequest.cs | 13 + .../Dto/TodoItem/GetListRequest.cs | 33 + .../Dto/TodoItem/TodoItemDto.cs | 50 + code/Zxd.Core.Domain/Dto/UserInfoDto.cs | 29 + .../Dto/Wework/WwUserExtuserDto.cs | 16 + .../Dto/Wework/WwUserExtuserIdDto.cs | 15 + .../Dto/Wework/WwUserFollowDto.cs | 43 + .../Dto/WxResource/ResourceConfigCreateDto.cs | 38 + .../Dto/WxResource/SearchSourceTaskDto.cs | 105 + .../Dto/WxResource/UserGroupQueryDto.cs | 105 + .../Dto/Zxd/Callback/BindOrderDto.cs | 117 + .../Dto/Zxd/CreateMeetingAccessoryDto.cs | 31 + .../Dto/Zxd/CreateOrEditActiveDto.cs | 39 + .../Dto/Zxd/CreateOrEditMeetingDto.cs | 52 + .../Dto/Zxd/CreateOrEditProducGiftDto.cs | 38 + .../Dto/Zxd/EarlyWarningDetailDto.cs | 87 + .../Dto/Zxd/EarlyWarningGroupDto.cs | 34 + .../Dto/Zxd/EarlyWarningLogDto.cs | 68 + .../Dto/Zxd/EarlyWarningResourceDto.cs | 44 + .../Dto/Zxd/ExternalUserTotalDto.cs | 36 + code/Zxd.Core.Domain/Dto/Zxd/InneruserDto.cs | 17 + .../Dto/Zxd/MeetingAccessoryDto.cs | 68 + code/Zxd.Core.Domain/Dto/Zxd/MeetingDto.cs | 63 + .../Dto/Zxd/MeetingParticipantDto.cs | 19 + .../Dto/Zxd/Order/BindListDto.cs | 63 + .../Dto/Zxd/Order/ImportGiftOrderDto.cs | 36 + .../Dto/Zxd/Order/OrderChangeDto.cs | 47 + .../Dto/Zxd/Order/ResPassTimeDto.cs | 13 + .../Dto/Zxd/Order/SearchBindListDto.cs | 66 + code/Zxd.Core.Domain/Dto/Zxd/OrderDto.cs | 121 + .../Dto/Zxd/ProductActiveDto.cs | 37 + .../Dto/Zxd/QwWeiSide/SearchOrderDto.cs | 29 + .../Dto/Zxd/SearchEarlyWarningLogDto.cs | 36 + .../Dto/Zxd/SearchExternalUserTotalDto.cs | 26 + .../Dto/Zxd/SearchMeetingDto.cs | 56 + .../Zxd.Core.Domain/Dto/Zxd/SearchOrderDto.cs | 126 ++ .../Dto/Zxd/SubProductGiftDto.cs | 49 + .../Dto/Zxd/UpdateEarlyWarningStatusDto.cs | 18 + code/Zxd.Core.Domain/Dto/retMsg.cs | 22 + code/Zxd.Core.Domain/EarlyWarningDomain.cs | 461 ++++ code/Zxd.Core.Domain/FinishedProductDomain.cs | 634 ++++++ code/Zxd.Core.Domain/Impl/IActivityDomain.cs | 14 + code/Zxd.Core.Domain/Impl/ICacheDomain.cs | 19 + code/Zxd.Core.Domain/Impl/ICustomerDomain.cs | 59 + code/Zxd.Core.Domain/Impl/IDeptmentDomain.cs | 16 + .../Impl/IEarlyWarningDomain.cs | 23 + .../Impl/IFinishedProductDomain.cs | 31 + .../Impl/IImportanceItemDomain.cs | 15 + code/Zxd.Core.Domain/Impl/IInneruserDomain.cs | 18 + code/Zxd.Core.Domain/Impl/IMeetingDomain.cs | 15 + code/Zxd.Core.Domain/Impl/IOrderDomain.cs | 29 + code/Zxd.Core.Domain/Impl/IProdcutDomain.cs | 72 + .../Impl/IStandardProductDomain.cs | 17 + .../Zxd.Core.Domain/Impl/IStatisticsDomain.cs | 14 + code/Zxd.Core.Domain/Impl/ITodoItemDomain.cs | 34 + code/Zxd.Core.Domain/Impl/IUserInfoDomain.cs | 30 + .../Zxd.Core.Domain/Impl/IWxResourceDomain.cs | 23 + code/Zxd.Core.Domain/ImportanceItemDomain.cs | 128 ++ code/Zxd.Core.Domain/InneruserDomain.cs | 277 +++ code/Zxd.Core.Domain/MeetingDomain.cs | 232 ++ code/Zxd.Core.Domain/OrderBindDomain.cs | 443 ++++ code/Zxd.Core.Domain/OrderDomain.cs | 50 + code/Zxd.Core.Domain/ProductDomain.cs | 2012 +++++++++++++++++ .../Response/AddVirtualProductResult.cs | 20 + .../Response/SaleClusResult.cs | 20 + code/Zxd.Core.Domain/Response/SaleRelation.cs | 23 + .../Response/UsercenterResponse.cs | 17 + code/Zxd.Core.Domain/Sso/SsoDepartment.cs | 29 + code/Zxd.Core.Domain/Sso/SsoEmployee.cs | 25 + .../Sso/SsoEmployeeDepartment.cs | 18 + code/Zxd.Core.Domain/Sso/SsoOrganization.cs | 36 + code/Zxd.Core.Domain/Sso/SsoResult.cs | 29 + code/Zxd.Core.Domain/Sso/SsoUserTokenInfo.cs | 18 + code/Zxd.Core.Domain/StandardProductDomain.cs | 265 +++ code/Zxd.Core.Domain/StatisticsDomain.cs | 103 + code/Zxd.Core.Domain/TodoItemDomain.cs | 439 ++++ code/Zxd.Core.Domain/UserInfoDomain.cs | 240 ++ code/Zxd.Core.Domain/WeworkUserDomain.cs | 22 + code/Zxd.Core.Domain/WxResourceDomain.cs | 282 +++ code/Zxd.Core.Domain/Zxd.Core.Domain.csproj | 76 + code/Zxd.Core.Shared/CommonApiResult.cs | 15 + code/Zxd.Core.Shared/Dto/DeptmentDto.cs | 36 + code/Zxd.Core.Shared/Dto/WeWorkTagDto.cs | 32 + code/Zxd.Core.Shared/Dto/WeworkWorkerDto.cs | 22 + code/Zxd.Core.Shared/Helpers/ApiDockHelper.cs | 327 +++ code/Zxd.Core.Shared/Helpers/ConvertHelper.cs | 228 ++ code/Zxd.Core.Shared/Helpers/LogHelper.cs | 143 ++ .../Zxd.Core.Shared/Helpers/SecurityHelper.cs | 43 + .../Helpers/ValidationHelper.cs | 133 ++ code/Zxd.Core.Shared/Zxd.Core.Shared.csproj | 15 + .../Controllers/ActivityController.cs | 53 + .../Controllers/BaseController.cs | 11 + .../Controllers/BaseSsoController.cs | 94 + .../Controllers/CallbackController.cs | 169 ++ .../Controllers/ContractController.cs | 32 + .../Controllers/CustomerController.cs | 161 ++ .../Controllers/DeptmentController.cs | 43 + .../Controllers/EarlyWarningController.cs | 75 + .../Controllers/FinishedProductController.cs | 159 ++ .../Controllers/ImportanceItemController.cs | 40 + .../Controllers/InneruserController.cs | 36 + .../Controllers/MeetingController.cs | 62 + .../Controllers/OrderController.cs | 99 + .../Controllers/ProductController.cs | 246 ++ .../Controllers/QwWebSideController.cs | 46 + .../Controllers/StandardProductController.cs | 83 + .../Controllers/StatisticsController.cs | 21 + .../Controllers/TodoItemController.cs | 58 + .../Controllers/UserInfoController.cs | 40 + .../Controllers/WeWorkController.cs | 40 + .../Controllers/WeWorkResourceController.cs | 79 + code/Zxd.Core.WebApi/Dockerfile | 25 + code/Zxd.Core.WebApi/Program.cs | 133 ++ .../Properties/launchSettings.json | 39 + code/Zxd.Core.WebApi/ReadMe.md | 11 + code/Zxd.Core.WebApi/Serilog.Production.json | 33 + code/Zxd.Core.WebApi/Serilog.json | 33 + .../Workers/EarlyWarningWorker.cs | 39 + .../Workers/ProductSyncWorker.cs | 34 + code/Zxd.Core.WebApi/Workers/SsoWorker.cs | 30 + .../Zxd.Core.WebApi/Workers/TodoItemWorker.cs | 34 + code/Zxd.Core.WebApi/Zxd.Core.WebApi.csproj | 77 + .../Zxd.Core.WebApi/appsettings.Disaster.json | 153 ++ .../appsettings.Production.json | 157 ++ code/Zxd.Core.WebApi/appsettings.json | 142 ++ code/Zxd.Core.sln | 160 ++ code/Zxd.Crm.Domain/AssignRuleDomain.cs | 291 +++ code/Zxd.Crm.Domain/CacheDomain.cs | 99 + code/Zxd.Crm.Domain/Config/CacheKeys.cs | 34 + code/Zxd.Crm.Domain/Config/ClientKey.cs | 13 + code/Zxd.Crm.Domain/Config/Enum.cs | 191 ++ code/Zxd.Crm.Domain/Config/SystemConfig.cs | 84 + code/Zxd.Crm.Domain/Config/Utility.cs | 52 + .../Dto/AssignRule/AssignRuleQueryDto.cs | 225 ++ code/Zxd.Crm.Domain/Dto/BindAppUserDto.cs | 21 + code/Zxd.Crm.Domain/Dto/CreateFieldDto.cs | 66 + .../Dto/CreateOrUpdateUserSettingDto.cs | 17 + .../Zxd.Crm.Domain/Dto/CreateTableFieldDto.cs | 23 + code/Zxd.Crm.Domain/Dto/DeptmentDto.cs | 66 + .../Dto/Extuser/ExtUserCreateDto.cs | 16 + code/Zxd.Crm.Domain/Dto/GetDeptMentDto.cs | 24 + code/Zxd.Crm.Domain/Dto/GetEmpowermentDto.cs | 49 + .../Dto/GetProductByAppidDto.cs | 15 + .../Dto/GetWarnningTemplateDto.cs | 207 ++ .../Dto/QWOnlinePay/ActProductCreateDto.cs | 117 + .../Dto/QWOnlinePay/ActivityCreateDto.cs | 60 + code/Zxd.Crm.Domain/Dto/SetEmpowermentDto.cs | 48 + .../Dto/TableFieldSettingDto.cs | 40 + code/Zxd.Crm.Domain/Dto/UserInfoDto.cs | 15 + .../Dto/UserTableFieldSettingDto.cs | 25 + code/Zxd.Crm.Domain/ExtuserDomain.cs | 60 + code/Zxd.Crm.Domain/FieldDomain.cs | 200 ++ .../Impl/AssignRule/IAssignRuleDomain.cs | 25 + code/Zxd.Crm.Domain/Impl/ICacheDomain.cs | 21 + code/Zxd.Crm.Domain/Impl/IExtuserDomain.cs | 16 + code/Zxd.Crm.Domain/Impl/IFieldDomain.cs | 20 + .../Zxd.Crm.Domain/Impl/ISSOEmployeeDomain.cs | 35 + code/Zxd.Crm.Domain/Impl/IUserInfoDomain.cs | 14 + code/Zxd.Crm.Domain/Impl/IWarnningDomain.cs | 30 + .../Impl/IWeworkUserWorkerDomain.cs | 20 + .../Impl/QwOnlinePay/IQwOnlinePayDomain.cs | 35 + code/Zxd.Crm.Domain/QwOnlinePayDomain.cs | 418 ++++ code/Zxd.Crm.Domain/SSOEmployeeDomain.cs | 945 ++++++++ code/Zxd.Crm.Domain/UserInfoDomain.cs | 48 + code/Zxd.Crm.Domain/WarnningDomain.cs | 460 ++++ code/Zxd.Crm.Domain/WeworkUserWorkerDomain.cs | 25 + code/Zxd.Crm.Domain/Zxd.Crm.Domain.csproj | 52 + .../Controllers/AssignRuleController.cs | 81 + .../Controllers/BaseController.cs | 9 + .../Controllers/ExtuserController.cs | 29 + .../Controllers/FieldController.cs | 75 + .../Controllers/ProductController.cs | 81 + .../Controllers/QwOnlinePayController.cs | 99 + .../Controllers/SSOController.cs | 138 ++ .../Controllers/UserInfoController.cs | 27 + .../Controllers/WarnningController.cs | 131 ++ .../Controllers/WeworkUserWorkerController.cs | 28 + code/Zxd.Crm.WebApi/Dockerfile | 26 + code/Zxd.Crm.WebApi/Program.cs | 119 + .../Properties/launchSettings.json | 39 + code/Zxd.Crm.WebApi/Readme.md | 8 + code/Zxd.Crm.WebApi/Serilog.Production.json | 33 + code/Zxd.Crm.WebApi/Serilog.json | 33 + .../Workers/AssignRuleWorker.cs | 33 + .../Workers/EmployeeSyncWorker.cs | 33 + code/Zxd.Crm.WebApi/Workers/SSOTempWorker.cs | 29 + code/Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj | 60 + code/Zxd.Crm.WebApi/appsettings.Disaster.json | 76 + .../appsettings.Production.json | 76 + code/Zxd.Crm.WebApi/appsettings.json | 79 + code/Zxd.Domain/BasParameterDomain.cs | 35 + code/Zxd.Domain/BaseRoleDomain.cs | 28 + code/Zxd.Domain/Config/CacheKeys.cs | 33 + code/Zxd.Domain/Config/ClientKey.cs | 13 + code/Zxd.Domain/Config/Enum.cs | 191 ++ code/Zxd.Domain/Config/SystemConfig.cs | 78 + code/Zxd.Domain/DeptmentDomain.cs | 63 + code/Zxd.Domain/Dto/AssignQuery.cs | 94 + code/Zxd.Domain/Dto/Exents/SYNC_PUSH_DTO.cs | 16 + code/Zxd.Domain/Dto/Resource/CheckUserDTO.cs | 155 ++ code/Zxd.Domain/Dto/Resource/CmsRequestDto.cs | 41 + code/Zxd.Domain/Dto/Resource/ReSourceDto.cs | 15 + .../Dto/Resource/ResAllocationDto.cs | 81 + .../Dto/Resource/ScreenRecordDto.cs | 49 + .../Zxd.Domain/Dto/Resource/SyncRegUserDto.cs | 80 + code/Zxd.Domain/Dto/SalesLeadDto.cs | 31 + code/Zxd.Domain/Dto/UserInfoDto.cs | 30 + code/Zxd.Domain/Dto/retMsg.cs | 22 + .../Events/JoinActiveAllDeptEvent.cs | 26 + .../EventBuses/Events/JoinActiveEvent.cs | 24 + .../Events/SoftUserRegisterEvent.cs | 24 + code/Zxd.Domain/Impl/IBasParameterDomain.cs | 16 + code/Zxd.Domain/Impl/IBasRoseDomain.cs | 14 + code/Zxd.Domain/Impl/IDeptmentDomain.cs | 13 + code/Zxd.Domain/Impl/IReSourceDomain.cs | 36 + code/Zxd.Domain/Impl/IRegUserDomain.cs | 17 + code/Zxd.Domain/Impl/IResCustomerDomain.cs | 18 + code/Zxd.Domain/Impl/IScreenRecordDomain.cs | 16 + code/Zxd.Domain/Impl/ISystemConfigDomain.cs | 9 + code/Zxd.Domain/Impl/IUserInfoDomain.cs | 16 + code/Zxd.Domain/ReSourceDomain.cs | 922 ++++++++ code/Zxd.Domain/RegUserDomain.cs | 216 ++ code/Zxd.Domain/ResCustomerDomain.cs | 105 + code/Zxd.Domain/Response/SaleClusResult.cs | 20 + code/Zxd.Domain/Response/SaleRelation.cs | 23 + code/Zxd.Domain/ScreenRecordDomain.cs | 230 ++ code/Zxd.Domain/Sso/SsoDepartment.cs | 29 + code/Zxd.Domain/Sso/SsoEmployee.cs | 25 + code/Zxd.Domain/Sso/SsoEmployeeDepartment.cs | 18 + code/Zxd.Domain/Sso/SsoOrganization.cs | 36 + code/Zxd.Domain/Sso/SsoResult.cs | 29 + code/Zxd.Domain/Sso/SsoUserTokenInfo.cs | 18 + code/Zxd.Domain/SystemConfigDomain.cs | 31 + code/Zxd.Domain/UserInfoDomain.cs | 84 + code/Zxd.Domain/Zxd.Domain.csproj | 61 + code/Zxd.Entity/Action/CustomerBehaviorLog.cs | 80 + .../Action/EmployeeDepartmentDetail.cs | 25 + code/Zxd.Entity/Action/EmployeeTodoitem.cs | 86 + code/Zxd.Entity/Action/Eventdwd.cs | 66 + .../Zxd.Entity/CompanyBaseConf/Application.cs | 24 + .../CompanyBaseConf/ApplicationDepartment.cs | 20 + code/Zxd.Entity/CompanyBaseConf/Department.cs | 36 + .../CompanyBaseConf/DepartmentCrmconf.cs | 30 + code/Zxd.Entity/CompanyBaseConf/Employee.cs | 22 + .../CompanyBaseConf/EmployeeDepartment.cs | 21 + .../EmployeeDepartmentDetail.cs | 23 + code/Zxd.Entity/Crm/Module.cs | 43 + code/Zxd.Entity/Crm/Product.cs | 65 + code/Zxd.Entity/Crm/ProductGroup.cs | 23 + code/Zxd.Entity/Crm/ProductPackage.cs | 88 + code/Zxd.Entity/Crm/ProductTeacher.cs | 36 + code/Zxd.Entity/Crm/Teacher.cs | 25 + code/Zxd.Entity/Crm/UserModule.cs | 25 + code/Zxd.Entity/DbEnums.cs | 116 + code/Zxd.Entity/Dncms/Assign.cs | 68 + code/Zxd.Entity/Dncms/AssignRules.cs | 76 + code/Zxd.Entity/Dncms/Department.cs | 38 + code/Zxd.Entity/Dncms/Deptment.cs | 46 + code/Zxd.Entity/Dncms/DeptmentCampainId.cs | 35 + .../Dncms/EmployeeDepartmentDetail.cs | 26 + .../Dncms/EmployeeDepartmentFull.cs | 20 + code/Zxd.Entity/Dncms/ResCutomerPassTime.cs | 43 + .../Dncms/ResResidWeworkEventLog.cs | 25 + code/Zxd.Entity/Dncms/ResResidWeworkUser.cs | 47 + code/Zxd.Entity/Dncms/ResourceFlowConfig.cs | 66 + .../Dncms/ResourceFlowConfigFrom.cs | 50 + code/Zxd.Entity/Dncms/ResourceFlowConfigTo.cs | 49 + .../Zxd.Entity/Dncms/ResourceFlowDimission.cs | 36 + code/Zxd.Entity/Dncms/ResourceFlowLog.cs | 72 + code/Zxd.Entity/Dncms/ResourceProtectInfo.cs | 34 + code/Zxd.Entity/Dncms/WeworkAgent.cs | 23 + code/Zxd.Entity/Dncms/WeworkExternalUser.cs | 23 + .../Dncms/WeworkExternalUserTotal.cs | 42 + code/Zxd.Entity/Dncms/Wx_Szzyorder_log.cs | 53 + code/Zxd.Entity/Dncms/resourcetag.cs | 27 + code/Zxd.Entity/Dncms/weworkuser2eid.cs | 100 + code/Zxd.Entity/HgAction/Department.cs | 39 + .../Zxd.Entity/HgAction/EmployeeDepartment.cs | 22 + .../HgAction/EmployeeDepartmentDetail.cs | 26 + .../HgAction/EmployeeDepartmentFull.cs | 20 + code/Zxd.Entity/SSO/Department.cs | 23 + code/Zxd.Entity/SSO/DepartmentCrmConf.cs | 20 + code/Zxd.Entity/SSO/Employee.cs | 25 + code/Zxd.Entity/SSO/EmployeeDepartment.cs | 20 + code/Zxd.Entity/Sql/20221111.txt | 14 + code/Zxd.Entity/UserCenter/UserInfo.cs | 49 + code/Zxd.Entity/Wework/WwUserExtuser.cs | 17 + code/Zxd.Entity/Zxd.Entity.csproj | 21 + code/Zxd.Entity/Zxd/BAS_INNERUSER.cs | 54 + code/Zxd.Entity/Zxd/BAS_INNERUSERSALT.cs | 25 + code/Zxd.Entity/Zxd/BAS_PARAMETER.cs | 35 + code/Zxd.Entity/Zxd/BAS_ROLE.cs | 33 + code/Zxd.Entity/Zxd/BasCompanyChannel.cs | 20 + code/Zxd.Entity/Zxd/Bas_CompanyChannel.cs | 17 + code/Zxd.Entity/Zxd/BaseProduct.cs | 59 + code/Zxd.Entity/Zxd/BaseProductPackage.cs | 51 + .../Zxd/BaseProductPackageRelation.cs | 33 + code/Zxd.Entity/Zxd/CMS_QIWEI_POSTLOG.cs | 34 + code/Zxd.Entity/Zxd/CreateCustomerDto.cs | 33 + code/Zxd.Entity/Zxd/Department.cs | 39 + code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_DICT.cs | 20 + code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_LOG.cs | 17 + code/Zxd.Entity/Zxd/EarlyWarningLog.cs | 80 + code/Zxd.Entity/Zxd/EarlyWarningSetting.cs | 43 + code/Zxd.Entity/Zxd/EarlyWarningTemplate.cs | 58 + code/Zxd.Entity/Zxd/EarlyWarningUser.cs | 58 + code/Zxd.Entity/Zxd/Employee.cs | 25 + .../Zxd/EmployeeDepartmentDetail.cs | 29 + code/Zxd.Entity/Zxd/EmployeeDepartmentFull.cs | 20 + .../Zxd/Employee_Department_Detail.cs | 17 + code/Zxd.Entity/Zxd/FieldSetting.cs | 28 + code/Zxd.Entity/Zxd/FinishedProduct.cs | 135 ++ code/Zxd.Entity/Zxd/L2SOFTORDER.cs | 86 + code/Zxd.Entity/Zxd/Meeting.cs | 57 + code/Zxd.Entity/Zxd/MeetingAccessory.cs | 38 + code/Zxd.Entity/Zxd/MeetingParticipant.cs | 26 + .../Zxd/Order/WX_SZZYORDERDEPOSIT.cs | 43 + .../Zxd.Entity/Zxd/Order/WX_SZZYORDER_BIND.cs | 82 + .../Zxd/Order/WX_SzzyOrderRefund.cs | 55 + .../Zxd/Order/Wx_SzzyOrder_HandGift.cs | 65 + .../Zxd/QiweiOnlePay/QWActivityProduct.cs | 27 + .../Zxd/QiweiOnlePay/QiWeiActivity.cs | 30 + .../Zxd/QiweiOnlePay/QiWeiActivityDept.cs | 22 + code/Zxd.Entity/Zxd/RES_APPLY.cs | 55 + code/Zxd.Entity/Zxd/RES_CUSTOMER.cs | 18 + code/Zxd.Entity/Zxd/RES_CUSTOMERDETAIL.cs | 37 + code/Zxd.Entity/Zxd/RES_CUSTOMERUSER.cs | 19 + code/Zxd.Entity/Zxd/RES_MOBILE_MD5.cs | 12 + code/Zxd.Entity/Zxd/RES_RESOURCEMOBILE.cs | 16 + code/Zxd.Entity/Zxd/Res_Tag.cs | 36 + code/Zxd.Entity/Zxd/SMS_MESSAGE.cs | 34 + code/Zxd.Entity/Zxd/SMS_MSGSUBTYPE.cs | 47 + code/Zxd.Entity/Zxd/SMS_MSGTYPE_CLIENT.cs | 33 + code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND.cs | 21 + code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND_LOG.cs | 20 + code/Zxd.Entity/Zxd/SOFT_USER.cs | 68 + code/Zxd.Entity/Zxd/ScreenRecord.cs | 107 + code/Zxd.Entity/Zxd/Soft_User_CH.cs | 17 + code/Zxd.Entity/Zxd/Soft_Userinfo_Sub.cs | 24 + code/Zxd.Entity/Zxd/StandardProduct.cs | 34 + code/Zxd.Entity/Zxd/TableField.cs | 42 + code/Zxd.Entity/Zxd/WW_EXTUSER_RESID.cs | 34 + code/Zxd.Entity/Zxd/WX_EMPOWER_LOG.cs | 26 + code/Zxd.Entity/Zxd/WX_SZZYORDER.cs | 279 +++ code/Zxd.Entity/Zxd/WxCanopenorder.cs | 12 + code/Zxd.Entity/Zxd/WxOrderActive.cs | 35 + code/Zxd.Entity/Zxd/WxSzzyProduct.cs | 40 + code/Zxd.Entity/Zxd/WxSzzySubProductGift.cs | 29 + code/Zxd.Entity/Zxd/WxSzzySubproduct.cs | 29 + code/Zxd.Entity/Zxd/WxSzzySubproductCh.cs | 22 + code/Zxd.Entity/dim/CustomerEmployee.cs | 182 ++ .../CompanyBaseConfDbContext.cs | 40 + code/Zxd.EntityFramework/CrmCloudDbContext.cs | 47 + code/Zxd.EntityFramework/CrmDbContext.cs | 73 + .../Zxd.EntityFramework/DgActionsDbContext.cs | 32 + code/Zxd.EntityFramework/DncmsDbContext.cs | 55 + .../Zxd.EntityFramework/DncmsbaseDbContext.cs | 60 + code/Zxd.EntityFramework/HgActionDbContext.cs | 38 + code/Zxd.EntityFramework/SSODbContext.cs | 38 + .../UserCenterDbContext.cs | 34 + .../Zxd.EntityFramework.csproj | 26 + code/Zxd.EntityFramework/ZxdDbContext.cs | 163 ++ code/Zxd.SqlSugar/InitConfiguration.cs | 66 + code/Zxd.SqlSugar/InitDB.cs | 35 + .../Zxd.SqlSugar/Zxd - Backup.SqlSugar.csproj | 9 + code/Zxd.SqlSugar/Zxd.SqlSugar.csproj | 21 + code/Zxd.WebApi/.config/dotnet-tools.json | 12 + code/Zxd.WebApi/AssignUserDomain.cs | 75 + .../Controllers/AssignUserController.cs | 28 + code/Zxd.WebApi/Controllers/BaseController.cs | 12 + .../Controllers/DeptmentController.cs | 20 + .../Controllers/ReSourceController.cs | 47 + .../Controllers/ScreenRecordController.cs | 47 + .../Controllers/SoftUserController.cs | 115 + code/Zxd.WebApi/Controllers/TestController.cs | 92 + code/Zxd.WebApi/Dockerfile | 22 + code/Zxd.WebApi/Dto/AssignModel.cs | 23 + code/Zxd.WebApi/Impl/IAssignUserDomain.cs | 11 + code/Zxd.WebApi/Program.cs | 115 + .../Zxd.WebApi/Properties/launchSettings.json | 40 + code/Zxd.WebApi/Readme.md | 6 + code/Zxd.WebApi/Serilog.Production.json | 33 + code/Zxd.WebApi/Serilog.json | 33 + code/Zxd.WebApi/Zxd.WebApi.csproj | 58 + code/Zxd.WebApi/appsettings.Disaster.json | 74 + code/Zxd.WebApi/appsettings.Production.json | 81 + code/Zxd.WebApi/appsettings.json | 82 + test/Zxd.Core.Test/UnitTest1.cs | 43 + test/Zxd.Core.Test/Usings.cs | 8 + test/Zxd.Core.Test/Zxd.Core.Test.csproj | 34 + test/Zxd.Core.Test/appsettings.json | 54 + 535 files changed, 37355 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 code/.dockerignore create mode 100644 code/CommonWorker/CommonWorker.csproj create mode 100644 code/CommonWorker/Config/SystemConfig.cs create mode 100644 code/CommonWorker/Dockerfile create mode 100644 code/CommonWorker/Dto/ResPassTimeDto.cs create mode 100644 code/CommonWorker/Dto/UserModuleApiModel.cs create mode 100644 code/CommonWorker/Program.cs create mode 100644 code/CommonWorker/Properties/launchSettings.json create mode 100644 code/CommonWorker/Serilog.Production.json create mode 100644 code/CommonWorker/Serilog.json create mode 100644 code/CommonWorker/Workers/CustomerPassTimeWorker.cs create mode 100644 code/CommonWorker/appsettings.Disaster.json create mode 100644 code/CommonWorker/appsettings.Production.json create mode 100644 code/CommonWorker/appsettings.json create mode 100644 code/DG.Kafka.Worker/BatchKafkaWorkerBase.cs create mode 100644 code/DG.Kafka.Worker/DG.Kafka.Worker.csproj create mode 100644 code/DG.Kafka.Worker/IKafkaWorkerManager.cs create mode 100644 code/DG.Kafka.Worker/IWorkerManager.cs create mode 100644 code/DG.Kafka.Worker/KafkaWorkerBase.cs create mode 100644 code/DG.Kafka.Worker/KafkaWorkerManager.cs create mode 100644 code/DG.Kafka.Worker/ServiceCollectionExtensions.cs create mode 100644 code/DG.Kafka.Worker/TaskConfig.cs create mode 100644 code/DG.Kafka.Worker/WorkerManager.cs create mode 100644 code/DG.Kafka/Consumer.cs create mode 100644 code/DG.Kafka/DG.Kafka.csproj create mode 100644 code/DG.Kafka/IKafkaProducer.cs create mode 100644 code/DG.Kafka/KafkaClient.cs create mode 100644 code/DG.Kafka/KafkaProducer.cs create mode 100644 code/DG.Kafka/ServiceCollectionExtensions.cs create mode 100644 code/EmployeeDepartmentDetailWorker/Config/SystemConfig.cs create mode 100644 code/EmployeeDepartmentDetailWorker/EmployeeDepartmentDetailServices.csproj create mode 100644 code/EmployeeDepartmentDetailWorker/Program.cs create mode 100644 code/EmployeeDepartmentDetailWorker/Properties/launchSettings.json create mode 100644 code/EmployeeDepartmentDetailWorker/Serilog.PreProduction.json create mode 100644 code/EmployeeDepartmentDetailWorker/Serilog.Production.json create mode 100644 code/EmployeeDepartmentDetailWorker/Serilog.json create mode 100644 code/EmployeeDepartmentDetailWorker/Worker/SynchronousWorker.cs create mode 100644 code/EmployeeDepartmentDetailWorker/appsettings.PreProduction.json create mode 100644 code/EmployeeDepartmentDetailWorker/appsettings.Production.json create mode 100644 code/EmployeeDepartmentDetailWorker/appsettings.json create mode 100644 code/NuGet.Config create mode 100644 code/ResourceFlowWorker/Config/Properties/launchSettings.json create mode 100644 code/ResourceFlowWorker/Config/SystemConfig.cs create mode 100644 code/ResourceFlowWorker/Dockerfile create mode 100644 code/ResourceFlowWorker/Dockerfile.original create mode 100644 code/ResourceFlowWorker/Dto/LivePageDto.cs create mode 100644 code/ResourceFlowWorker/Dto/ResourceFlowCustomerAndUserDto.cs create mode 100644 code/ResourceFlowWorker/Dto/ResourceFlowWorkerDto.cs create mode 100644 code/ResourceFlowWorker/Program.cs create mode 100644 code/ResourceFlowWorker/Properties/launchSettings.json create mode 100644 code/ResourceFlowWorker/ResourceFlowWorker.csproj create mode 100644 code/ResourceFlowWorker/Serilog.Production.json create mode 100644 code/ResourceFlowWorker/Serilog.json create mode 100644 code/ResourceFlowWorker/Workers/ResourceWorker.cs create mode 100644 code/ResourceFlowWorker/appsettings.Disaster.json create mode 100644 code/ResourceFlowWorker/appsettings.Production.json create mode 100644 code/ResourceFlowWorker/appsettings.json create mode 100644 code/ToDoWorker/Config/SystemConfig.cs create mode 100644 code/ToDoWorker/Dockerfile create mode 100644 code/ToDoWorker/Domain/EventDomain.cs create mode 100644 code/ToDoWorker/Domain/IEventDomain.cs create mode 100644 code/ToDoWorker/Dto/CustomerEmployeeMap.cs create mode 100644 code/ToDoWorker/Dto/EventDto.cs create mode 100644 code/ToDoWorker/Dto/ToDoItemSetting.cs create mode 100644 code/ToDoWorker/Helper/EventEnum.cs create mode 100644 code/ToDoWorker/Helper/SeqIdGen.cs create mode 100644 code/ToDoWorker/Program.cs create mode 100644 code/ToDoWorker/Properties/launchSettings.json create mode 100644 code/ToDoWorker/Serilog.Production.json create mode 100644 code/ToDoWorker/Serilog.json create mode 100644 code/ToDoWorker/ToDoWorker - Backup.csproj create mode 100644 code/ToDoWorker/ToDoWorker.csproj create mode 100644 code/ToDoWorker/Workers/ActionConsumeWorker.cs create mode 100644 code/ToDoWorker/Workers/RepairDataWorker.cs create mode 100644 code/ToDoWorker/Workers/ToDoWorker.cs create mode 100644 code/ToDoWorker/appsettings.Production.json create mode 100644 code/ToDoWorker/appsettings.json create mode 100644 code/WeworkUserWorker/Config/SystemConfig.cs create mode 100644 code/WeworkUserWorker/Dockerfile create mode 100644 code/WeworkUserWorker/Dto/ZXDApiResult.cs create mode 100644 code/WeworkUserWorker/Program.cs create mode 100644 code/WeworkUserWorker/Properties/launchSettings.json create mode 100644 code/WeworkUserWorker/Serilog.Production.json create mode 100644 code/WeworkUserWorker/Serilog.json create mode 100644 code/WeworkUserWorker/WeworkUserWorker.csproj create mode 100644 code/WeworkUserWorker/Workers/WeworkTagWorker.cs create mode 100644 code/WeworkUserWorker/Workers/WeworkWorker.cs create mode 100644 code/WeworkUserWorker/appsettings.Disaster.json create mode 100644 code/WeworkUserWorker/appsettings.Production.json create mode 100644 code/WeworkUserWorker/appsettings.json create mode 100644 code/Zxd.Core.Domain/ActivityDomain.cs create mode 100644 code/Zxd.Core.Domain/CacheDomain.cs create mode 100644 code/Zxd.Core.Domain/Config/CacheKeys.cs create mode 100644 code/Zxd.Core.Domain/Config/ClientKey.cs create mode 100644 code/Zxd.Core.Domain/Config/Enum.cs create mode 100644 code/Zxd.Core.Domain/Config/SystemConfig.cs create mode 100644 code/Zxd.Core.Domain/CustomerDomain.cs create mode 100644 code/Zxd.Core.Domain/DeptmentDomain.cs create mode 100644 code/Zxd.Core.Domain/Dto/Activity/GetActivityNameRequest.cs create mode 100644 code/Zxd.Core.Domain/Dto/AddVirtualProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/AssignQuery.cs create mode 100644 code/Zxd.Core.Domain/Dto/Contract/ContractResultView.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/BaseProductInfoDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/ChangeProductStatusDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDetailDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateProductCodeDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateProductPackageDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateProductTeacherDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateStandardProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/CreateSuperProductPackageDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/DroplistEnumDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/EditFinishedProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/FinishedCustomPriceDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/FinishedGiveProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/FinishedProductDetailDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/FinishedProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/ProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/ProductModuleInfo.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/ProductPackageDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/ResTagAddDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/SearchFinishedProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/SearchProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/SearchProductPackageDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/SearchStandardProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/StandardProductDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/StandardProductInfoDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Crm/WwHhuserEidDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Dncmsbase/DeptStatistcsDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Dncmsbase/MonthAttentionDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Dncmsbase/WeWorkUser2EidDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorLogDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorStatisticsDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/ImportanceItem/SearchCustomerBehaviorLogDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Resource/GroupPageDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Resource/WxworkResponse.cs create mode 100644 code/Zxd.Core.Domain/Dto/SalesLeadDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/SsoOrganizationDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/SsoStaffDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/TodoItem/EditReadRequest.cs create mode 100644 code/Zxd.Core.Domain/Dto/TodoItem/GetEventTypeSelectRequest.cs create mode 100644 code/Zxd.Core.Domain/Dto/TodoItem/GetListRequest.cs create mode 100644 code/Zxd.Core.Domain/Dto/TodoItem/TodoItemDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/UserInfoDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserIdDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Wework/WwUserFollowDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/WxResource/ResourceConfigCreateDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/WxResource/SearchSourceTaskDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/WxResource/UserGroupQueryDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/Callback/BindOrderDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/CreateMeetingAccessoryDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditActiveDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditMeetingDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditProducGiftDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningDetailDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningGroupDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningLogDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningResourceDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/ExternalUserTotalDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/InneruserDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/MeetingAccessoryDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/MeetingDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/MeetingParticipantDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/Order/BindListDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/Order/ImportGiftOrderDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/Order/OrderChangeDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/Order/ResPassTimeDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/Order/SearchBindListDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/OrderDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/ProductActiveDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/QwWeiSide/SearchOrderDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/SearchEarlyWarningLogDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/SearchExternalUserTotalDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/SearchMeetingDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/SearchOrderDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/SubProductGiftDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/Zxd/UpdateEarlyWarningStatusDto.cs create mode 100644 code/Zxd.Core.Domain/Dto/retMsg.cs create mode 100644 code/Zxd.Core.Domain/EarlyWarningDomain.cs create mode 100644 code/Zxd.Core.Domain/FinishedProductDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IActivityDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/ICacheDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/ICustomerDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IDeptmentDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IEarlyWarningDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IFinishedProductDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IImportanceItemDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IInneruserDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IMeetingDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IOrderDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IProdcutDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IStandardProductDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IStatisticsDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/ITodoItemDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IUserInfoDomain.cs create mode 100644 code/Zxd.Core.Domain/Impl/IWxResourceDomain.cs create mode 100644 code/Zxd.Core.Domain/ImportanceItemDomain.cs create mode 100644 code/Zxd.Core.Domain/InneruserDomain.cs create mode 100644 code/Zxd.Core.Domain/MeetingDomain.cs create mode 100644 code/Zxd.Core.Domain/OrderBindDomain.cs create mode 100644 code/Zxd.Core.Domain/OrderDomain.cs create mode 100644 code/Zxd.Core.Domain/ProductDomain.cs create mode 100644 code/Zxd.Core.Domain/Response/AddVirtualProductResult.cs create mode 100644 code/Zxd.Core.Domain/Response/SaleClusResult.cs create mode 100644 code/Zxd.Core.Domain/Response/SaleRelation.cs create mode 100644 code/Zxd.Core.Domain/Response/UsercenterResponse.cs create mode 100644 code/Zxd.Core.Domain/Sso/SsoDepartment.cs create mode 100644 code/Zxd.Core.Domain/Sso/SsoEmployee.cs create mode 100644 code/Zxd.Core.Domain/Sso/SsoEmployeeDepartment.cs create mode 100644 code/Zxd.Core.Domain/Sso/SsoOrganization.cs create mode 100644 code/Zxd.Core.Domain/Sso/SsoResult.cs create mode 100644 code/Zxd.Core.Domain/Sso/SsoUserTokenInfo.cs create mode 100644 code/Zxd.Core.Domain/StandardProductDomain.cs create mode 100644 code/Zxd.Core.Domain/StatisticsDomain.cs create mode 100644 code/Zxd.Core.Domain/TodoItemDomain.cs create mode 100644 code/Zxd.Core.Domain/UserInfoDomain.cs create mode 100644 code/Zxd.Core.Domain/WeworkUserDomain.cs create mode 100644 code/Zxd.Core.Domain/WxResourceDomain.cs create mode 100644 code/Zxd.Core.Domain/Zxd.Core.Domain.csproj create mode 100644 code/Zxd.Core.Shared/CommonApiResult.cs create mode 100644 code/Zxd.Core.Shared/Dto/DeptmentDto.cs create mode 100644 code/Zxd.Core.Shared/Dto/WeWorkTagDto.cs create mode 100644 code/Zxd.Core.Shared/Dto/WeworkWorkerDto.cs create mode 100644 code/Zxd.Core.Shared/Helpers/ApiDockHelper.cs create mode 100644 code/Zxd.Core.Shared/Helpers/ConvertHelper.cs create mode 100644 code/Zxd.Core.Shared/Helpers/LogHelper.cs create mode 100644 code/Zxd.Core.Shared/Helpers/SecurityHelper.cs create mode 100644 code/Zxd.Core.Shared/Helpers/ValidationHelper.cs create mode 100644 code/Zxd.Core.Shared/Zxd.Core.Shared.csproj create mode 100644 code/Zxd.Core.WebApi/Controllers/ActivityController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/BaseController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/BaseSsoController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/CallbackController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/ContractController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/CustomerController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/DeptmentController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/EarlyWarningController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/FinishedProductController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/ImportanceItemController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/InneruserController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/MeetingController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/OrderController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/ProductController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/QwWebSideController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/StandardProductController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/StatisticsController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/TodoItemController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/UserInfoController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/WeWorkController.cs create mode 100644 code/Zxd.Core.WebApi/Controllers/WeWorkResourceController.cs create mode 100644 code/Zxd.Core.WebApi/Dockerfile create mode 100644 code/Zxd.Core.WebApi/Program.cs create mode 100644 code/Zxd.Core.WebApi/Properties/launchSettings.json create mode 100644 code/Zxd.Core.WebApi/ReadMe.md create mode 100644 code/Zxd.Core.WebApi/Serilog.Production.json create mode 100644 code/Zxd.Core.WebApi/Serilog.json create mode 100644 code/Zxd.Core.WebApi/Workers/EarlyWarningWorker.cs create mode 100644 code/Zxd.Core.WebApi/Workers/ProductSyncWorker.cs create mode 100644 code/Zxd.Core.WebApi/Workers/SsoWorker.cs create mode 100644 code/Zxd.Core.WebApi/Workers/TodoItemWorker.cs create mode 100644 code/Zxd.Core.WebApi/Zxd.Core.WebApi.csproj create mode 100644 code/Zxd.Core.WebApi/appsettings.Disaster.json create mode 100644 code/Zxd.Core.WebApi/appsettings.Production.json create mode 100644 code/Zxd.Core.WebApi/appsettings.json create mode 100644 code/Zxd.Core.sln create mode 100644 code/Zxd.Crm.Domain/AssignRuleDomain.cs create mode 100644 code/Zxd.Crm.Domain/CacheDomain.cs create mode 100644 code/Zxd.Crm.Domain/Config/CacheKeys.cs create mode 100644 code/Zxd.Crm.Domain/Config/ClientKey.cs create mode 100644 code/Zxd.Crm.Domain/Config/Enum.cs create mode 100644 code/Zxd.Crm.Domain/Config/SystemConfig.cs create mode 100644 code/Zxd.Crm.Domain/Config/Utility.cs create mode 100644 code/Zxd.Crm.Domain/Dto/AssignRule/AssignRuleQueryDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/BindAppUserDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/CreateFieldDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/CreateOrUpdateUserSettingDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/CreateTableFieldDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/DeptmentDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/Extuser/ExtUserCreateDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/GetDeptMentDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/GetEmpowermentDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/GetProductByAppidDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/GetWarnningTemplateDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActProductCreateDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActivityCreateDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/SetEmpowermentDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/TableFieldSettingDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/UserInfoDto.cs create mode 100644 code/Zxd.Crm.Domain/Dto/UserTableFieldSettingDto.cs create mode 100644 code/Zxd.Crm.Domain/ExtuserDomain.cs create mode 100644 code/Zxd.Crm.Domain/FieldDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/AssignRule/IAssignRuleDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/ICacheDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/IExtuserDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/IFieldDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/ISSOEmployeeDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/IUserInfoDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/IWarnningDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/IWeworkUserWorkerDomain.cs create mode 100644 code/Zxd.Crm.Domain/Impl/QwOnlinePay/IQwOnlinePayDomain.cs create mode 100644 code/Zxd.Crm.Domain/QwOnlinePayDomain.cs create mode 100644 code/Zxd.Crm.Domain/SSOEmployeeDomain.cs create mode 100644 code/Zxd.Crm.Domain/UserInfoDomain.cs create mode 100644 code/Zxd.Crm.Domain/WarnningDomain.cs create mode 100644 code/Zxd.Crm.Domain/WeworkUserWorkerDomain.cs create mode 100644 code/Zxd.Crm.Domain/Zxd.Crm.Domain.csproj create mode 100644 code/Zxd.Crm.WebApi/Controllers/AssignRuleController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/BaseController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/ExtuserController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/FieldController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/ProductController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/QwOnlinePayController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/SSOController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/UserInfoController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/WarnningController.cs create mode 100644 code/Zxd.Crm.WebApi/Controllers/WeworkUserWorkerController.cs create mode 100644 code/Zxd.Crm.WebApi/Dockerfile create mode 100644 code/Zxd.Crm.WebApi/Program.cs create mode 100644 code/Zxd.Crm.WebApi/Properties/launchSettings.json create mode 100644 code/Zxd.Crm.WebApi/Readme.md create mode 100644 code/Zxd.Crm.WebApi/Serilog.Production.json create mode 100644 code/Zxd.Crm.WebApi/Serilog.json create mode 100644 code/Zxd.Crm.WebApi/Workers/AssignRuleWorker.cs create mode 100644 code/Zxd.Crm.WebApi/Workers/EmployeeSyncWorker.cs create mode 100644 code/Zxd.Crm.WebApi/Workers/SSOTempWorker.cs create mode 100644 code/Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj create mode 100644 code/Zxd.Crm.WebApi/appsettings.Disaster.json create mode 100644 code/Zxd.Crm.WebApi/appsettings.Production.json create mode 100644 code/Zxd.Crm.WebApi/appsettings.json create mode 100644 code/Zxd.Domain/BasParameterDomain.cs create mode 100644 code/Zxd.Domain/BaseRoleDomain.cs create mode 100644 code/Zxd.Domain/Config/CacheKeys.cs create mode 100644 code/Zxd.Domain/Config/ClientKey.cs create mode 100644 code/Zxd.Domain/Config/Enum.cs create mode 100644 code/Zxd.Domain/Config/SystemConfig.cs create mode 100644 code/Zxd.Domain/DeptmentDomain.cs create mode 100644 code/Zxd.Domain/Dto/AssignQuery.cs create mode 100644 code/Zxd.Domain/Dto/Exents/SYNC_PUSH_DTO.cs create mode 100644 code/Zxd.Domain/Dto/Resource/CheckUserDTO.cs create mode 100644 code/Zxd.Domain/Dto/Resource/CmsRequestDto.cs create mode 100644 code/Zxd.Domain/Dto/Resource/ReSourceDto.cs create mode 100644 code/Zxd.Domain/Dto/Resource/ResAllocationDto.cs create mode 100644 code/Zxd.Domain/Dto/Resource/ScreenRecordDto.cs create mode 100644 code/Zxd.Domain/Dto/Resource/SyncRegUserDto.cs create mode 100644 code/Zxd.Domain/Dto/SalesLeadDto.cs create mode 100644 code/Zxd.Domain/Dto/UserInfoDto.cs create mode 100644 code/Zxd.Domain/Dto/retMsg.cs create mode 100644 code/Zxd.Domain/EventBuses/Events/JoinActiveAllDeptEvent.cs create mode 100644 code/Zxd.Domain/EventBuses/Events/JoinActiveEvent.cs create mode 100644 code/Zxd.Domain/EventBuses/Events/SoftUserRegisterEvent.cs create mode 100644 code/Zxd.Domain/Impl/IBasParameterDomain.cs create mode 100644 code/Zxd.Domain/Impl/IBasRoseDomain.cs create mode 100644 code/Zxd.Domain/Impl/IDeptmentDomain.cs create mode 100644 code/Zxd.Domain/Impl/IReSourceDomain.cs create mode 100644 code/Zxd.Domain/Impl/IRegUserDomain.cs create mode 100644 code/Zxd.Domain/Impl/IResCustomerDomain.cs create mode 100644 code/Zxd.Domain/Impl/IScreenRecordDomain.cs create mode 100644 code/Zxd.Domain/Impl/ISystemConfigDomain.cs create mode 100644 code/Zxd.Domain/Impl/IUserInfoDomain.cs create mode 100644 code/Zxd.Domain/ReSourceDomain.cs create mode 100644 code/Zxd.Domain/RegUserDomain.cs create mode 100644 code/Zxd.Domain/ResCustomerDomain.cs create mode 100644 code/Zxd.Domain/Response/SaleClusResult.cs create mode 100644 code/Zxd.Domain/Response/SaleRelation.cs create mode 100644 code/Zxd.Domain/ScreenRecordDomain.cs create mode 100644 code/Zxd.Domain/Sso/SsoDepartment.cs create mode 100644 code/Zxd.Domain/Sso/SsoEmployee.cs create mode 100644 code/Zxd.Domain/Sso/SsoEmployeeDepartment.cs create mode 100644 code/Zxd.Domain/Sso/SsoOrganization.cs create mode 100644 code/Zxd.Domain/Sso/SsoResult.cs create mode 100644 code/Zxd.Domain/Sso/SsoUserTokenInfo.cs create mode 100644 code/Zxd.Domain/SystemConfigDomain.cs create mode 100644 code/Zxd.Domain/UserInfoDomain.cs create mode 100644 code/Zxd.Domain/Zxd.Domain.csproj create mode 100644 code/Zxd.Entity/Action/CustomerBehaviorLog.cs create mode 100644 code/Zxd.Entity/Action/EmployeeDepartmentDetail.cs create mode 100644 code/Zxd.Entity/Action/EmployeeTodoitem.cs create mode 100644 code/Zxd.Entity/Action/Eventdwd.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/Application.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/ApplicationDepartment.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/Department.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/DepartmentCrmconf.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/Employee.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/EmployeeDepartment.cs create mode 100644 code/Zxd.Entity/CompanyBaseConf/EmployeeDepartmentDetail.cs create mode 100644 code/Zxd.Entity/Crm/Module.cs create mode 100644 code/Zxd.Entity/Crm/Product.cs create mode 100644 code/Zxd.Entity/Crm/ProductGroup.cs create mode 100644 code/Zxd.Entity/Crm/ProductPackage.cs create mode 100644 code/Zxd.Entity/Crm/ProductTeacher.cs create mode 100644 code/Zxd.Entity/Crm/Teacher.cs create mode 100644 code/Zxd.Entity/Crm/UserModule.cs create mode 100644 code/Zxd.Entity/DbEnums.cs create mode 100644 code/Zxd.Entity/Dncms/Assign.cs create mode 100644 code/Zxd.Entity/Dncms/AssignRules.cs create mode 100644 code/Zxd.Entity/Dncms/Department.cs create mode 100644 code/Zxd.Entity/Dncms/Deptment.cs create mode 100644 code/Zxd.Entity/Dncms/DeptmentCampainId.cs create mode 100644 code/Zxd.Entity/Dncms/EmployeeDepartmentDetail.cs create mode 100644 code/Zxd.Entity/Dncms/EmployeeDepartmentFull.cs create mode 100644 code/Zxd.Entity/Dncms/ResCutomerPassTime.cs create mode 100644 code/Zxd.Entity/Dncms/ResResidWeworkEventLog.cs create mode 100644 code/Zxd.Entity/Dncms/ResResidWeworkUser.cs create mode 100644 code/Zxd.Entity/Dncms/ResourceFlowConfig.cs create mode 100644 code/Zxd.Entity/Dncms/ResourceFlowConfigFrom.cs create mode 100644 code/Zxd.Entity/Dncms/ResourceFlowConfigTo.cs create mode 100644 code/Zxd.Entity/Dncms/ResourceFlowDimission.cs create mode 100644 code/Zxd.Entity/Dncms/ResourceFlowLog.cs create mode 100644 code/Zxd.Entity/Dncms/ResourceProtectInfo.cs create mode 100644 code/Zxd.Entity/Dncms/WeworkAgent.cs create mode 100644 code/Zxd.Entity/Dncms/WeworkExternalUser.cs create mode 100644 code/Zxd.Entity/Dncms/WeworkExternalUserTotal.cs create mode 100644 code/Zxd.Entity/Dncms/Wx_Szzyorder_log.cs create mode 100644 code/Zxd.Entity/Dncms/resourcetag.cs create mode 100644 code/Zxd.Entity/Dncms/weworkuser2eid.cs create mode 100644 code/Zxd.Entity/HgAction/Department.cs create mode 100644 code/Zxd.Entity/HgAction/EmployeeDepartment.cs create mode 100644 code/Zxd.Entity/HgAction/EmployeeDepartmentDetail.cs create mode 100644 code/Zxd.Entity/HgAction/EmployeeDepartmentFull.cs create mode 100644 code/Zxd.Entity/SSO/Department.cs create mode 100644 code/Zxd.Entity/SSO/DepartmentCrmConf.cs create mode 100644 code/Zxd.Entity/SSO/Employee.cs create mode 100644 code/Zxd.Entity/SSO/EmployeeDepartment.cs create mode 100644 code/Zxd.Entity/Sql/20221111.txt create mode 100644 code/Zxd.Entity/UserCenter/UserInfo.cs create mode 100644 code/Zxd.Entity/Wework/WwUserExtuser.cs create mode 100644 code/Zxd.Entity/Zxd.Entity.csproj create mode 100644 code/Zxd.Entity/Zxd/BAS_INNERUSER.cs create mode 100644 code/Zxd.Entity/Zxd/BAS_INNERUSERSALT.cs create mode 100644 code/Zxd.Entity/Zxd/BAS_PARAMETER.cs create mode 100644 code/Zxd.Entity/Zxd/BAS_ROLE.cs create mode 100644 code/Zxd.Entity/Zxd/BasCompanyChannel.cs create mode 100644 code/Zxd.Entity/Zxd/Bas_CompanyChannel.cs create mode 100644 code/Zxd.Entity/Zxd/BaseProduct.cs create mode 100644 code/Zxd.Entity/Zxd/BaseProductPackage.cs create mode 100644 code/Zxd.Entity/Zxd/BaseProductPackageRelation.cs create mode 100644 code/Zxd.Entity/Zxd/CMS_QIWEI_POSTLOG.cs create mode 100644 code/Zxd.Entity/Zxd/CreateCustomerDto.cs create mode 100644 code/Zxd.Entity/Zxd/Department.cs create mode 100644 code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_DICT.cs create mode 100644 code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_LOG.cs create mode 100644 code/Zxd.Entity/Zxd/EarlyWarningLog.cs create mode 100644 code/Zxd.Entity/Zxd/EarlyWarningSetting.cs create mode 100644 code/Zxd.Entity/Zxd/EarlyWarningTemplate.cs create mode 100644 code/Zxd.Entity/Zxd/EarlyWarningUser.cs create mode 100644 code/Zxd.Entity/Zxd/Employee.cs create mode 100644 code/Zxd.Entity/Zxd/EmployeeDepartmentDetail.cs create mode 100644 code/Zxd.Entity/Zxd/EmployeeDepartmentFull.cs create mode 100644 code/Zxd.Entity/Zxd/Employee_Department_Detail.cs create mode 100644 code/Zxd.Entity/Zxd/FieldSetting.cs create mode 100644 code/Zxd.Entity/Zxd/FinishedProduct.cs create mode 100644 code/Zxd.Entity/Zxd/L2SOFTORDER.cs create mode 100644 code/Zxd.Entity/Zxd/Meeting.cs create mode 100644 code/Zxd.Entity/Zxd/MeetingAccessory.cs create mode 100644 code/Zxd.Entity/Zxd/MeetingParticipant.cs create mode 100644 code/Zxd.Entity/Zxd/Order/WX_SZZYORDERDEPOSIT.cs create mode 100644 code/Zxd.Entity/Zxd/Order/WX_SZZYORDER_BIND.cs create mode 100644 code/Zxd.Entity/Zxd/Order/WX_SzzyOrderRefund.cs create mode 100644 code/Zxd.Entity/Zxd/Order/Wx_SzzyOrder_HandGift.cs create mode 100644 code/Zxd.Entity/Zxd/QiweiOnlePay/QWActivityProduct.cs create mode 100644 code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivity.cs create mode 100644 code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivityDept.cs create mode 100644 code/Zxd.Entity/Zxd/RES_APPLY.cs create mode 100644 code/Zxd.Entity/Zxd/RES_CUSTOMER.cs create mode 100644 code/Zxd.Entity/Zxd/RES_CUSTOMERDETAIL.cs create mode 100644 code/Zxd.Entity/Zxd/RES_CUSTOMERUSER.cs create mode 100644 code/Zxd.Entity/Zxd/RES_MOBILE_MD5.cs create mode 100644 code/Zxd.Entity/Zxd/RES_RESOURCEMOBILE.cs create mode 100644 code/Zxd.Entity/Zxd/Res_Tag.cs create mode 100644 code/Zxd.Entity/Zxd/SMS_MESSAGE.cs create mode 100644 code/Zxd.Entity/Zxd/SMS_MSGSUBTYPE.cs create mode 100644 code/Zxd.Entity/Zxd/SMS_MSGTYPE_CLIENT.cs create mode 100644 code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND.cs create mode 100644 code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND_LOG.cs create mode 100644 code/Zxd.Entity/Zxd/SOFT_USER.cs create mode 100644 code/Zxd.Entity/Zxd/ScreenRecord.cs create mode 100644 code/Zxd.Entity/Zxd/Soft_User_CH.cs create mode 100644 code/Zxd.Entity/Zxd/Soft_Userinfo_Sub.cs create mode 100644 code/Zxd.Entity/Zxd/StandardProduct.cs create mode 100644 code/Zxd.Entity/Zxd/TableField.cs create mode 100644 code/Zxd.Entity/Zxd/WW_EXTUSER_RESID.cs create mode 100644 code/Zxd.Entity/Zxd/WX_EMPOWER_LOG.cs create mode 100644 code/Zxd.Entity/Zxd/WX_SZZYORDER.cs create mode 100644 code/Zxd.Entity/Zxd/WxCanopenorder.cs create mode 100644 code/Zxd.Entity/Zxd/WxOrderActive.cs create mode 100644 code/Zxd.Entity/Zxd/WxSzzyProduct.cs create mode 100644 code/Zxd.Entity/Zxd/WxSzzySubProductGift.cs create mode 100644 code/Zxd.Entity/Zxd/WxSzzySubproduct.cs create mode 100644 code/Zxd.Entity/Zxd/WxSzzySubproductCh.cs create mode 100644 code/Zxd.Entity/dim/CustomerEmployee.cs create mode 100644 code/Zxd.EntityFramework/CompanyBaseConfDbContext.cs create mode 100644 code/Zxd.EntityFramework/CrmCloudDbContext.cs create mode 100644 code/Zxd.EntityFramework/CrmDbContext.cs create mode 100644 code/Zxd.EntityFramework/DgActionsDbContext.cs create mode 100644 code/Zxd.EntityFramework/DncmsDbContext.cs create mode 100644 code/Zxd.EntityFramework/DncmsbaseDbContext.cs create mode 100644 code/Zxd.EntityFramework/HgActionDbContext.cs create mode 100644 code/Zxd.EntityFramework/SSODbContext.cs create mode 100644 code/Zxd.EntityFramework/UserCenterDbContext.cs create mode 100644 code/Zxd.EntityFramework/Zxd.EntityFramework.csproj create mode 100644 code/Zxd.EntityFramework/ZxdDbContext.cs create mode 100644 code/Zxd.SqlSugar/InitConfiguration.cs create mode 100644 code/Zxd.SqlSugar/InitDB.cs create mode 100644 code/Zxd.SqlSugar/Zxd - Backup.SqlSugar.csproj create mode 100644 code/Zxd.SqlSugar/Zxd.SqlSugar.csproj create mode 100644 code/Zxd.WebApi/.config/dotnet-tools.json create mode 100644 code/Zxd.WebApi/AssignUserDomain.cs create mode 100644 code/Zxd.WebApi/Controllers/AssignUserController.cs create mode 100644 code/Zxd.WebApi/Controllers/BaseController.cs create mode 100644 code/Zxd.WebApi/Controllers/DeptmentController.cs create mode 100644 code/Zxd.WebApi/Controllers/ReSourceController.cs create mode 100644 code/Zxd.WebApi/Controllers/ScreenRecordController.cs create mode 100644 code/Zxd.WebApi/Controllers/SoftUserController.cs create mode 100644 code/Zxd.WebApi/Controllers/TestController.cs create mode 100644 code/Zxd.WebApi/Dockerfile create mode 100644 code/Zxd.WebApi/Dto/AssignModel.cs create mode 100644 code/Zxd.WebApi/Impl/IAssignUserDomain.cs create mode 100644 code/Zxd.WebApi/Program.cs create mode 100644 code/Zxd.WebApi/Properties/launchSettings.json create mode 100644 code/Zxd.WebApi/Readme.md create mode 100644 code/Zxd.WebApi/Serilog.Production.json create mode 100644 code/Zxd.WebApi/Serilog.json create mode 100644 code/Zxd.WebApi/Zxd.WebApi.csproj create mode 100644 code/Zxd.WebApi/appsettings.Disaster.json create mode 100644 code/Zxd.WebApi/appsettings.Production.json create mode 100644 code/Zxd.WebApi/appsettings.json create mode 100644 test/Zxd.Core.Test/UnitTest1.cs create mode 100644 test/Zxd.Core.Test/Usings.cs create mode 100644 test/Zxd.Core.Test/Zxd.Core.Test.csproj create mode 100644 test/Zxd.Core.Test/appsettings.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..908fb28 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# 2010 +*.txt -crlf + +# 2020 +*.txt text eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9807c61 --- /dev/null +++ b/.gitignore @@ -0,0 +1,258 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +*.DS_Store +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +logs/ +[Bb]in/ +[Oo]bj/ +results/ + +# Visual Studio 2015 cache/options directory +.vs/ +.vscode/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ +site/wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +!idsrv3test.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ +!tools/packages.config +tools/ + +# MacOS +.DS_Store + +# Ocelot acceptance test config +test/Ocelot.AcceptanceTests/ocelot.json + +# Read the docstates +_build/ +_static/ +_templates/ + +# JetBrains Rider +.idea/ + +# Test Results +*.trx diff --git a/README.md b/README.md new file mode 100644 index 0000000..f41f06f --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# zxd.webapi + diff --git a/code/.dockerignore b/code/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/code/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/code/CommonWorker/CommonWorker.csproj b/code/CommonWorker/CommonWorker.csproj new file mode 100644 index 0000000..1d901bd --- /dev/null +++ b/code/CommonWorker/CommonWorker.csproj @@ -0,0 +1,71 @@ + + + + Exe + net6.0 + enable + enable + Linux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + diff --git a/code/CommonWorker/Config/SystemConfig.cs b/code/CommonWorker/Config/SystemConfig.cs new file mode 100644 index 0000000..3873acd --- /dev/null +++ b/code/CommonWorker/Config/SystemConfig.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonWorker.Config +{ + public class SystemConfig + { + public string zxdCoreApi { get; set; } + public string nodeWebApi { get; set; } + public string crmCoreApi { get; set; } + } +} \ No newline at end of file diff --git a/code/CommonWorker/Dockerfile b/code/CommonWorker/Dockerfile new file mode 100644 index 0000000..45d03d4 --- /dev/null +++ b/code/CommonWorker/Dockerfile @@ -0,0 +1,23 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["CommonWorker/CommonWorker.csproj", "CommonWorker/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +RUN dotnet restore "CommonWorker/CommonWorker.csproj" +COPY . . +WORKDIR "/src/CommonWorker" +RUN dotnet build "CommonWorker.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "CommonWorker.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "CommonWorker.dll"] \ No newline at end of file diff --git a/code/CommonWorker/Dto/ResPassTimeDto.cs b/code/CommonWorker/Dto/ResPassTimeDto.cs new file mode 100644 index 0000000..783a96c --- /dev/null +++ b/code/CommonWorker/Dto/ResPassTimeDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonWorker.Dto +{ + public class ResPassTimeDto + { + public string ResId { get; set; } + } + + public class CompanyBussiness + { + public string[] soft { get; set; } + public string[] xinmeiti { get; set; } + public int? ProtectTime { get; set; } = 14; + public decimal limitPrice { get; set; } + } +} \ No newline at end of file diff --git a/code/CommonWorker/Dto/UserModuleApiModel.cs b/code/CommonWorker/Dto/UserModuleApiModel.cs new file mode 100644 index 0000000..69b2877 --- /dev/null +++ b/code/CommonWorker/Dto/UserModuleApiModel.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonWorker.Dto +{ + public class UserModuleApiModel + { + public int ret { get; set; } + public string? message { get; set; } + public Dictionary> moduelData { get; set; } + } + + public class UserModuleModel + { + public string? orderid { get; set; } + public string? productid { get; set; } + public long? start { get; set; } + public long? end { get; set; } + } +} \ No newline at end of file diff --git a/code/CommonWorker/Program.cs b/code/CommonWorker/Program.cs new file mode 100644 index 0000000..5999e26 --- /dev/null +++ b/code/CommonWorker/Program.cs @@ -0,0 +1,85 @@ +using CommonWorker.Config; +using CommonWorker.Dto; +using CommonWorker.Workers; +using DG.Kafka.Worker; +using Exceptionless; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Hosting; +using Serilog; +using Zxd.EntityFramework; + +try +{ + var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + Console.WriteLine($"Env: {env}"); + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{env ?? "Production"}.json", true) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{env ?? "Production"}.json", true) + .Build(); + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) + .WriteTo.Exceptionless(config.GetValue("Exceptionless:ApiKey"), config.GetValue("Exceptionless:ServerUrl"), new string[] { "WeworkUserWorker" }) + .CreateLogger(); + Log.Logger = logger; + Log.Information("Starting WeworkUserWorker"); + IServiceCollection services = new ServiceCollection(); + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(config); + services.AddOptions() + .Configure(e => config.GetSection("SystemConfig").Bind(e)); + ExceptionlessClient.Default.Startup(config.GetValue("Exceptionless:ApiKey")); + ExceptionlessClient.Default.Configuration.ServerUrl = config.GetValue("Exceptionless:ServerUrl"); + //services.AddRedis(config); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(config.GetConnectionString("zxdcrm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(config.GetConnectionString("dncmsbase"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("usercenter"), ServerVersion.AutoDetect(config.GetConnectionString("usercenter"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncms"), ServerVersion.AutoDetect(config.GetConnectionString("dncms"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("crm"), ServerVersion.AutoDetect(config.GetConnectionString("crm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("companyBaseConf"), ServerVersion.AutoDetect(config.GetConnectionString("companyBaseConf"))); + }); + services.AddKafkaWorker(config); + services.AddDGHttpClient(); + services.AddRegisterWorker(); + //构建容器 + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var workerManager = serviceProvider.GetRequiredService(); + await workerManager.RegisterWorker("ResPassTime"); + await workerManager.RegisterWorker("ResPassTime"); + await workerManager.RegisterWorker("ResPassTime"); + await workerManager.RegisterWorker("ResPassTime"); + await workerManager.RegisterWorker("ResPassTime"); + var builder = new HostBuilder(); + await builder.RunConsoleAsync(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/code/CommonWorker/Properties/launchSettings.json b/code/CommonWorker/Properties/launchSettings.json new file mode 100644 index 0000000..994e190 --- /dev/null +++ b/code/CommonWorker/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "profiles": { + "CommonWorker": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker (1)": { + "commandName": "Docker", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/code/CommonWorker/Serilog.Production.json b/code/CommonWorker/Serilog.Production.json new file mode 100644 index 0000000..491af8c --- /dev/null +++ b/code/CommonWorker/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} \ No newline at end of file diff --git a/code/CommonWorker/Serilog.json b/code/CommonWorker/Serilog.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/CommonWorker/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/CommonWorker/Workers/CustomerPassTimeWorker.cs b/code/CommonWorker/Workers/CustomerPassTimeWorker.cs new file mode 100644 index 0000000..f0a2e1b --- /dev/null +++ b/code/CommonWorker/Workers/CustomerPassTimeWorker.cs @@ -0,0 +1,251 @@ +using CommonWorker.Config; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Crm; +using Zxd.Entity.Dncms; +using Zxd.Entity.Zxd; +using Zxd.Entity.Zxd.Order; +using Zxd.EntityFramework; + +namespace CommonWorker.Workers +{ + internal class CustomerPassTimeWorker : KafkaWorkerBase + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + private readonly IHttpClient _httpClient; + private readonly IOptionsSnapshot _systemConfig; + + public CustomerPassTimeWorker( + IServiceProvider serviceProvider, + IOptionsSnapshot systemConfig, + ILogger logger, + IHttpClient httpClient + ) : base(logger) + { + _serviceProvider = serviceProvider; + _httpClient = httpClient; + _logger = logger; + _systemConfig = systemConfig; + } + + /// + /// 算出统计表 + /// + /// + /// + protected override async Task DoWorkAsync(ResPassTimeDto model) + { + var resList = model.ResId.Split(","); + //Log.Information($"批量计算客户过期时间{model.ResId}"); + foreach (var item in resList) + { + try + { + Log.Information($"{item}开始计算客户过期时间"); + //需要新注册实体 + using var scope = _serviceProvider.CreateAsyncScope(); + var _repository = scope.ServiceProvider.GetRequiredService>(); + var _crmRepository = scope.ServiceProvider.GetRequiredService>(); + //目前只支持一个resid + var allresid = item.Split(",").ToList(); + //订单信息 + allresid = allresid.Where(n => !string.IsNullOrWhiteSpace(n)).ToList(); + var cust = await _repository.GetRepository().Query().FirstOrDefaultAsync(n => n.RESID == item || n.UMID == item); + allresid = await _repository.GetRepository().Query().Where(n => n.CUSTOMERID == cust.CUSTOMERID && !string.IsNullOrWhiteSpace(n.RESID)) + .Select(n => n.RESID).Distinct().ToListAsync(); + var customerList = await _repository.GetRepository().Query().Where(n => allresid.Contains(n.RESID)).ToListAsync(); + + var _orderRepository = _repository.GetRepository(); + var orderList = await _orderRepository.Query().Where(n => allresid.Contains(n.RESID)).ToListAsync(); + //退款信息 按实际退款 + var refundOrderList = await _repository.GetRepository().Query() + .Where(n => allresid.Contains(n.resid) && n.auditstatus == 1 && n.isacturalrefund == 1).ToListAsync(); + //到账信息 + var orderDepositList = await _repository.GetRepository().Query() + .Where(n => allresid.Contains(n.resid) && n.auditstatus == 1).ToListAsync(); + var _userRepository = _repository.GetRepository(); + Log.Information($"实际计算客户过期时间{string.Join(",", allresid)}"); + var allsoft = _userRepository.Query().Where(m => allresid.Contains(m.RESID)).OrderBy(m => m.REGDATE).ToList();//查出所有的soft + //过期时间 + var usernameList = allsoft.Select(n => n.USERNAME).ToList(); + if (allsoft.Count == 0) + { + usernameList = orderList.Select(n => n.SOFTUSERNAME).Distinct().ToList(); + } + List passTimeList = new List(); + Log.Information($"{item}GetSoftName【{string.Join(",", usernameList)}】"); + foreach (var username in usernameList) + { + passTimeList.AddRange(await GetRootPassTime(username)); + } + + var orderidList = passTimeList.Select(n => n.orderid).ToList(); + //剔除免费订单 + var freeOrderList = await _repository.GetRepository().Query().Where(n => orderidList.Contains(n.WEBORDERID)).ToListAsync(); + var freeorderids = freeOrderList.Where(n => !n.MainOrderId.HasValue).Select(n => n.WEBORDERID).ToList(); + passTimeList = passTimeList.Where(n => !freeorderids.Contains(n.orderid)).ToList(); //不包括免费产品 + var deptCodes = orderList.GroupBy(n => new { n.Deptid, n.GroupId, n.DeptName }).Select(n => new { deptid = n.Key.Deptid, groupid = n.Key.GroupId, deptname = n.Key.DeptName }).ToList(); + var depositCodes = orderDepositList.GroupBy(n => new { n.deptid, n.groupid, n.deptName }).Select(n => new { deptid = n.Key.deptid, groupid = n.Key.groupid, deptname = n.Key.deptName }).ToList(); + var refundCodes = refundOrderList.GroupBy(n => new { n.deptid, n.groupid, n.deptName }).Select(n => new { deptid = n.Key.deptid, groupid = n.Key.groupid, deptname = n.Key.deptName }).ToList(); + deptCodes.AddRange(depositCodes); + deptCodes.AddRange(refundCodes); + deptCodes = deptCodes.Distinct().ToList(); + var protectDay = 14; //默认14天 + var softbusiness = await _repository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "SoftBusiness"); + //Log.Information($"获取配置{softbusiness.ToJson()}"); + decimal limitPrice = 500; //默认500 + if (softbusiness != null) + { + CompanyBussiness bussiness = JsonHelper.FromJson(softbusiness.PARAVALUE); + protectDay = bussiness.ProtectTime.Value; + limitPrice = bussiness.limitPrice; + } + foreach (var code in deptCodes) + { + var deptorders = orderList.Where(n => n.Deptid == code.deptid).ToList(); + var deptFreeOrder = freeOrderList.Where(n => n.MainOrderId.HasValue && n.deptid == code.deptid).ToList(); + //算出 余额 = 取流水剩余金额 + 已支付 已提交支付的订单到账金额。 + var deptDepositList = orderDepositList.Where(n => n.deptid == code.deptid).ToList(); + var lastPrice = deptDepositList.Sum(n => n.lastprice); + + var unOpenOrderStatus = new List { "200", "190" }; + var orderUsePrice = deptorders.Where(n => unOpenOrderStatus.Contains(n.ORDERSTATUS)).Sum(n => n.ARRIVALPAY); + lastPrice += orderUsePrice; + Log.Information($"{item} lastPrice:【{lastPrice}】,orderUsePrice:【{orderUsePrice}】"); + //退款信息 + var deptrefundOrderList = refundOrderList.Where(n => n.deptid == code.deptid); + //Log.Information($"查询出事业部【{code.deptid}_{code.deptname}】订单信息【{JsonHelper.ToJson(deptorders)}】流水信息{JsonHelper.ToJson(deptDepositList)}退款信息{JsonHelper.ToJson(deptrefundOrderList)}免费订单信息{JsonHelper.ToJson(deptFreeOrder)}"); + var info = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.RESID == item && n.Deptid == code.deptid); + var isInsert = false; + var customer = customerList.FirstOrDefault(n => n.RESID == item); + if (info == null) + { + isInsert = true; + info = new ResCutomerPassTime + { + Deptid = code.deptid, + GroupId = code.groupid, + DeptName = code.deptname, + RESID = item + }; + } + if (string.IsNullOrWhiteSpace(info.UMID)) + { + info.UMID = customer?.UMID; + } + info.balancepay = lastPrice; + var orderPassTime = passTimeList.Where(n => deptorders.Select(n => n.SZZYORDERID.ToString()).Contains(n.orderid) || deptFreeOrder.Select(n => n.WEBORDERID).Contains(n.orderid)).ToList(); + Log.Information($"{item}过期时间计算【{JsonHelper.ToJson(orderPassTime)}】【{JsonHelper.ToJson(info)}】"); + info.arrivalpay = deptDepositList.Sum(n => n.payprice); + info.refundpay = deptrefundOrderList.Sum(n => n.refundprice); + var paydeptDepositList = deptDepositList.Where(n => n.lastprice > 0 || n.useprice > 0).ToList(); + info.firstPayTime = paydeptDepositList.Min(n => n.audittime); + info.inpay = info.arrivalpay - info.refundpay; + if (orderPassTime.Count > 0) + { + var longtime = orderPassTime.Max(n => n.end); + info.orderpasstime = JavaLongToDateTime(longtime.Value); + } + if (info.balancepay >= limitPrice) + { + info.protecttime = Convert.ToDateTime("2050-01-01"); + } + else if (orderPassTime.Count > 0) + { + info.protecttime = info.orderpasstime.Value.AddDays(protectDay); + } + else + { + info.protecttime = null; + } + //如果净金额小于500 不予保护 + if (info.inpay < 500) + { + info.protecttime = null; + } + try + { + if (isInsert) + { + info.Ctime = DateTime.Now; + await _crmRepository.GetRepository().InsertAsync(info); + } + else + { + info.utime = DateTime.Now; + await _crmRepository.GetRepository().UpdateAsync(info); + } + Log.Information($"{item}计算结果【{JsonHelper.ToJson(info)}】"); + } + catch (Exception ex) + { + Log.Error($"计算客户过期时间错误{ex.Message}"); + } + } + //删除无关的数据 + var existCode = deptCodes.Select(n => n.deptid).ToList(); + var existItem = await _crmRepository.GetRepository().Query().Where(n => n.RESID == item && !existCode.Contains(n.Deptid)).ToListAsync(); + if (existItem.Count > 0) + { + Log.Information($"{item}待删除{string.Join(",", existItem.Select(n => n.Deptid))}"); + await _crmRepository.GetRepository().BatchDeleteAsync(existItem); + } + } + catch (Exception ex) + { + Log.Error($"{item}获取过期时间失败{ex.Message}"); + } + } + } + + private async Task> GetRootPassTime(string username) + { + List res = new List(); + var url = $"{_systemConfig.Value.nodeWebApi.Trim('/')}/order/doGetUserPerssion"; + var postJson = new + { + username = username + }; + try + { + var data = await _httpClient.PostAsync(url, postJson); + if (data.ret == 0) + { + foreach (var item in data.moduelData) + { + try + { + res.AddRange(item.Value); + } + catch (Exception ex) + { + Log.Error($"【{username}】接口获取权限数据失败{ex.Message}【{item.Value}】"); + } + } + } + } + catch (Exception ex) + { + Log.Error($"【{username}】接口获取权限数据失败{ex.Message}"); + } + return res; + } + + /// + /// + /// java长整型日期,毫秒为单位 + /// + private DateTime JavaLongToDateTime(long timeJavaLong) + { + var dt1970 = new DateTime(1970, 1, 1, 0, 0, 0); + var tricks1970 = dt1970.Ticks;//1970年1月1日刻度 + var timeTricks = tricks1970 + timeJavaLong * 10000;//日志日期刻度 + return new DateTime(timeTricks).AddHours(8);//转化为DateTime + } + } +} \ No newline at end of file diff --git a/code/CommonWorker/appsettings.Disaster.json b/code/CommonWorker/appsettings.Disaster.json new file mode 100644 index 0000000..bfd9715 --- /dev/null +++ b/code/CommonWorker/appsettings.Disaster.json @@ -0,0 +1,30 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=10.22.15.61;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=10.22.15.68;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=10.22.15.68;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Consumers": [ + { + "Host": "172.18.11.77:9092,172.18.11.76:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "TaskConfig": { + "TaskName": "Zxd.WeworkUserWorker", + "TaskRemarks": "Zxd.WeworkUserWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "X5P60jU2Iemg8YaKtp71O4YUhbFqmqgCVLfDAQRy" + }, + "SystemConfig": { + "zxdCoreApi": "http://10.22.15.163:8089", + "nodeWebApi": "http://10.22.15.5:8080" + } +} \ No newline at end of file diff --git a/code/CommonWorker/appsettings.Production.json b/code/CommonWorker/appsettings.Production.json new file mode 100644 index 0000000..474f4f1 --- /dev/null +++ b/code/CommonWorker/appsettings.Production.json @@ -0,0 +1,30 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Consumers": [ + { + "Host": "172.18.11.77:9092,172.18.11.76:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "TaskConfig": { + "TaskName": "Zxd.WeworkUserWorker", + "TaskRemarks": "Zxd.WeworkUserWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "X5P60jU2Iemg8YaKtp71O4YUhbFqmqgCVLfDAQRy" + }, + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089", + "nodeWebApi": "https://r2.soft.dn8188.com/" + } +} \ No newline at end of file diff --git a/code/CommonWorker/appsettings.json b/code/CommonWorker/appsettings.json new file mode 100644 index 0000000..d485f91 --- /dev/null +++ b/code/CommonWorker/appsettings.json @@ -0,0 +1,31 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "Consumers": [ + { + "Host": "192.168.11.104:9092,192.168.11.104:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "TaskConfig": { + "TaskName": "DG.Worker.Sample", + "TaskRemarks": "DG.Worker.Sample", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "tmrp0GmwyTMe6UxJIw7LXAcIWYKEUgy2kprMiybd" + }, + "SystemConfig": { + "zxdCoreApi": "http://192.168.11.81:8089", + "nodeWebApi": "http://120.238.224.24:10034" + } +} \ No newline at end of file diff --git a/code/DG.Kafka.Worker/BatchKafkaWorkerBase.cs b/code/DG.Kafka.Worker/BatchKafkaWorkerBase.cs new file mode 100644 index 0000000..f8a43f5 --- /dev/null +++ b/code/DG.Kafka.Worker/BatchKafkaWorkerBase.cs @@ -0,0 +1,67 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka.Worker +{ + public abstract class BatchKafkaWorkerBase + { + private readonly ILogger> _logger; + private TaskConfig _taskConfig; + private int _milliSecondsDelay; + + public BatchKafkaWorkerBase(ILogger> logger) + { + _logger = logger; + _taskConfig = KafkaClient.Default.ConfigurationManager.GetSection("TaskConfig").Get(); + if (_taskConfig == null) + { + throw new ArgumentNullException(nameof(_taskConfig)); + } + _milliSecondsDelay = _taskConfig.MilliSecondsDelay; + } + + public async Task Start(List t) + { + Stopwatch watch = new Stopwatch(); + watch.Reset(); + watch.Start(); + try + { + if (_milliSecondsDelay <= 0) + { + _logger.LogWarning($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务定时时间不能少于0!"); + return; + } + if (!_taskConfig.Enable) + { + await Task.Delay(_milliSecondsDelay); + _logger.LogWarning($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务停止启动!"); + return; + } + + await DoWorkAsync(t); + } + catch (Exception ex) + { + _logger.LogError(ex, $"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}]"); + } + watch.Stop(); + double costtime = watch.ElapsedMilliseconds; + _logger.LogDebug($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务执行结束,用时:{costtime}ms"); + } + + protected virtual async Task DoWorkAsync(List t) + { + } + + public virtual async Task ShopAsync() + { + } + } +} \ No newline at end of file diff --git a/code/DG.Kafka.Worker/DG.Kafka.Worker.csproj b/code/DG.Kafka.Worker/DG.Kafka.Worker.csproj new file mode 100644 index 0000000..556f314 --- /dev/null +++ b/code/DG.Kafka.Worker/DG.Kafka.Worker.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + True + 1.0.21 + + + + + + + + + + + + + diff --git a/code/DG.Kafka.Worker/IKafkaWorkerManager.cs b/code/DG.Kafka.Worker/IKafkaWorkerManager.cs new file mode 100644 index 0000000..189ebd1 --- /dev/null +++ b/code/DG.Kafka.Worker/IKafkaWorkerManager.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka.Worker +{ + public interface IKafkaWorkerManager + { + Task RegisterWorker(string? topic) where TWorker : KafkaWorkerBase; + + Task RegisterBatchWorker(string? topic, int batchsize = 1000) where TWorker : BatchKafkaWorkerBase; + } +} diff --git a/code/DG.Kafka.Worker/IWorkerManager.cs b/code/DG.Kafka.Worker/IWorkerManager.cs new file mode 100644 index 0000000..0b3ad7a --- /dev/null +++ b/code/DG.Kafka.Worker/IWorkerManager.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka.Worker +{ + public interface IWorkerManager + { + void DoWork(Action doWork); + + Task DoWorkAsync(Func doWork); + } +} diff --git a/code/DG.Kafka.Worker/KafkaWorkerBase.cs b/code/DG.Kafka.Worker/KafkaWorkerBase.cs new file mode 100644 index 0000000..c96dce7 --- /dev/null +++ b/code/DG.Kafka.Worker/KafkaWorkerBase.cs @@ -0,0 +1,70 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka.Worker +{ + public abstract class KafkaWorkerBase + { + private readonly ILogger> _logger; + private TaskConfig _taskConfig; + private int _milliSecondsDelay; + public KafkaWorkerBase(ILogger> logger) + { + _logger = logger; + _taskConfig = KafkaClient.Default.ConfigurationManager.GetSection("TaskConfig").Get(); + if (_taskConfig == null) + { + throw new ArgumentNullException(nameof(_taskConfig)); + } + _milliSecondsDelay = _taskConfig.MilliSecondsDelay; + } + + public async Task Start(T t) + { + Stopwatch watch = new Stopwatch(); + watch.Reset(); + watch.Start(); + _logger.LogDebug($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务开始执行1"); + try + { + + if (_milliSecondsDelay <= 0) + { + _logger.LogWarning($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务定时时间不能少于0!"); + return; + } + if (!_taskConfig.Enable) + { + await Task.Delay(_milliSecondsDelay); + _logger.LogWarning($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务停止启动!"); + return; + } + + await DoWorkAsync(t); + } + catch (Exception ex) + { + _logger.LogError(ex, $"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}]"); + } + watch.Stop(); + double costtime = watch.ElapsedMilliseconds; + _logger.LogDebug($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务执行结束,用时:{costtime}ms"); + } + + protected virtual async Task DoWorkAsync(T t) + { + } + + public virtual async Task ShopAsync() + { + + } + } +} diff --git a/code/DG.Kafka.Worker/KafkaWorkerManager.cs b/code/DG.Kafka.Worker/KafkaWorkerManager.cs new file mode 100644 index 0000000..4e3af15 --- /dev/null +++ b/code/DG.Kafka.Worker/KafkaWorkerManager.cs @@ -0,0 +1,63 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka.Worker +{ + internal class KafkaWorkerManager : IKafkaWorkerManager + { + private TaskConfig _taskConfig; + private List _consumers; + private readonly ILogger _logger; + private readonly IServiceProvider _serviceProvider; + + public KafkaWorkerManager(ILogger logger, IServiceProvider serviceProvider) + { + _logger = logger; + // 读取任务配置 + _taskConfig = KafkaClient.Default.ConfigurationManager.GetSection("TaskConfig").Get(); + _consumers = KafkaClient.Default.ConfigurationManager.GetSection("Consumers").Get>(); + if (_taskConfig == null) + { + throw new ArgumentNullException(nameof(_taskConfig)); + } + if (_consumers == null) + { + throw new ArgumentNullException(nameof(_consumers)); + } + _serviceProvider = serviceProvider; + } + + public async Task RegisterWorker(string? topic) + where TWorker : KafkaWorkerBase + { + var t = _serviceProvider.GetRequiredService(); + _logger.LogDebug($"注册worker: {typeof(TWorker).Name}"); + var consumer = _consumers.FirstOrDefault(c => c.Topic == topic); + if (consumer == null) + { + throw new ArgumentNullException(nameof(consumer)); + } + await KafkaClient.Builder(consumer, t.Start, t.ShopAsync); + } + + public async Task RegisterBatchWorker(string? topic, int batchsize = 1000) + where TWorker : BatchKafkaWorkerBase + { + var t = _serviceProvider.GetRequiredService(); + _logger.LogDebug($"注册worker: {typeof(TWorker).Name}"); + var consumer = _consumers.FirstOrDefault(c => c.Topic == topic); + if (consumer == null) + { + throw new ArgumentNullException(nameof(consumer)); + } + await KafkaClient.BatchBuilder(consumer, t.Start, t.ShopAsync, batchsize); + } + } +} diff --git a/code/DG.Kafka.Worker/ServiceCollectionExtensions.cs b/code/DG.Kafka.Worker/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..7bf8cea --- /dev/null +++ b/code/DG.Kafka.Worker/ServiceCollectionExtensions.cs @@ -0,0 +1,45 @@ +using DG.Kafka; +using DG.Kafka.Worker; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// Extensions method + /// + public static class ServiceCollectionExtensions + { + + /// + /// Redis service registered + /// + /// + /// + /// + public static IServiceCollection AddKafkaWorker(this IServiceCollection services, IConfiguration configuration) + { + services.AddKafka(configuration); + services.AddSingleton(); + services.AddSingleton(); + return services; + } + + public static IServiceCollection AddRegisterWorker(this IServiceCollection services) where TWorker : KafkaWorkerBase + { + services.AddSingleton(); + return services; + } + + public static IServiceCollection AddRegisterBatchWorker(this IServiceCollection services) where TWorker : BatchKafkaWorkerBase + { + services.AddSingleton(); + return services; + } + } +} diff --git a/code/DG.Kafka.Worker/TaskConfig.cs b/code/DG.Kafka.Worker/TaskConfig.cs new file mode 100644 index 0000000..6d9113e --- /dev/null +++ b/code/DG.Kafka.Worker/TaskConfig.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka.Worker +{ + internal class TaskConfig + { + /// + /// 任务名称 + /// + public string? TaskName { get; set; } + + /// + /// 任务备注 + /// + public string? TaskRemarks { get; set; } + + /// + /// 是否启用 + /// + public bool Enable { get; set; } + + /// + /// 停止毫秒数 + /// + public int MilliSecondsDelay { get; set; } + } +} diff --git a/code/DG.Kafka.Worker/WorkerManager.cs b/code/DG.Kafka.Worker/WorkerManager.cs new file mode 100644 index 0000000..28e07bf --- /dev/null +++ b/code/DG.Kafka.Worker/WorkerManager.cs @@ -0,0 +1,69 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; + +namespace DG.Kafka.Worker +{ + internal class WorkerManager : IWorkerManager + { + private TaskConfig _taskConfig; + private int _milliSecondsDelay; + private readonly ILogger _logger; + + public WorkerManager(ILogger logger) + { + _logger = logger; + // 读取任务配置 + _taskConfig = KafkaClient.Default.ConfigurationManager.GetSection("TaskConfig").Get(); + if (_taskConfig == null) + { + throw new ArgumentNullException(nameof(_taskConfig)); + } + _milliSecondsDelay = _taskConfig.MilliSecondsDelay; + } + + public void DoWork(Action doWork) + { + try + { + doWork(); + } + catch (Exception ex) + { + _logger.LogError(ex, $"[{DateTimeOffset.Now}] [{_taskConfig?.TaskName}] 获取配置失败!"); + + return; + } + } + + public async Task DoWorkAsync(Func doWork) + { + while(true) + { + _logger.LogDebug($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务开始执行11"); + try + { + if (_milliSecondsDelay <= 0) + { + _logger.LogWarning($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务定时时间不能少于0!"); + continue; + } + if (!_taskConfig.Enable) + { + await Task.Delay(_milliSecondsDelay); + _logger.LogWarning($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务停止启动!"); + continue; + } + + // 执行主逻辑 + await doWork(); + } + catch (Exception ex) + { + _logger.LogError(ex, $"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}]"); + } + _logger.LogDebug($"[{DateTimeOffset.Now}] [{_taskConfig.TaskName}] 任务执行结束"); + await Task.Delay(_milliSecondsDelay); + } + } + } +} \ No newline at end of file diff --git a/code/DG.Kafka/Consumer.cs b/code/DG.Kafka/Consumer.cs new file mode 100644 index 0000000..a87ff7e --- /dev/null +++ b/code/DG.Kafka/Consumer.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka +{ + public class Consumer + { + public string? Host { get; set; } + + public string? GroupId { get; set; } + + public string Topic { get; set; } + public string? TypeName { get; set; } + } +} \ No newline at end of file diff --git a/code/DG.Kafka/DG.Kafka.csproj b/code/DG.Kafka/DG.Kafka.csproj new file mode 100644 index 0000000..adde5e4 --- /dev/null +++ b/code/DG.Kafka/DG.Kafka.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + True + 1.0.18 + + + + + + + + + + + + + diff --git a/code/DG.Kafka/IKafkaProducer.cs b/code/DG.Kafka/IKafkaProducer.cs new file mode 100644 index 0000000..3f9bf34 --- /dev/null +++ b/code/DG.Kafka/IKafkaProducer.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DG.Kafka +{ + public interface IKafkaProducer + { + Task ProduceAsync(string? topic, TMessage message); + } +} diff --git a/code/DG.Kafka/KafkaClient.cs b/code/DG.Kafka/KafkaClient.cs new file mode 100644 index 0000000..b404f8f --- /dev/null +++ b/code/DG.Kafka/KafkaClient.cs @@ -0,0 +1,220 @@ +using Confluent.Kafka; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; + +namespace DG.Kafka +{ + public class KafkaClient + { + /// + /// 是否停止服务 + /// + public static bool Shop { get; set; } = false; + + public void ReadFromConfiguration(IConfiguration configuration) + { + ConfigurationManager = configuration; + } + + public IConfiguration ConfigurationManager { get; private set; } + + private static readonly Lazy _defaultClient = new(() => new KafkaClient()); + + public static KafkaClient Default + { + get { return _defaultClient.Value; } + } + + + private static List _consumers { get; set; } = new List(); + + public static List GetConsumers() + { + _consumers = Default.ConfigurationManager.GetSection("Consumers").Get>(); + return _consumers; + } + + public static async Task Builder(Consumer consumer, Func received, Func shoped) + { + await Task.Run(() => + { + var tasks = new List(); + //var receivedDelegate = new ReceivedDelegate(ReceivedAsync); + ThreadPool.QueueUserWorkItem(async task => + { + await ReceivedAsync(consumer, received, shoped); + }); + }); + } + + public static async Task BatchBuilder(Consumer consumer, Func, Task> received, Func shoped, int batchsize = 1000) + { + await Task.Run(() => + { + var tasks = new List(); + //var receivedDelegate = new BatchReceivedDelegate(BatchReceivedAsync); + ThreadPool.QueueUserWorkItem(async task => + { + await BatchReceivedAsync(consumer, received, shoped, batchsize); + }); + }); + } + + public delegate Task ReceivedDelegate(Consumer consumer, Func received); + + public delegate Task BatchReceivedDelegate(Consumer consumer, Func, Task> received, int batchsize = 1000); + + public static async Task ReceivedAsync(Consumer consumer, Func received, Func shoped) + { + try { + var consumerConfig = new ConsumerConfig + { + BootstrapServers = consumer.Host, + GroupId = consumer.GroupId, + AutoOffsetReset = AutoOffsetReset.Earliest, + EnableAutoCommit = false + }; + + var cancel = false; + + using var consumerBuilder = new ConsumerBuilder(consumerConfig).Build(); + Console.WriteLine($"Kafka alone 连接成功,配置: {JsonSerializer.Serialize(consumerConfig)}"); + var topic = consumer.Topic; + consumerBuilder.Subscribe(topic); + while (!cancel) + { + try + { + if (Shop) + { + await shoped(); + return; + } + var consumeResult = consumerBuilder.Consume(CancellationToken.None); + Console.WriteLine($"Consumer message: {consumeResult.Message.Value} topic: {consumeResult.Topic} Partition: {consumeResult.Partition}"); + var message = JsonSerializer.Deserialize(consumeResult.Message.Value); + if (message != null) + { + await received(message); + } + try + { + consumerBuilder.Commit(consumeResult); + } + catch (KafkaException e) + { + Console.WriteLine(e.Message); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + await Task.Delay(1); + } + consumerBuilder.Close(); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + } + + public static async Task BatchReceivedAsync(Consumer consumer, Func, Task> received, Func shoped, int batchsize = 1000) + { + try + { + var consumerConfig = new ConsumerConfig + { + BootstrapServers = consumer.Host, + GroupId = consumer.GroupId, + AutoOffsetReset = AutoOffsetReset.Earliest, + EnableAutoCommit = false + }; + + var cancel = false; + + + using var consumerBuilder = new ConsumerBuilder(consumerConfig).Build(); + Console.WriteLine($"Kafka batch 连接成功,配置: {JsonSerializer.Serialize(consumerConfig)}"); + var topic = consumer.Topic; + consumerBuilder.Subscribe(topic); + while (!cancel) + { + try + { + if (Shop) + { + await shoped(); + return; + } + var batchRecords = new List(); + var consumeResults = new List>(); + while (batchRecords.Count < batchsize) + { + var consumeResult = consumerBuilder.Consume(CancellationToken.None); + Console.WriteLine($"Consumer message: {consumeResult.Message.Value} topic: {consumeResult.Topic} Partition: {consumeResult.Partition}"); + var message = JsonSerializer.Deserialize(consumeResult.Message.Value); + if (message == null) + break; // 贤有更多的消启可供消裁 + consumeResults.Add(consumeResult); + batchRecords.Add(message); + } + await received(batchRecords); + foreach (var consumeResult in consumeResults) + { + consumerBuilder.Commit(consumeResult); + } + } + catch (KafkaException e) + { + Console.WriteLine("KafkaException:" + e.Message); + } + catch (Exception ex) + { + Console.WriteLine("KafkaException:" + ex.ToString()); + } + await Task.Delay(1); + } + consumerBuilder.Close(); + } + catch (Exception ex) + { + Console.WriteLine("KafkaException:" + ex.ToString()); + } + } + + public static async Task SendMessage(Consumer consumer, TMessage message) + { + var config = new ProducerConfig + { + BootstrapServers = consumer.Host, + }; + var topic = consumer.Topic; + Action> handler = r => + Console.WriteLine(!r.Error.IsError + ? $"Delivered message to {r.TopicPartitionOffset}" + : $"Delivery Error: {r.Error.Reason}"); + + using (var p = new ProducerBuilder(config).Build()) + { + try + { + p.Produce(topic, new Message { Value = JsonSerializer.Serialize(message) }); + p.Flush(TimeSpan.FromSeconds(10)); + + } + catch (ProduceException e) + { + Console.WriteLine($"Delivery failed: {e.Error.Reason}"); + } + } + } + } +} diff --git a/code/DG.Kafka/KafkaProducer.cs b/code/DG.Kafka/KafkaProducer.cs new file mode 100644 index 0000000..9de566d --- /dev/null +++ b/code/DG.Kafka/KafkaProducer.cs @@ -0,0 +1,47 @@ +using Confluent.Kafka; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using static Confluent.Kafka.ConfigPropertyNames; + +namespace DG.Kafka +{ + internal class KafkaProducer : IKafkaProducer + { + private static List _consumers { get; set; } = new List(); + private Dictionary> _producers; + public KafkaProducer() + { + _consumers = KafkaClient.Default.ConfigurationManager.GetSection("Consumers").Get>(); + _producers = new Dictionary>(); + foreach (var consumer in _consumers) + { + var config = new ProducerConfig + { + BootstrapServers = consumer.Host, + }; + var topic = consumer.Topic; + Action> handler = r => + Console.WriteLine(!r.Error.IsError + ? $"Delivered message to {r.TopicPartitionOffset}" + : $"Delivery Error: {r.Error.Reason}"); + _producers.Add(consumer.Topic, new ProducerBuilder(config).Build()); + } + } + + public async Task ProduceAsync(string? topic, TMessage message) + { + var producer = _producers.First().Value; + if (!string.IsNullOrEmpty(topic)) + { + producer = _producers.GetValueOrDefault(topic); + } + await producer.ProduceAsync(topic, new Message { Value = JsonSerializer.Serialize(message) }); + producer.Flush(); + } + } +} diff --git a/code/DG.Kafka/ServiceCollectionExtensions.cs b/code/DG.Kafka/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..0331370 --- /dev/null +++ b/code/DG.Kafka/ServiceCollectionExtensions.cs @@ -0,0 +1,25 @@ +using DG.Kafka; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// Extensions method + /// + public static class ServiceCollectionExtensions + { + + /// + /// Redis service registered + /// + /// + /// + /// + public static IServiceCollection AddKafka(this IServiceCollection services, IConfiguration configuration) + { + KafkaClient.Default.ReadFromConfiguration(configuration); + services = services.AddSingleton(); + return services; + } + } +} diff --git a/code/EmployeeDepartmentDetailWorker/Config/SystemConfig.cs b/code/EmployeeDepartmentDetailWorker/Config/SystemConfig.cs new file mode 100644 index 0000000..77b556c --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Config/SystemConfig.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EmployeeDepartmentDetailServices.Config +{ + public class SystemConfig + { + public string zxdCoreApi { get; set; } + public string nodeWebApi { get; set; } + public string crmCoreApi { get; set; } + public int clearEDDHour { get; set; } + } +} diff --git a/code/EmployeeDepartmentDetailWorker/EmployeeDepartmentDetailServices.csproj b/code/EmployeeDepartmentDetailWorker/EmployeeDepartmentDetailServices.csproj new file mode 100644 index 0000000..913015f --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/EmployeeDepartmentDetailServices.csproj @@ -0,0 +1,57 @@ + + + + Exe + net6.0 + enable + enable + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + Always + + + Always + + + Always + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/EmployeeDepartmentDetailWorker/Program.cs b/code/EmployeeDepartmentDetailWorker/Program.cs new file mode 100644 index 0000000..f6eedd3 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Program.cs @@ -0,0 +1,91 @@ +using DG.EntityFramework; +using EmployeeDepartmentDetailServices.Config; +using Exceptionless; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Quartz.Impl; +using Quartz.Spi; +using Quartz; +using Serilog; +using Zxd.EntityFramework; +using DG.Core; +using EmployeeDepartmentDetailServices.Worker; + +try +{ + var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + Console.WriteLine($"Env: {env}"); + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{env ?? "Production"}.json", true) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{env ?? "Production"}.json", true) + .Build(); + + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) + .WriteTo.Exceptionless(config.GetValue("Exceptionless:ApiKey"), config.GetValue("Exceptionless:ServerUrl"), new string[] { "WeworkUserWorker" }) + .CreateLogger(); + Log.Logger = logger; + Log.Information("Starting ResourceFlowWorker"); + IServiceCollection services = new ServiceCollection(); + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(config); + services.AddOptions() + .Configure(e => config.GetSection("SystemConfig").Bind(e)); + ExceptionlessClient.Default.Startup(config.GetValue("Exceptionless:ApiKey")); + ExceptionlessClient.Default.Configuration.ServerUrl = config.GetValue("Exceptionless:ServerUrl"); + ExceptionlessClient.Default.Configuration.DefaultTags.Add("zxd-ResourceFlowWorker"); + //services.AddRedis(config); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(config.GetConnectionString("zxdcrm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(config.GetConnectionString("dncmsbase"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("usercenter"), ServerVersion.AutoDetect(config.GetConnectionString("usercenter"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncms"), ServerVersion.AutoDetect(config.GetConnectionString("dncms"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("companyBaseConf"), ServerVersion.AutoDetect(config.GetConnectionString("companyBaseConf"))); + }); + //services.AddDGEntityFramework(options => + //{ + // options.UseMySql(config.GetConnectionString("hgaction"), ServerVersion.AutoDetect(config.GetConnectionString("hgaction"))); + //}); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("crmcloud"), ServerVersion.AutoDetect(config.GetConnectionString("crmcloud"))); + }); + + services.AddWorker(config); + services.AddDGHttpClient(); + services.AddRegisterWorker(); + var builder = new HostBuilder(); + await builder.RunConsoleAsync(); + +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} diff --git a/code/EmployeeDepartmentDetailWorker/Properties/launchSettings.json b/code/EmployeeDepartmentDetailWorker/Properties/launchSettings.json new file mode 100644 index 0000000..38ab25f --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "profiles": { + "WeworkUserWorker": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/code/EmployeeDepartmentDetailWorker/Serilog.PreProduction.json b/code/EmployeeDepartmentDetailWorker/Serilog.PreProduction.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Serilog.PreProduction.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/EmployeeDepartmentDetailWorker/Serilog.Production.json b/code/EmployeeDepartmentDetailWorker/Serilog.Production.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/EmployeeDepartmentDetailWorker/Serilog.json b/code/EmployeeDepartmentDetailWorker/Serilog.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/EmployeeDepartmentDetailWorker/Worker/SynchronousWorker.cs b/code/EmployeeDepartmentDetailWorker/Worker/SynchronousWorker.cs new file mode 100644 index 0000000..9e4dcb3 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/Worker/SynchronousWorker.cs @@ -0,0 +1,452 @@ +using DG.Core; +using DG.EntityFramework; +using DG.Worker; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Dncms; +using Zxd.Entity; +using Zxd.EntityFramework; +using EmployeeDepartmentDetailServices.Config; +using Microsoft.EntityFrameworkCore; +using static System.Formats.Asn1.AsnWriter; +using Zxd.Entity.CompanyBaseConf; +using Microsoft.EntityFrameworkCore.Internal; +using DG.Tool; +using Zxd.Core.Shared.Dto; +using Zxd.Entity.Zxd; +using OfficeOpenXml.FormulaParsing.Excel.Functions.Engineering; + +namespace EmployeeDepartmentDetailServices.Worker +{ + internal class SynchronousWorker : WorkerBase, IDisposable + { + private readonly IConfiguration _configuration; + private readonly IServiceProvider _serviceProvider; + private readonly IHttpClient _httpClient; + private readonly ILogger _logger; + private readonly SystemConfig? _systemConfig; + private static bool IsFrist = true; + + public SynchronousWorker(ILogger logger, + IServiceProvider serviceProvider, + IConfiguration configuration, + IHttpClient httpClient + ) : base(logger) + { + _logger = logger; + _configuration = configuration; + _serviceProvider = serviceProvider; + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _httpClient = httpClient; + } + + /// + /// + /// + /// + /// + protected override async Task DoWorkAsync() + { + try + { + List changeEdd = new List(); + List changeEd = new List(); + List changeDepart = new List(); + + using var scope = _serviceProvider.CreateAsyncScope(); + var companyBaseConfRepository = scope.ServiceProvider.GetRequiredService>(); + var zxdRepository = scope.ServiceProvider.GetRequiredService>(); + var crmCloudRepository = scope.ServiceProvider.GetRequiredService>(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + + //从员工系统同步数据 + var employeedepartmentdetail = companyBaseConfRepository.GetRepository().Query(); + var applicationpartment = companyBaseConfRepository.GetRepository().Query(); + var application = companyBaseConfRepository.GetRepository().Query(); + var department = companyBaseConfRepository.GetRepository().Query(); + + var employ = companyBaseConfRepository.GetRepository().Query(); + var deptment = await _httpClient.GetAsync>>($"{_systemConfig.zxdCoreApi}/Api/Deptment/Depts");//员工系统部门关心 + if (DateTime.Now.Hour == _systemConfig.clearEDDHour) + { //固定时间 + //全量清空重新同步 + Log.Error("清空历史数据:"+ DateTime.Now.Hour); + await zxdRepository.ExecuteSqlCommandNonQueryAsync(System.Data.CommandType.Text, "truncate table employee_department_detail"); + await crmCloudRepository.ExecuteSqlCommandNonQueryAsync(System.Data.CommandType.Text, "truncate table employee_department_detail"); + await dncmsbaseRepository.ExecuteSqlCommandNonQueryAsync(System.Data.CommandType.Text, "truncate table employee_department_detail"); + } + + #region 处理数据 + var zxdEdd = zxdRepository.GetRepository().Query(); + DateTime eddMaxUpDate = zxdEdd.Any() ? zxdEdd.Max(m => m.update_time) : new DateTime(); + + var newEmp = employeedepartmentdetail.Where(m => m.update_time > eddMaxUpDate).ToList();//需要入库的部分 + var eidDic = employ.ToDictionary(m => m.id, n => n.employee_id); + var statusDic = employ.ToDictionary(m => m.id, n => n.status); + var deptDic = department.ToDictionary(m => m.Id, n => n.DepartmentName); + foreach (var item in newEmp) + { + Zxd.Entity.Zxd.EmployeeDepartmentDetail eddItem = new Zxd.Entity.Zxd.EmployeeDepartmentDetail(); + eddItem.id = item.id; + eddItem.eid = 0; + eddItem.empStatus = 4; + if (eidDic.ContainsKey(item.emp_id)) + { + eddItem.eid = eidDic[item.emp_id];//匹配eid + eddItem.empStatus = statusDic[item.emp_id] ?? 0; + } + else + { //找不到工号 + continue; + } + if (deptDic.ContainsKey(item.department_id)) + { + eddItem.department_name = deptDic[item.department_id]; + } + eddItem.department_id = item.department_id; + eddItem.department_type = item.department_type; + eddItem.level = item.level; + eddItem.is_deleted = item.is_deleted; + eddItem.create_time = item.create_time; + eddItem.update_time = item.update_time; + changeEdd.Add(eddItem); + } + + var zxdEddIdList = zxdEdd.Select(m => m.id).ToList(); + var updateEdd = changeEdd.Where(m => zxdEddIdList.Contains(m.id)).ToList(); + var insertEdd = changeEdd.Where(m => !zxdEddIdList.Contains(m.id)).ToList(); + + #endregion 处理数据 + + #region 处理部门信息 + + var zxdDepart = zxdRepository.GetRepository().Query(); + DateTime DepartMaxUpDate = zxdDepart.Any() ? zxdDepart.Max(m => m.Update_Time) : new DateTime(); + var newDepart = department.Where(m => m.Update_Time > eddMaxUpDate).ToList();//需要入库的部分 + foreach (var item in newDepart) + { + Zxd.Entity.Zxd.ZXDDepartment depart = new Zxd.Entity.Zxd.ZXDDepartment(); + depart.Id = item.Id; + depart.ParentId = item.ParentId; + depart.DepartmentName = item.DepartmentName; + depart.DepartmentCode = item.DepartmentCode; + depart.DepartmentType = item.DepartmentType; + depart.Status = item.Status; + depart.IsDeleted = item.IsDeleted; + depart.Create_Time = item.Create_Time; + depart.Update_Time = item.Update_Time; + changeDepart.Add(depart); + } + + var zxDepart = zxdDepart.Select(m => m.Id).ToList(); + var updateDepart = changeDepart.Where(m => zxDepart.Contains(m.Id)).ToList(); + var insertDepart = changeDepart.Where(m => !zxDepart.Contains(m.Id)).ToList(); + + #endregion 处理部门信息 + + #region 处理员工归属事业部关系 + + var zxdEDF = zxdRepository.GetRepository().Query().ToList(); + + List deleteEdf = new List(); + List insertEdf = new List(); + List allEdf = new List(); + var edList = await companyBaseConfRepository.ExecuteSqlToListAsync(@"select a.emp_id,concat(c.app_id,'') app_id,c.application_name + from employee_department_detail a + left join application_department b on a.department_id=b.department_id + left join application c on b.application_id=c.id + where a.is_deleted =0 and b.is_deleted =0 and c.is_deleted =0 + group by a.emp_id,c.app_id"); + //拼接数据 + foreach (var item in edList) + { + Zxd.Entity.Zxd.EmployeeDepartmentFull edf = new Zxd.Entity.Zxd.EmployeeDepartmentFull(); + if (eidDic.ContainsKey(item.emp_id)) + { + edf.eid = eidDic[item.emp_id];//匹配eid + } + else + { //找不到工号 + continue; + } + edf.appid = item.app_id; + edf.app_name = item.application_name; + edf.create_time = DateTime.Now; + if (!zxdEDF.Any(n => n.appid == edf.appid && n.eid == edf.eid)) + {//不存在 + insertEdf.Add(edf);//新增 + } + allEdf.Add(edf); + } + foreach (var item in zxdEDF) + { + if (!allEdf.Any(n => n.appid == item.appid && n.eid == item.eid))//全量数据中 不存在的旧数据 + { + deleteEdf.Add(item);//新增 + } + } + + #endregion 处理员工归属事业部关系 + + #region 同步到zxd + + using var transaction = await zxdRepository.BeginTransactionAsync(); + try + { + await zxdRepository.GetRepository().BatchUpdateAsync(updateEdd); + await zxdRepository.GetRepository().BatchInsertAsync(insertEdd); + + await zxdRepository.GetRepository().BatchDeleteAsync(deleteEdf); + await zxdRepository.GetRepository().BatchInsertAsync(insertEdf); + + await zxdRepository.GetRepository().BatchUpdateAsync(updateDepart); + await zxdRepository.GetRepository().BatchInsertAsync(insertDepart); + + await transaction.CommitAsync(); + } + catch (Exception ex) + { + Log.Error(ex, "同步失败!"); + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + } + + #endregion 同步到zxd + + #region 同步到crm_cloud + + using var hgtransaction = await crmCloudRepository.BeginTransactionAsync(); + try + { + await crmCloudRepository.GetRepository().BatchUpdateAsync(Mapping(updateEdd)); + await crmCloudRepository.GetRepository().BatchInsertAsync(Mapping(insertEdd)); + + await crmCloudRepository.GetRepository().BatchDeleteAsync(Mapping(deleteEdf)); + await crmCloudRepository.GetRepository().BatchInsertAsync(Mapping(insertEdf)); + + await crmCloudRepository.GetRepository().BatchUpdateAsync(Mapping(updateDepart)); + await crmCloudRepository.GetRepository().BatchInsertAsync(Mapping(insertDepart)); + + await hgtransaction.CommitAsync(); + } + catch (Exception ex) + { + Log.Error(ex, "同步失败!"); + await hgtransaction.RollbackAsync(); + await hgtransaction.DisposeAsync(); + } + + #endregion 同步到hgaction + + #region 同步到hncmsbase + + using var dncmsbase = await dncmsbaseRepository.BeginTransactionAsync(); + try + { + await dncmsbaseRepository.GetRepository().BatchUpdateAsync(MappingToDncms(updateEdd)); + await dncmsbaseRepository.GetRepository().BatchInsertAsync(MappingToDncms(insertEdd)); + + await dncmsbaseRepository.GetRepository().BatchDeleteAsync(MappingToDncms(deleteEdf)); + await dncmsbaseRepository.GetRepository().BatchInsertAsync(MappingToDncms(insertEdf)); + + await dncmsbaseRepository.GetRepository().BatchUpdateAsync(MappingToDncms(updateDepart)); + await dncmsbaseRepository.GetRepository().BatchInsertAsync(MappingToDncms(insertDepart)); + + await dncmsbase.CommitAsync(); + } + catch (Exception ex) + { + Log.Error(ex, "同步失败!"); + await dncmsbase.RollbackAsync(); + await dncmsbase.DisposeAsync(); + } + + #endregion 同步到hncmsbase + + #region 推送到坐席 + + //var eddGup = changeEdd.GroupBy(m => m.department_id); + //foreach (var item in eddGup) + //{ + // try + // { + // int psize = 10; + // var dept = deptment.Data.FirstOrDefault(m => m.DepartmentId == item.Key); + // if (dept != null) + // { + // var url = $"{_systemConfig?.crmCoreApi}/Api/Customer/SynchronousCustomer"; + // if (item.Count() < psize) + // { + // var data = await _httpClient.PostAsync>(url, new { eddList = item.ToList() }, dept.Appid);// + // } + // else + // { + // //分页推送 + // int maxIndex = (item.Count() % psize) + 1; + // int pindex = 1; + // while (pindex <= maxIndex) + // { + // var list = item.ToList().Skip((pindex - 1) * psize).Take(psize).ToList(); + // var res = await _httpClient.PostAsync>(url, new { eddList = list }, dept.Appid);// + // pindex++; + // } + // } + // } + // } + // catch (Exception ex) + // { + // Log.Error(ex, "推送失败!"); + // continue; + // } + //} + + #endregion 推送到坐席 + } + catch (Exception ex) + { + Log.Error(ex, "同步失败!"); + } + } + + private List Mapping(List list) + { + List res = new List(); + foreach (var item in list) + { + Zxd.Entity.HgAction.EmployeeDepartmentDetail i = new Zxd.Entity.HgAction.EmployeeDepartmentDetail(); + i.id = item.id; + i.eid = item.eid; + i.department_id = item.department_id; + i.department_name = item.department_name; + i.department_type = item.department_type; + i.empStatus = item.empStatus; + i.level = item.level; + i.is_deleted = item.is_deleted; + i.create_time = item.create_time; + i.update_time = item.update_time; + res.Add(i); + } + return res; + } + + private List Mapping(List list) + { + List res = new List(); + foreach (var item in list) + { + Zxd.Entity.HgAction.EmployeeDepartmentFull i = new Zxd.Entity.HgAction.EmployeeDepartmentFull(); + i.id = item.id; + i.eid = item.eid; + i.appid = item.appid; + i.app_name = item.app_name; + i.create_time = item.create_time; + res.Add(i); + } + return res; + } + + private List Mapping(List list) + { + List res = new List(); + foreach (var item in list) + { + Zxd.Entity.HgAction.HGDepartment i = new Zxd.Entity.HgAction.HGDepartment(); + i.Id = item.Id; + i.ParentId = item.ParentId; + i.DepartmentName = item.DepartmentName; + i.DepartmentType = item.DepartmentType; + i.DepartmentCode = item.DepartmentCode; + i.IsDeleted = item.IsDeleted; + i.Status = item.Status; + i.Create_Time = item.Create_Time; + i.Update_Time = item.Update_Time; + res.Add(i); + } + return res; + } + + private List MappingToDncms(List list) + { + List res = new List(); + foreach (var item in list) + { + Zxd.Entity.Dncms.EmployeeDepartmentDetail i = new Zxd.Entity.Dncms.EmployeeDepartmentDetail(); + i.id = item.id; + i.eid = item.eid; + i.department_id = item.department_id; + i.department_name = item.department_name; + i.department_type = item.department_type; + i.empStatus = item.empStatus; + i.level = item.level; + i.is_deleted = item.is_deleted; + i.create_time = item.create_time; + i.update_time = item.update_time; + res.Add(i); + } + return res; + } + + private List MappingToDncms(List list) + { + List res = new List(); + foreach (var item in list) + { + Zxd.Entity.Dncms.EmployeeDepartmentFull i = new Zxd.Entity.Dncms.EmployeeDepartmentFull(); + i.id = item.id; + i.eid = item.eid; + i.appid = item.appid; + i.app_name = item.app_name; + i.create_time = item.create_time; + res.Add(i); + } + return res; + } + + private List MappingToDncms(List list) + { + List res = new List(); + foreach (var item in list) + { + Zxd.Entity.Dncms.Department i = new Zxd.Entity.Dncms.Department(); + i.Id = item.Id; + i.ParentId = item.ParentId; + i.DepartmentName = item.DepartmentName; + i.DepartmentType = item.DepartmentType; + i.DepartmentCode = item.DepartmentCode; + i.IsDeleted = item.IsDeleted; + i.Status = item.Status; + i.Create_Time = item.Create_Time; + i.Update_Time = item.Update_Time; + res.Add(i); + } + return res; + } + + public void Dispose() + { + _logger.LogInformation("任务正在关闭"); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + var configs = dncmsRepository.GetRepository().Query() + .Where(x => x.Status == ResourceConfigStatus.执行中).ToList(); + + configs.ForEach(x => x.Status = ResourceConfigStatus.待重启); + + dncmsRepository.GetRepository().BatchUpdateAsync(configs, x => new { x.Status }); + } + } + + public class EmpAppItem + { + public int emp_id { get; set; } + public string? app_id { get; set; } + public string? application_name { get; set; } + } +} \ No newline at end of file diff --git a/code/EmployeeDepartmentDetailWorker/appsettings.PreProduction.json b/code/EmployeeDepartmentDetailWorker/appsettings.PreProduction.json new file mode 100644 index 0000000..55451f5 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/appsettings.PreProduction.json @@ -0,0 +1,27 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crmcloud": "Server=192.168.11.141;Database=crm_cloud;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "TaskConfig": { + "TaskName": "DG.SynchronousWorker", + "TaskRemarks": "DG.SynchronousWorker", + "Enable": true, + "SecondsDelay": 90 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "tmrp0GmwyTMe6UxJIw7LXAcIWYKEUgy2kprMiybd" + }, + "SystemConfig": { + "zxdCoreApi": "http://192.168.11.81:8089", + "nodeWebApi": "http://120.238.224.24:10034", + "crmCoreApi": "http://192.168.11.81:8088", + "clearEDDHour": "1" + } +} \ No newline at end of file diff --git a/code/EmployeeDepartmentDetailWorker/appsettings.Production.json b/code/EmployeeDepartmentDetailWorker/appsettings.Production.json new file mode 100644 index 0000000..a73cb02 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/appsettings.Production.json @@ -0,0 +1,27 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "crm": "Server=mysql98ff96c3dffa.rds.ivolces.com;Database=db_crm;UserId=qianbenjie;Password=Hcqianbenjie@123;port=3306;", + "crmcloud": "Data Source=dgbigdata.mysql.rds.aliyuncs.com;Port=3306;Initial Catalog=crm_cloud;user id=crm_rd;password=K#RQ1TYx9my;SslMode=None;" + }, + "TaskConfig": { + "TaskName": "DG.SynchronousWorker", + "TaskRemarks": "DG.SynchronousWorker", + "Enable": true, + "SecondsDelay": 3600 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "tmrp0GmwyTMe6UxJIw7LXAcIWYKEUgy2kprMiybd" + }, + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089", + "nodeWebApi": "http://120.238.224.24:10034", + "crmCoreApi": "http://api.crm.tcfortune.com:8282", + "clearEDDHour": "1" + } +} \ No newline at end of file diff --git a/code/EmployeeDepartmentDetailWorker/appsettings.json b/code/EmployeeDepartmentDetailWorker/appsettings.json new file mode 100644 index 0000000..71f9ad6 --- /dev/null +++ b/code/EmployeeDepartmentDetailWorker/appsettings.json @@ -0,0 +1,28 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crmcloud": "Server=192.168.11.141;Database=crm_cloud;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "TaskConfig": { + "TaskName": "DG.SynchronousWorker", + "TaskRemarks": "DG.SynchronousWorker", + "Enable": true, + "SecondsDelay": 60 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "tmrp0GmwyTMe6UxJIw7LXAcIWYKEUgy2kprMiybd" + }, + "SystemConfig": { + "zxdCoreApi": "http://192.168.11.81:8089", + "nodeWebApi": "http://120.238.224.24:10034", + //"crmCoreApi": "https://localhost:7234" + "crmCoreApi": "http://192.168.11.80:8088", + "clearEDDHour": "1" + } +} \ No newline at end of file diff --git a/code/NuGet.Config b/code/NuGet.Config new file mode 100644 index 0000000..3f0e003 --- /dev/null +++ b/code/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/code/ResourceFlowWorker/Config/Properties/launchSettings.json b/code/ResourceFlowWorker/Config/Properties/launchSettings.json new file mode 100644 index 0000000..c5c9812 --- /dev/null +++ b/code/ResourceFlowWorker/Config/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "profiles": { + "ResourceFlowWorker": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/code/ResourceFlowWorker/Config/SystemConfig.cs b/code/ResourceFlowWorker/Config/SystemConfig.cs new file mode 100644 index 0000000..133fffc --- /dev/null +++ b/code/ResourceFlowWorker/Config/SystemConfig.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ResourceFlowWorker.Config +{ + public class SystemConfig + { + public string zxdCoreApi { get; set; } + } +} diff --git a/code/ResourceFlowWorker/Dockerfile b/code/ResourceFlowWorker/Dockerfile new file mode 100644 index 0000000..6ab0c11 --- /dev/null +++ b/code/ResourceFlowWorker/Dockerfile @@ -0,0 +1,23 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["ResourceFlowWorker/ResourceFlowWorker.csproj", "ResourceFlowWorker/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +RUN dotnet restore "ResourceFlowWorker/ResourceFlowWorker.csproj" +COPY . . +WORKDIR "/src/ResourceFlowWorker" +RUN dotnet build "ResourceFlowWorker.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "ResourceFlowWorker.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ResourceFlowWorker.dll"] \ No newline at end of file diff --git a/code/ResourceFlowWorker/Dockerfile.original b/code/ResourceFlowWorker/Dockerfile.original new file mode 100644 index 0000000..90a3762 --- /dev/null +++ b/code/ResourceFlowWorker/Dockerfile.original @@ -0,0 +1,23 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["WeworkUserWorker/WeworkUserWorker.csproj", "WeworkUserWorker/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +RUN dotnet restore "WeworkUserWorker/WeworkUserWorker.csproj" +COPY . . +WORKDIR "/src/WeworkUserWorker" +RUN dotnet build "WeworkUserWorker.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "WeworkUserWorker.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "WeworkUserWorker.dll"] \ No newline at end of file diff --git a/code/ResourceFlowWorker/Dto/LivePageDto.cs b/code/ResourceFlowWorker/Dto/LivePageDto.cs new file mode 100644 index 0000000..5acd711 --- /dev/null +++ b/code/ResourceFlowWorker/Dto/LivePageDto.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ResourceFlowWorker.Dto +{ + internal class LivePageDto + { + /// + /// 当前页码 + /// + [JsonPropertyName("currentPage")] + public int? CurrentPage { get; set; } + + /// + /// 每页记录数 + /// + [JsonPropertyName("pageSize")] + public int? PageSize { get; set; } + + /// + /// 列表数据 + /// + [JsonPropertyName("tableData")] + public List TableData { get; set; } + + /// + /// 总记录数 + /// + [JsonPropertyName("total")] + public long Total { get; set; } + } +} diff --git a/code/ResourceFlowWorker/Dto/ResourceFlowCustomerAndUserDto.cs b/code/ResourceFlowWorker/Dto/ResourceFlowCustomerAndUserDto.cs new file mode 100644 index 0000000..0322d9b --- /dev/null +++ b/code/ResourceFlowWorker/Dto/ResourceFlowCustomerAndUserDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ResourceFlowWorker.Dto +{ + internal class ResourceFlowCustomerAndUserDto + { + public string? Appid { get; set; } + + + public string? Userid { get; set; } + + } +} diff --git a/code/ResourceFlowWorker/Dto/ResourceFlowWorkerDto.cs b/code/ResourceFlowWorker/Dto/ResourceFlowWorkerDto.cs new file mode 100644 index 0000000..1a323c9 --- /dev/null +++ b/code/ResourceFlowWorker/Dto/ResourceFlowWorkerDto.cs @@ -0,0 +1,72 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Dncms; + +namespace ResourceFlowWorker.Dto +{ + internal class ResourceFlowWorkerDto + { + } + + internal class ResourceFlowFromDto + { + public ResourceFlowFromDto(ResourceFlowConfig? config, ResourceFlowConfigFrom? from, List sourceResources) + { + Config = config; + From = from; + SourceResources = sourceResources; + OperateResources = JsonHelper.FromJson>(sourceResources.ToJson()); + AssignedCount = 0; + } + + public ResourceFlowConfig Config { get; set; } + + public ResourceFlowConfigFrom From { get; set; } + + /// + /// 源人群包信息 + /// + public List SourceResources { get; set; } + + /// + /// 操作人群包信息 + /// + public List OperateResources { get; set; } + + /// + /// 已分配数量 + /// + public int AssignedCount { get; set; } + + /// + /// 权重 + /// + public decimal Weight + { + get + { + return SourceResources.Count == 0 ? 0 : (SourceResources.Count - OperateResources.Count) / SourceResources.Count; + } + } + } + + internal class ResourceCountQueryDto + { + public string groupids { get; set; } + public string userids { get; set; } + public string appid { get; set; } + public int page { get; set; } = 1; + public int limit { get; set; } = 100000; + } + + internal class ResourceCountReturnModel + { + public string? _nickname { get; set; } + public string? _appuserid { get; set; } + public string? _headimgurl { get; set; } + } +} diff --git a/code/ResourceFlowWorker/Program.cs b/code/ResourceFlowWorker/Program.cs new file mode 100644 index 0000000..0ac9a50 --- /dev/null +++ b/code/ResourceFlowWorker/Program.cs @@ -0,0 +1,67 @@ +using Microsoft.Extensions.Configuration; + +try +{ + var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + Console.WriteLine($"Env: {env}"); + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{env ?? "Production"}.json", true) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{env ?? "Production"}.json", true) + .Build(); + + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) + .WriteTo.Exceptionless(config.GetValue("Exceptionless:ApiKey"), config.GetValue("Exceptionless:ServerUrl"), new string[] { "WeworkUserWorker" }) + .CreateLogger(); + Log.Logger = logger; + Log.Information("Starting ResourceFlowWorker"); + IServiceCollection services = new ServiceCollection(); + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(config); + services.AddOptions() + .Configure(e => config.GetSection("SystemConfig").Bind(e)); + ExceptionlessClient.Default.Startup(config.GetValue("Exceptionless:ApiKey")); + ExceptionlessClient.Default.Configuration.ServerUrl = config.GetValue("Exceptionless:ServerUrl"); + ExceptionlessClient.Default.Configuration.DefaultTags.Add("zxd-ResourceFlowWorker"); + //services.AddRedis(config); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(config.GetConnectionString("zxdcrm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(config.GetConnectionString("dncmsbase"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("usercenter"), ServerVersion.AutoDetect(config.GetConnectionString("usercenter"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncms"), ServerVersion.AutoDetect(config.GetConnectionString("dncms"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("companyBaseConf"), ServerVersion.AutoDetect(config.GetConnectionString("companyBaseConf"))); + }); + services.AddWorker(config); + services.AddDGHttpClient(); + services.AddRegisterWorker(); + var builder = new HostBuilder(); + await builder.RunConsoleAsync(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} diff --git a/code/ResourceFlowWorker/Properties/launchSettings.json b/code/ResourceFlowWorker/Properties/launchSettings.json new file mode 100644 index 0000000..c5c9812 --- /dev/null +++ b/code/ResourceFlowWorker/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "profiles": { + "ResourceFlowWorker": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/code/ResourceFlowWorker/ResourceFlowWorker.csproj b/code/ResourceFlowWorker/ResourceFlowWorker.csproj new file mode 100644 index 0000000..8c4777e --- /dev/null +++ b/code/ResourceFlowWorker/ResourceFlowWorker.csproj @@ -0,0 +1,82 @@ + + + + Exe + net6.0 + enable + enable + Linux + + + + + $(DockerDefaultDockerfile) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/code/ResourceFlowWorker/Serilog.Production.json b/code/ResourceFlowWorker/Serilog.Production.json new file mode 100644 index 0000000..491af8c --- /dev/null +++ b/code/ResourceFlowWorker/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} \ No newline at end of file diff --git a/code/ResourceFlowWorker/Serilog.json b/code/ResourceFlowWorker/Serilog.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/ResourceFlowWorker/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/ResourceFlowWorker/Workers/ResourceWorker.cs b/code/ResourceFlowWorker/Workers/ResourceWorker.cs new file mode 100644 index 0000000..b517ab4 --- /dev/null +++ b/code/ResourceFlowWorker/Workers/ResourceWorker.cs @@ -0,0 +1,306 @@ +using Exceptionless.Utility; +using Microsoft.Extensions.Configuration; +using ResourceFlowWorker.Config; +using ResourceFlowWorker.Dto; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Dncms; +using Zxd.EntityFramework; + +namespace ResourceFlowWorker.Workers +{ + internal class ResourceWorker : WorkerBase, IDisposable + { + private readonly IConfiguration _configuration; + private readonly IServiceProvider _serviceProvider; + private readonly IHttpClient _httpClient; + private readonly ILogger _logger; + private readonly SystemConfig? _systemConfig; + private static bool IsFrist = true; + + public ResourceWorker(ILogger logger, + IServiceProvider serviceProvider, + IConfiguration configuration, + IHttpClient httpClient + ) : base(logger) + { + _logger = logger; + _configuration = configuration; + _serviceProvider = serviceProvider; + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _httpClient = httpClient; + } + + /// + /// + /// + /// + /// + protected override async Task DoWorkAsync() + { + var status = new List { ResourceConfigStatus.待执行 }; + if (IsFrist) + { + IsFrist = !IsFrist; + status.Add(ResourceConfigStatus.执行中); + status.Add(ResourceConfigStatus.待重启); + } + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + var configs = await dncmsRepository.GetRepository().Query() + .Where(x => status.Contains(x.Status)).ToListAsync(); + if (configs.Any()) + { + configs.ForEach(x => x.Status = ResourceConfigStatus.执行中); + await dncmsRepository.GetRepository().BatchUpdateAsync(configs, x => new { x.Status }); + + foreach (var config in configs) + { + var fromList = await dncmsRepository.GetRepository().Query() + .Where(x => x.ConfigId == config.Id).ToListAsync(); + var toList = await dncmsRepository.GetRepository().Query() + .Where(x => x.ConfigId == config.Id).ToListAsync(); + await DoDistribute(config, fromList, toList); + } + } + } + + /// + /// 执行分配 + /// + /// + private async Task DoDistribute(ResourceFlowConfig config, List froms, List tos) + { + var flowFroms = new List(); + foreach (var from in froms) + { + var sourceResourceResult = await _httpClient.GetAsync>>($"{_systemConfig.zxdCoreApi}/Api/WeWorkResource/KFResourceCount?groupids={config.GroupId}&userids={from.Userid}&appid={config.Appid}&page=1&limit=10000"); + if (sourceResourceResult.Code == 0) + { + var sourceResources = sourceResourceResult.Data.TableData; + // 判断是否离职 + if (!sourceResources.Any()) + { + sourceResourceResult = await _httpClient.GetAsync>>($"{_systemConfig.zxdCoreApi}/Api/WeWorkResource/KFResourceCount?groupids={config.GroupId}&userids={from.Userid}&appid={config.Appid}&page=1&limit=10000&status=0&subscribe=-4"); + if (sourceResourceResult.Code == 0) + { + sourceResources = sourceResourceResult.Data.TableData; + } + } + flowFroms.Add(new ResourceFlowFromDto(config, from, sourceResources)); + } + } + var logs = new List(); + + // 离职员工分配逻辑 + // 目标数量 + var flowCount = config.FlowCount; + var assignedCount = 0; + var fromUserids = froms.Select(x => x.Userid).ToList(); + var toUserids = tos.Select(n => n.Userid).ToList(); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + var dimissiones = await dncmsRepository.GetRepository().Query() + .Where(x => x.Appid == config.Appid && fromUserids.Contains(x.FromUserid)).ToListAsync(); + if (dimissiones.Count > 0) + { + Log.Information("处理离职数据"); + + Log.Information($"处理离职数据{dimissiones.Count}条"); + foreach (var flowFrom in flowFroms) + { + var list = dimissiones.Where(x => x.FromUserid == flowFrom.From.Userid).ToList(); + foreach (var item in list) + { + if (flowFrom.OperateResources.Any(y => y._appuserid == item.Appuserid)) + { + var resource = flowFrom.OperateResources.Where(y => y._appuserid == item.Appuserid).First(); + logs.Add(new ResourceFlowLog + { + Deptid = config.Deptid, + Appid = config.Appid, + Appuserid = item.Appuserid, + FromUserid = flowFrom.From.Userid, + ConfigId = config.Id, + FlowTime = DateTime.Now, + Status = ResourceFlowStatus.待转移, + IsDimission = true, + }); + flowFrom.AssignedCount++; + assignedCount++; + flowFrom.From.TransferCount++; + flowFrom.OperateResources.Remove(resource); + if (flowCount == assignedCount) break; + } + } + if (flowCount == assignedCount) break; + } + } + // 相同人群包 已分配日志 + var allOldFromLog = await dncmsRepository.GetRepository().Query().Where(x => x.Appid == config.Appid && fromUserids.Contains(x.FromUserid) && x.Status != ResourceFlowStatus.转移成功).ToListAsync(); + var oldFromLog = new List(); + if (config.GroupId > 0) + { + oldFromLog = allOldFromLog.Where(x => x.GroupId == config.GroupId).ToList(); + } + //最近一天的 不让重新分配 + var notPassFromLog = allOldFromLog.Where(n => n.FlowTime >= DateTime.Now.AddDays(-1)).ToList(); + oldFromLog.AddRange(notPassFromLog); + var oldToLog = await dncmsRepository.GetRepository().Query() + .Where(x => x.Appid == config.Appid && toUserids.Contains(x.ToUserid) && x.GroupId == config.GroupId).ToListAsync(); + + while (flowCount > assignedCount) + { + // 如果队列已经不够好友,跳出循环 + if (!flowFroms.Any()) { Log.Information("队列已经不够好友,跳出循环"); break; } + // 确定权重 + var first = flowFroms.OrderByDescending(x => x.Weight).First(); + + // 如果客服无可分配资源,移除分配队列,重新选择客服 + if (first.OperateResources.Count == 0) + { + Log.Information($"客服{first.From.Ename}无可分配资源"); + flowFroms.Remove(first); + continue; + } + // 随机指定用户 + var n = new Random().Next(first.OperateResources.Count); + // 获取随机用户 + var resource = first.OperateResources[n]; + if (logs.Any(x => x.Appid == config.Appid && x.Appuserid == resource._appuserid)) + { + Log.Information($"资源已分配,移除队列后重新分配"); + first.OperateResources.Remove(resource); + continue; + } + if (oldFromLog.Any(x => x.Appuserid == resource._appuserid && x.FromUserid == first.From.Userid)) + { + Log.Information($"同一个人群包内,已转移过的资源不可再次发起转移{config.Id}【{resource._appuserid}】"); + first.OperateResources.Remove(resource); + continue; + } + logs.Add(new ResourceFlowLog + { + Deptid = config.Deptid, + Appid = config.Appid, + Appuserid = resource._appuserid, + FromUserid = first.From.Userid, + ConfigId = config.Id, + FlowTime = DateTime.Now, + Status = ResourceFlowStatus.待转移, + IsDimission = false, + GroupId = config.GroupId, + }); + // 移除其他客服的相同好友 + foreach (var from in flowFroms) + { + var sameResource = from.OperateResources.FirstOrDefault(x => x._appuserid == resource._appuserid); + if (sameResource != null) + { + if (from.From.Id != first.From.Id) + { + if (oldFromLog.Any(x => x.Appuserid == resource._appuserid && x.FromUserid == from.From.Userid)) + { + Log.Information($"同一个人群包内,已转移过的资源不可再次发起转移{config.Id}【{resource._appuserid}】"); + first.OperateResources.Remove(sameResource); + continue; + } + logs.Add(new ResourceFlowLog + { + Deptid = config.Deptid, + Appid = config.Appid, + Appuserid = resource._appuserid, + FromUserid = from.From.Userid, + ConfigId = config.Id, + FlowTime = DateTime.Now, + Status = ResourceFlowStatus.待转移, + IsDimission = false, + GroupId = config.GroupId, + }); + from.AssignedCount++; + from.From.TransferCount++; + } + from.OperateResources.Remove(sameResource); + } + } + first.AssignedCount++; + first.From.TransferCount++; + assignedCount++; + } + //remove时候刷新不对 + /* foreach (var flowFrom in flowFroms) + { + flowFrom.From.TransferCount = flowFrom.SourceResources.Count - flowFrom.OperateResources.Count; + Log.Information($"客服{flowFrom.From.Ename}转移数量{flowFrom.From.TransferCount}"); + }*/ + + // 分配新客服 + var toAssignedCount = 0; + Log.Information($"分配新客服"); + //历史客户有转移的日志 则直接分配给目标人 + var besidesUser = oldToLog.Select(n => n.Appuserid).ToList(); + foreach (var to in tos) + { + //客户存在 转移历史 则直接把他装给历史转移对象 资源归一 + var oldToUser = oldToLog.Where(x => x.ToUserid == to.Userid).Select(n => n.Appuserid).ToList(); + var toLog = logs.Where(n => oldToUser.Contains(n.Appuserid)).Select(n => n.Appuserid).Distinct().ToList(); + var toflowCount = to.FlowCount; + List appuserList = new List(); + if (toLog.Count > 0) + { + appuserList.AddRange(toLog); + toflowCount = toLog.Count > toflowCount ? 0 : toflowCount - toLog.Count; + } + var otheruserid = logs.Where(n => !besidesUser.Contains(n.Appuserid)) + .Select(n => n.Appuserid).Distinct().Take(toflowCount).ToList(); + appuserList.AddRange(otheruserid); + var resources = logs.Where(n => appuserList.Contains(n.Appuserid)).ToList(); + if (!resources.Any()) + { + Log.Error("分配数量不足,跳出!"); + continue; + } + resources.ForEach(x => + { + x.ToUserid = to.Userid; + }); + Log.Information($"{to.Userid}_get_{string.Join(",", resources.Select(n => n.Appuserid))}"); + var allocationUser = resources.Select(n => n.Appuserid).Distinct().ToList(); + besidesUser.AddRange(appuserList); + besidesUser = besidesUser.Distinct().ToList(); + } + config.Status = ResourceConfigStatus.执行完成; + using var transaction = await dncmsRepository.BeginTransactionAsync(); + try + { + await dncmsRepository.GetRepository().UpdateAsync(config, x => new { x.Status }); + await dncmsRepository.GetRepository().BatchUpdateAsync(froms, x => new { x.TransferCount }); + await dncmsRepository.GetRepository().BatchInsertAsync(logs); + await transaction.CommitAsync(); + } + catch (Exception ex) + { + Log.Error(ex, "执行分配服务报错!"); + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + } + } + + public void Dispose() + { + _logger.LogInformation("任务正在关闭"); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + var configs = dncmsRepository.GetRepository().Query() + .Where(x => x.Status == ResourceConfigStatus.执行中).ToList(); + + configs.ForEach(x => x.Status = ResourceConfigStatus.待重启); + + dncmsRepository.GetRepository().BatchUpdateAsync(configs, x => new { x.Status }); + } + } +} \ No newline at end of file diff --git a/code/ResourceFlowWorker/appsettings.Disaster.json b/code/ResourceFlowWorker/appsettings.Disaster.json new file mode 100644 index 0000000..2bfe9f1 --- /dev/null +++ b/code/ResourceFlowWorker/appsettings.Disaster.json @@ -0,0 +1,23 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=10.22.15.61;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=10.22.15.68;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=10.22.15.68;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "TaskConfig": { + "TaskName": "Zxd-ResourceWorker", + "TaskRemarks": "Zxd-ResourceWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "UdbvVSdTs1i8lGsaO7hF7MkOil5ArONoTLaEJePn" + }, + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089", + "nodeWebApi": "http://10.22.15.5:8080" + } +} \ No newline at end of file diff --git a/code/ResourceFlowWorker/appsettings.Production.json b/code/ResourceFlowWorker/appsettings.Production.json new file mode 100644 index 0000000..41a56ad --- /dev/null +++ b/code/ResourceFlowWorker/appsettings.Production.json @@ -0,0 +1,22 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "TaskConfig": { + "TaskName": "Zxd-ResourceWorker", + "TaskRemarks": "Zxd-ResourceWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "UdbvVSdTs1i8lGsaO7hF7MkOil5ArONoTLaEJePn" + }, + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089" + } +} \ No newline at end of file diff --git a/code/ResourceFlowWorker/appsettings.json b/code/ResourceFlowWorker/appsettings.json new file mode 100644 index 0000000..805ef24 --- /dev/null +++ b/code/ResourceFlowWorker/appsettings.json @@ -0,0 +1,22 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "TaskConfig": { + "TaskName": "Zxd-ResourceWorker", + "TaskRemarks": "Zxd-ResourceWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "AukFjLDBeABakHa1jS67DXoRFPh5J6TdVjDqFMwx" + }, + "SystemConfig": { + "zxdCoreApi": "http://192.168.11.81:8089" + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Config/SystemConfig.cs b/code/ToDoWorker/Config/SystemConfig.cs new file mode 100644 index 0000000..53660a5 --- /dev/null +++ b/code/ToDoWorker/Config/SystemConfig.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToDoWorker.Config +{ + public class SystemConfig + { + public string zxdCoreApi { get; set; } + public string BdMarkting { get; set; } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Dockerfile b/code/ToDoWorker/Dockerfile new file mode 100644 index 0000000..6ab0c11 --- /dev/null +++ b/code/ToDoWorker/Dockerfile @@ -0,0 +1,23 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["ResourceFlowWorker/ResourceFlowWorker.csproj", "ResourceFlowWorker/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +RUN dotnet restore "ResourceFlowWorker/ResourceFlowWorker.csproj" +COPY . . +WORKDIR "/src/ResourceFlowWorker" +RUN dotnet build "ResourceFlowWorker.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "ResourceFlowWorker.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ResourceFlowWorker.dll"] \ No newline at end of file diff --git a/code/ToDoWorker/Domain/EventDomain.cs b/code/ToDoWorker/Domain/EventDomain.cs new file mode 100644 index 0000000..a171b7a --- /dev/null +++ b/code/ToDoWorker/Domain/EventDomain.cs @@ -0,0 +1,495 @@ +using DG.EntityFramework; +using DG.Redis; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using ToDoWorker.Helper; +using Zxd.Core.Shared; +using Zxd.Core.Shared.Helpers; +using Zxd.Entity.Action; +using Zxd.Entity.dim; +using Zxd.Entity.Zxd; +using Zxd.EntityFramework; + +namespace ToDoWorker.Domain +{ + public class EventDomain : IEventDomain + { + private readonly IBaseRepository _repository; + + private readonly IBaseRepository _actRepository; + private readonly IConfiguration _configuration; + private readonly SystemConfig? _systemConfig; + private readonly IHttpClient _httpClient; + private readonly IRedisManager _redisManager; + private static string _queueskey = "queue:todoItemQueues"; + private static string _cachekey = "queue:cacheItem"; + private readonly IMapper _mapper; + + public EventDomain( + IBaseRepository zxdRepository, IBaseRepository actRepository, IMapper mapper, + IConfiguration configuration, IHttpClient httpClient, IRedisManager redisManager) + { + _repository = zxdRepository; + _mapper = mapper; + _actRepository = actRepository; + _configuration = configuration; + _systemConfig = _configuration.GetSection("SystemConfig").Get(); + _httpClient = httpClient; + _redisManager = redisManager; + } + + public async Task RunEvent(EventDto eventDto) + { + if (!eventDto.deptid.HasValue) + { + Log.Error($"无部门不处理{eventDto.ToJson()}"); + return false; + } + try + { + var deptSet = await GetSetting(eventDto); + if (deptSet == null) + { + Log.Error($"没找到相关的业务线配置{eventDto.ToJson()}"); + return false; + } + CustomerBehaviorLog newModel = new CustomerBehaviorLog + { + act_date = Convert.ToDateTime(eventDto.act_date), + appid = eventDto.appid, + umid = eventDto.umid, + appuserid = eventDto.appuserid, + resid = eventDto.resid, + uid = eventDto.uid, + unionid = eventDto.unionid, + customerid = eventDto.customerid, + user_type = eventDto.user_type, + eventid = eventDto.eventid, + eventname = eventDto.eventname, + eventmemo = eventDto.eventmemo, + others = eventDto.others, + scenetype = eventDto.scenetype, + scenetypename = eventDto.scenetypename, + sceneid = eventDto.sceneid, + sceneidname = eventDto.sceneidname, + scenename = eventDto.scenename, + sceneext = eventDto.sceneext, + ip = eventDto.ip, + channel = eventDto.channel, + deptid = eventDto.deptid.GetValueOrDefault(), + productplat = eventDto.productplat, + productplatname = eventDto.productplatname, + sinkClickhouseTable = eventDto.sinkClickhouseTable, + updatetime = eventDto.update_time, + ctime = DateTime.Now, + eventtypename = deptSet.memo, + neweventid = deptSet.neweventid, + neweventname = deptSet.remark, + }; + if (eventDto.act_time.HasValue) + { + newModel.act_time = ConvertHelper.JavaLongToDateTime(eventDto.act_time.Value); + } + if (eventDto.leavetime.HasValue) + { + newModel.leavetime = ConvertHelper.JavaLongToDateTime(eventDto.leavetime.Value); + } + newModel.Content = GetNoticeContent(newModel, deptSet); + + //请求大数据接口获取用户昵称和头像 + // 新增优品信息 + using var transaction = await _actRepository.BeginTransactionAsync(); + var url = $"{_systemConfig.BdMarkting}/user/relations?uid={newModel.uid}"; + var empData = await _httpClient.GetAsync>>(url); + if (string.IsNullOrWhiteSpace(newModel.umid)) + { + Log.Information($"bigdata: {newModel.uid} {empData.ToJson()}"); + //var resid = empData.data.FirstOrDefault(n => !string.IsNullOrWhiteSpace(n.resid))?.resid; + var umid = empData.data.FirstOrDefault(n => !string.IsNullOrWhiteSpace(n.umid))?.umid; + //newModel.resid = resid; + newModel.umid = umid; + if (string.IsNullOrWhiteSpace(newModel.umid)) + { + // 任务重试入队 + // 只重试两次 + if (eventDto.RetryCount <= 1) + { + var setting = await GetDelaySec(); + var delaySec = setting == null ? 120 : setting.delaytime.Value; + eventDto.RetryCount++; + eventDto.TaskTime = DateTime.Now.AddSeconds(delaySec); + await _redisManager.EnqueueAsync(_queueskey, eventDto); + Log.Information($"reTry{eventDto.uid}【{umid}】"); + return true; + } + } + } + //插入行为日志 + await _actRepository.GetRepository().InsertAsync(newModel); + List todoItemList = new List(); + + if (empData != null && empData.code == 0) + { + var customerEmps = empData.data.Where(n => n.deptid == newModel.deptid).ToList(); + if (!deptSet.allNotice) + { + if (deptSet.firstCtime.HasValue && deptSet.firstCtime.Value) + { + var firemp = customerEmps.OrderBy(n => n.create_time).FirstOrDefault(); + if (firemp != null) + { + customerEmps = new List { firemp }; + } + } + } + if (customerEmps.Count == 0) + { + if (deptSet.isforce.Value) + { + EmployeeTodoitem todoitem = new EmployeeTodoitem + { + logid = newModel.id, + done = false, + deptid = newModel.deptid, + ctime = DateTime.Now, + utime = DateTime.Now, + act_date = Convert.ToDateTime(newModel.act_date), + act_time = newModel.act_time, + appid = newModel.appid, + appuserid = newModel.appuserid, + resid = newModel.resid, + umid = newModel.umid, + unionid = newModel.unionid, + customerid = newModel.customerid, + uid = newModel.uid, + user_type = newModel.user_type, + eventid = newModel.eventid, + eventname = newModel.eventname, + eventtypename = newModel.eventtypename, + eventmemo = newModel.eventmemo, + others = newModel.others, + scenetype = newModel.scenetype, + scenetypename = newModel.scenetypename, + sceneid = newModel.sceneid, + sceneidname = newModel.sceneidname, + scenename = newModel.scenename, + sceneext = newModel.sceneext, + ip = newModel.ip, + channel = newModel.channel, + productplat = newModel.productplat, + productplatname = newModel.productplatname, + leavetime = newModel.leavetime, + neweventid = newModel.neweventid, + neweventname = newModel.neweventname, + content = newModel.Content, + isread = 0 + }; + await _actRepository.GetRepository().InsertAsync(todoitem); + } + await transaction.CommitAsync(); + return true; + } + //只通知 企微好友 归属关系 + List resultEmp = new List(); + if (deptSet.is_wework) + { + resultEmp.AddRange(customerEmps.Where(n => n.is_wework == 1).ToList()); + } + if (deptSet.is_mobile) + { + resultEmp.AddRange(customerEmps.Where(n => n.is_mobile == 1).ToList()); + } + if (deptSet.is_belong) + { + resultEmp.AddRange(customerEmps.Where(n => n.is_belong == 1).ToList()); + } + resultEmp = resultEmp.Distinct().ToList(); + foreach (var item in resultEmp) + { + EmployeeTodoitem todoitem = new EmployeeTodoitem + { + logid = newModel.id, + eid = item.eid.Value, + ename = item.employee_name, + done = false, + deptid = newModel.deptid, + ctime = DateTime.Now, + utime = DateTime.Now, + Nickname = !string.IsNullOrWhiteSpace(item.Username) ? item.Username : item.Nickname, + Headimgurl = item.Headimgurl, + act_date = Convert.ToDateTime(newModel.act_date), + act_time = newModel.act_time, + appid = newModel.appid, + appuserid = newModel.appuserid, + resid = newModel.resid, + unionid = newModel.unionid, + umid = newModel.umid, + customerid = newModel.customerid, + uid = newModel.uid, + user_type = newModel.user_type, + eventid = newModel.eventid, + eventname = newModel.eventname, + eventtypename = newModel.eventtypename, + eventmemo = newModel.eventmemo, + others = newModel.others, + scenetype = newModel.scenetype, + scenetypename = newModel.scenetypename, + sceneid = newModel.sceneid, + sceneidname = newModel.sceneidname, + scenename = newModel.scenename, + sceneext = newModel.sceneext, + ip = newModel.ip, + channel = newModel.channel, + productplat = newModel.productplat, + productplatname = newModel.productplatname, + leavetime = newModel.leavetime, + neweventid = newModel.neweventid, + neweventname = newModel.neweventname, + content = newModel.Content, + isread = 0 + }; + + todoItemList.Add(todoitem); + } + if (todoItemList.Count > 0) + { + await _actRepository.GetRepository().BatchInsertAsync(todoItemList); + } + await transaction.CommitAsync(); + } + } + catch (Exception ex) + { + Log.Error($"处理待办事项出错{ex.Message}【{eventDto.ToJson()}】"); + } + return true; + } + + public async Task GetSetting(EventDto eventDto) + + { + var cacheKey = "ToDoItemSetting"; + var set = await _redisManager.GetAsync(cacheKey); + if (set == null) + { + var setting = await _repository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "ToDoItemSetting"); + if (setting != null && !string.IsNullOrWhiteSpace(setting.PARAVALUE)) + { + set = JsonHelper.FromJson(setting.PARAVALUE); + await _redisManager.SetAsync(cacheKey, set); + } + } + var deptSetList = set.setting.Where(n => n.eventid == eventDto.eventid).ToList(); + var deptSet = deptSetList.FirstOrDefault(); + foreach (var item in deptSetList) + { + deptSet = null; + if (!string.IsNullOrWhiteSpace(item.source) && !item.source.Contains(eventDto.sinkClickhouseTable)) + { + continue; + } + if (item.scenetype.Count > 0 && !item.scenetype.Contains(eventDto.scenetype)) + { + continue; + } + if (item.sceneid.Count > 0 && !item.sceneid.Contains(eventDto.sceneid)) + { + continue; + } + if (item.deptids.Count > 0 && !item.deptids.Contains(eventDto.deptid.Value)) + { + continue; + } + if (item.appids.Count > 0 && !item.appids.Contains(eventDto.appid)) + { + continue; + } + //找到了 看是否配置了场景 + deptSet = item; + var sceneItem = deptSetList.FirstOrDefault(n => n.scenetype.Contains(eventDto.scenetype)); + if (sceneItem != null) + { + deptSet = sceneItem; + } + break; + } + return deptSet; + } + + public async Task GetDelaySec() + { + var cacheKey = "ToDoItemSetting"; + var set = await _redisManager.GetAsync(cacheKey); + if (set == null) + { + var setting = await _repository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "ToDoItemSetting"); + if (setting != null && !string.IsNullOrWhiteSpace(setting.PARAVALUE)) + { + set = JsonHelper.FromJson(setting.PARAVALUE); + await _redisManager.SetAsync(cacheKey, set); + } + } + return set; + } + + private string GetNoticeContent(CustomerBehaviorLog log, ToDoItemDeptMap set) + { + var content = set.template; + Type type = typeof(CustomerBehaviorLog); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (var item in propertyInfo) + { + var value = item.GetValue(log); + var setValue = value == null ? "" : value.ToString(); + var name = "{" + item.Name + "}"; + if (name == "{act_date}" && content.Contains(name)) + { + content = content.Replace(name, Convert.ToDateTime(setValue).ToString("yyyy-MM-dd")); + continue; + } + if (content.Contains(name)) + { + content = content.Replace(name, setValue); + } + } + content = content.Replace("----", "-").Replace("---", "-").Replace("--", "-").Trim('-'); + return content; + } + + /// + /// 过滤登录事件 + /// + /// + /// + public async Task FilterLogEvent(EventDto eventDto, ToDoItemDeptMap setting) + { + List redisKey = new List(); + + var residkey = setting.residkey; + var useridkey = setting.key; + if (string.IsNullOrWhiteSpace(useridkey)) + { + return true; + } + redisKey.Add(useridkey); + if (!string.IsNullOrWhiteSpace(residkey)) + { + redisKey.Add(residkey); + } + if (eventDto.eventid == (int)EventEnum.登录 && eventDto.sceneid == "soft.login") + { + return false; + } + if (string.IsNullOrWhiteSpace(eventDto.appuserid)) + { + Log.Information($"appuserid为空{eventDto.uid}"); + return false; + } + foreach (var rkey in redisKey) + { + //resid缓存 resid不等于空才生效 + if (rkey.Contains("resid") && string.IsNullOrWhiteSpace(eventDto.resid)) + { + continue; + } + var key = rkey.ToString(); + Type type = typeof(EventDto); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (var item in propertyInfo) + { + var value = item.GetValue(eventDto); + var setValue = value == null ? "" : value.ToString(); + var name = "{" + item.Name + "}"; + if (key.Contains(name)) + { + key = key.Replace(name, setValue); + } + } + if (key.Contains("date_")) + { + var replaceStr = key.Split("date_").LastOrDefault(); + var date = DateTime.Now.ToString(replaceStr.Trim('}').ToString()); + var dateStr = "{date_" + replaceStr; + key = key.Replace(dateStr, date); + } + //如果redis存在对应的键值 则只出现一次通知 + if (await _redisManager.ExistsAsync(key)) + { + return false; + } + else + { + await _redisManager.SetAsync(key, 1, TimeSpan.FromDays(1)); + } + } + return true; + } + + public async Task Repairdata() + { + var sql = @"select * from eventdwd"; + var data = await _actRepository.ExecuteSqlToListAsync(sql); + foreach (var item in data) + { + EventDto eventDto = new EventDto() + { + act_date = item.act_date.ToString(), + appid = item.appid, + appuserid = item.appuserid, + resid = item.resid, + unionid = item.unionid, + channel = item.channel, + customerid = item.customerid, + deptid = item.deptid, + eventid = item.eventid, + eventmemo = item.eventmemo, + eventname = item.eventname, + ip = item.ip, + others = item.others, + productplat = item.productplat, + productplatname = item.productplatname, + sceneext = item.sceneext, + sceneid = item.sceneid, + sceneidname = item.sceneidname, + scenetype = item.scenetype, + scenetypename = item.scenetypename, + sinkClickhouseTable = "手工推送", + uid = item.uid, + user_type = item.user_type, + with_eid = item.with_eid, + with_groupid = item.with_groupid, + with_orgid = item.with_orgid + }; + if (item.act_time.HasValue) + { + eventDto.act_time = ConvertDataTimeLong(item.act_time.Value); + } + if (item.leavetime.HasValue) + { + eventDto.leavetime = ConvertDataTimeLong(item.leavetime.Value); + } + await RunEvent(eventDto); + } + return true; + } + + /// + /// 将DateTime类型转换为long类型 + /// + /// 时间 + /// + public static long ConvertDataTimeLong(DateTime dt) + { + //dateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000 + DateTime dtBase = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + TimeSpan toNow = dt.ToUniversalTime().Subtract(dtBase); + long timeStamp = toNow.Ticks / 10000; + return timeStamp; + } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Domain/IEventDomain.cs b/code/ToDoWorker/Domain/IEventDomain.cs new file mode 100644 index 0000000..94cc553 --- /dev/null +++ b/code/ToDoWorker/Domain/IEventDomain.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToDoWorker.Domain +{ + public interface IEventDomain : IScopedDependency + { + /// + /// 获取活动名称 + /// + /// + /// + Task RunEvent(EventDto request); + + /// + /// 修复数据 + /// + /// + Task Repairdata(); + + Task GetSetting(EventDto eventDto); + + Task GetDelaySec(); + + /// + /// 过滤登录事件 + /// + /// + /// + Task FilterLogEvent(EventDto eventDto, ToDoItemDeptMap setting); + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Dto/CustomerEmployeeMap.cs b/code/ToDoWorker/Dto/CustomerEmployeeMap.cs new file mode 100644 index 0000000..4360468 --- /dev/null +++ b/code/ToDoWorker/Dto/CustomerEmployeeMap.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToDoWorker.Dto +{ + public class CustomerEmployeeMap + { + public int? customerid { get; set; } + public int? eid { get; set; } + public int? deptid { get; set; } + public int? groupid { get; set; } + public string? resid { get; set; } + public string? umid { get; set; } + public string? employee_name { get; set; } + public string? create_time { get; set; } + public int? is_wework { get; set; } + public int? is_mobile { get; set; } + public int? is_belong { get; set; } + + public string? Nickname { get; set; } + public string? Username { get; set; } + + public string? Headimgurl { get; set; } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Dto/EventDto.cs b/code/ToDoWorker/Dto/EventDto.cs new file mode 100644 index 0000000..8ae0425 --- /dev/null +++ b/code/ToDoWorker/Dto/EventDto.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToDoWorker.Dto +{ + public class KafkaEvent + { + public string? data { get; set; } + public string? tableName { get; set; } + } + + public class TestDto + { + public string? act_date { get; set; } + } + + public class EventDto + { + public string? act_date { get; set; } + public long? act_time { get; set; } + public string? appid { get; set; } + public string? appuserid { get; set; } + public int? channel { get; set; } + public int? customerid { get; set; } + public int? deptid { get; set; } + public string? env { get; set; } + public int eventid { get; set; } + public string? eventmemo { get; set; } + public string? eventname { get; set; } + public string? ip { get; set; } + public string? others { get; set; } + public string? productplat { get; set; } + public string? productplatname { get; set; } + public string? resid { get; set; } + public string? umid { get; set; } + public string? sceneext { get; set; } + public string? sceneid { get; set; } + public string? sceneidname { get; set; } + public string? scenename { get; set; } + public int? scenetype { get; set; } + public string? scenetypename { get; set; } + public string? sinkClickhouseTable { get; set; } + + public int? uid { get; set; } + public string? unionid { get; set; } + public int? user_type { get; set; } + public int? with_eid { get; set; } + public int? with_groupid { get; set; } + public int? with_orgid { get; set; } + public long? leavetime { get; set; } + public DateTime? update_time { get; set; } + public DateTime TaskTime { get; set; } + public int RetryCount { get; set; } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Dto/ToDoItemSetting.cs b/code/ToDoWorker/Dto/ToDoItemSetting.cs new file mode 100644 index 0000000..3fad646 --- /dev/null +++ b/code/ToDoWorker/Dto/ToDoItemSetting.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToDoWorker.Dto +{ + public class ToDoItemSetting + { + /// + /// 延迟时间 默认120秒 + /// + public int? delaytime { get; set; } + + public int? batchSize { get; set; } = 100; + public List setting { get; set; } + } + + public class ToDoItemDeptMap + { + public int? neweventid { get; set; } + + /// + /// 事件id + /// + public int? eventid { get; set; } + + /// + /// 大类 + /// + + public string? remark { get; set; } + + /// + /// 小类 + /// + public string? memo { get; set; } + + /// + /// 模板 + /// + public string? template { get; set; } + + /// + /// 场景 + /// + public List scenetype { get; set; } = new List(); + + /// + /// 具体场景 + /// + public List sceneid { get; set; } = new List(); + + /// + /// 是否通知所有好友 + /// + public bool allNotice { set; get; } = true; + + /// + /// 用户类型 + /// + public List userType { get; set; } + + /// + /// 只通知最早的那个客服 + /// + public bool? firstCtime { get; set; } = true; + + public List deptids { get; set; } = new List(); + + /// + /// 通知好友关系 + /// + public bool is_wework { get; set; } = true; + + /// + /// 通知归属关系 + /// + public bool is_mobile { get; set; } = true; + + /// + /// 通知成交关系 + /// + public bool is_belong { get; set; } = true; + + /// + /// Appid + /// + public List appids { get; set; } = new List(); + + public string? source { get; set; } + + /// + /// 当日唯一健值 + /// + public string? key { get; set; } + + /// + /// 当日唯一健值 (resid) + /// + public string? residkey { get; set; } + + /// + /// 没有归属强制插入 + /// + public bool? isforce { get; set; } = false; + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Helper/EventEnum.cs b/code/ToDoWorker/Helper/EventEnum.cs new file mode 100644 index 0000000..dd13f3e --- /dev/null +++ b/code/ToDoWorker/Helper/EventEnum.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ToDoWorker.Helper +{ + public enum EventEnum : int + { + [Description("点击")] + 点击 = 1, + + [Description("报名")] + 报名 = 2, + + [Description("登录")] + 登录 = 6, + + [Description("关注")] + 关注 = 7, + + [Description("取关")] + 取关 = 8, + + [Description("听课")] + 听课 = 17, + + [Description("聊天")] + 聊天 = 20, + + [Description("互动精选")] + 互动精选 = 45, + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Helper/SeqIdGen.cs b/code/ToDoWorker/Helper/SeqIdGen.cs new file mode 100644 index 0000000..9162a92 --- /dev/null +++ b/code/ToDoWorker/Helper/SeqIdGen.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management; +using System.Text; +using System.Threading.Tasks; +using Zxd.SqlSugar; + +namespace ToDoWorker.Helper +{ + public class SeqIdGen + { + //起始的时间戳 2020-01-01 00 00 00 开始 + private static long START_STMP = 1577808000000L; + + //每一部分占用的位数 + private static int SEQUENCE_BIT = 12; //序列号占用的位数 + + private static int MACHINE_BIT = 6; //机器标识占用的位数 + private static int DATACENTER_BIT = 3;//数据中心占用的位数 + + //每一部分的最大值 + private static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT); + + private static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT); + private static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); + + //每一部分向左的位移 + private static int MACHINE_LEFT = SEQUENCE_BIT; + + private static int DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT; + private static int TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT; + + private long datacenterId = 1; //数据中心 + private long machineId = 1; //机器标识 + private long sequence = 0L; //序列号 + private long lastStmp = -1L;//上一次时间戳 + + private static Random r = new Random(); + + private static readonly object _locker = new object(); + private static readonly object _Idlocker = new object(); + private static SeqIdGen _instance = (SeqIdGen)null; + + public static SeqIdGen Instance + { + get + { + if (_instance == null) + { + lock (_locker) + { + if (_instance == null) + _instance = new SeqIdGen(); + } + } + return SeqIdGen._instance; + } + } + + private SeqIdGen() + { + // SeqIdGenInitRedis(); + SeqIdGenInitConfig(); //从appsetting取 + } + + public void SeqIdGenInitConfig() + { + var _machineId = long.Parse(InitConfiguration.GetSection("machineId").Value.ToString()); + var _datacenterId = long.Parse(InitConfiguration.GetSection("datacenterId").Value.ToString()); + SeqIdGenInit(_machineId, _datacenterId); + } + + /* public void SeqIdGenInitRedis() + { + var cpukey = getCpu(); + var rdc = RedisManager.GetRedisClient2(); + var mechineSeq = rdc.GetValueFromHash("Num:MechineSeq", cpukey); + if (string.IsNullOrEmpty(mechineSeq)) + { + mechineSeq = rdc.IncrementValue("Num:MSeq").ToString(); + rdc.SetEntryInHash("Num:MechineSeq", cpukey, mechineSeq); + } + SeqIdGenInit(long.Parse(mechineSeq), datacenterId); + }*/ + + public string GetDiskVolumeSerialNumber() + { + ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); + ManagementObject disk = new ManagementObject("win32_LogHelpericaldisk.deviceid=\"c:\""); + disk.Get(); + return disk.GetPropertyValue("VolumeSerialNumber").ToString(); + } + + //获得CPU的序列号 + public string getCpu() + { + string strCpu = null; + ManagementClass myCpu = new ManagementClass("win32_Processor"); + ManagementObjectCollection myCpuConnection = myCpu.GetInstances(); + foreach (ManagementObject myObject in myCpuConnection) + { + strCpu = myObject.Properties["Processorid"].Value.ToString(); + break; + } + return strCpu; + } + + public void SeqIdGenInit(long cid, long mid) + { + if (cid > MAX_DATACENTER_NUM || cid < 0) throw new Exception($"中心Id应在(0,{MAX_DATACENTER_NUM})之间"); + if (mid > MAX_MACHINE_NUM || mid < 0) throw new Exception($"机器Id应在(0,{MAX_MACHINE_NUM})之间"); + datacenterId = cid; + machineId = mid; + } + + /// + /// 产生下一个ID + /// + /// + public long nextId() + { + lock (_Idlocker) + { + long currStmp = getNewstmp(); + if (currStmp < lastStmp) throw new Exception("时钟倒退,Id生成失败!"); + + if (currStmp == lastStmp) + { + //相同毫秒内,序列号自增 + sequence = (sequence + 1) & MAX_SEQUENCE; + //同一毫秒的序列数已经达到最大 + if (sequence == 0L) currStmp = getNextMill(); + } + else + { + //不同毫秒内,序列号置为0 + sequence = 0L; + } + + lastStmp = currStmp; + + return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分 + | datacenterId << DATACENTER_LEFT //数据中心部分 + | machineId << MACHINE_LEFT //机器标识部分 + | sequence; //序列号部分 + } + } + + private long getNextMill() + { + long mill = getNewstmp(); + while (mill <= lastStmp) + { + mill = getNewstmp(); + } + return mill; + } + + private long getNewstmp() + { + return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; + } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Program.cs b/code/ToDoWorker/Program.cs new file mode 100644 index 0000000..6822359 --- /dev/null +++ b/code/ToDoWorker/Program.cs @@ -0,0 +1,79 @@ +using ClickHouse.EntityFrameworkCore.Extensions; +using DG.EntityFramework; +using DG.Kafka; +using Exceptionless; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Hosting; +using ToDoWorker; +using Zxd.EntityFramework; + +try +{ + var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + Console.WriteLine($"Env: {env}"); + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{env ?? "Production"}.json", true) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{env ?? "Production"}.json", true) + .Build(); + + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) + .WriteTo.Exceptionless(config.GetValue("Exceptionless:ApiKey"), config.GetValue("Exceptionless:ServerUrl"), new string[] { "WeworkUserWorker" }) + .CreateLogger(); + Log.Logger = logger; + Log.Information("Starting ToDoWorker"); + IServiceCollection services = new ServiceCollection(); + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(config); + services.AddOptions() + .Configure(e => config.GetSection("SystemConfig").Bind(e)); + ExceptionlessClient.Default.Startup(config.GetValue("Exceptionless:ApiKey")); + ExceptionlessClient.Default.Configuration.ServerUrl = config.GetValue("Exceptionless:ServerUrl"); + ExceptionlessClient.Default.Configuration.DefaultTags.Add("Zxd-ToDoWorker"); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(config.GetConnectionString("zxdcrm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("crmcloud"), ServerVersion.AutoDetect(config.GetConnectionString("hgaction"))); + }); + /* services.AddDGEntityFramework(options => + { + options.UseClickHouse(config.GetConnectionString("dim")); + });*/ + services.AddAutoIoc(typeof(IScopedDependency), LifeCycle.Scoped) + .AddAutoIoc(typeof(ISingletonDependency), LifeCycle.Singleton) + .AddAutoIoc(typeof(ITransientDependency), LifeCycle.Transient) + .AddMapper(); + services.AddKafkaWorker(config); + services.AddWorker(config); + services.AddRedis(config); + services.AddDGHttpClient(); + services.AddRegisterWorker(); + //services.AddRegisterWorker(); + services.AddRegisterBatchWorker(); + + //构建容器 + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var workerManager = serviceProvider.GetRequiredService(); + var consumers = config.GetSection("Consumers").Get>(); ; + await workerManager.RegisterBatchWorker(consumers?.FirstOrDefault()?.Topic, 1); + var builder = new HostBuilder(); + await builder.RunConsoleAsync(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/code/ToDoWorker/Properties/launchSettings.json b/code/ToDoWorker/Properties/launchSettings.json new file mode 100644 index 0000000..801aa73 --- /dev/null +++ b/code/ToDoWorker/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "profiles": { + "ToDoWorker": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Serilog.Production.json b/code/ToDoWorker/Serilog.Production.json new file mode 100644 index 0000000..491af8c --- /dev/null +++ b/code/ToDoWorker/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Serilog.json b/code/ToDoWorker/Serilog.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/ToDoWorker/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/ToDoWorker/ToDoWorker - Backup.csproj b/code/ToDoWorker/ToDoWorker - Backup.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/code/ToDoWorker/ToDoWorker - Backup.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/code/ToDoWorker/ToDoWorker.csproj b/code/ToDoWorker/ToDoWorker.csproj new file mode 100644 index 0000000..2bdf552 --- /dev/null +++ b/code/ToDoWorker/ToDoWorker.csproj @@ -0,0 +1,75 @@ + + + + Exe + net6.0 + enable + enable + + + + + $(DockerDefaultDockerfile) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + diff --git a/code/ToDoWorker/Workers/ActionConsumeWorker.cs b/code/ToDoWorker/Workers/ActionConsumeWorker.cs new file mode 100644 index 0000000..42f1296 --- /dev/null +++ b/code/ToDoWorker/Workers/ActionConsumeWorker.cs @@ -0,0 +1,157 @@ +using DG.EntityFramework; +using DG.Redis; +using DG.Worker; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ToDoWorker.Domain; +using ToDoWorker.Dto; +using ToDoWorker.Helper; +using Zxd.Core.Shared.Helpers; +using Zxd.Entity.Action; +using Zxd.Entity.dim; +using Zxd.Entity.Zxd; +using Zxd.EntityFramework; +using Zxd.SqlSugar; + +namespace ToDoWorker.Workers +{ + /// + /// 消费队列 + /// + internal class ActionConsumeWorker : WorkerBase + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + private readonly IRedisManager _redisManager; + private static string _oldQueueskey = "queue:todoqueues"; + private static string _queueskey = "queue:todoItemQueues"; + private static string _cachekey = "queue:cacheItem"; + + public ActionConsumeWorker(ILogger logger, + IServiceProvider serviceProvider, + IConfiguration configuration, + IHttpClient httpClient, + IRedisManager redisManager + ) : base(logger) + { + _logger = logger; + _serviceProvider = serviceProvider; + _redisManager = redisManager; + } + + /// + /// + /// + /// + /// + protected override async Task DoWorkAsync() + { + // + Stopwatch stopwatch = Stopwatch.StartNew(); + using var scope = _serviceProvider.CreateAsyncScope(); + var setting = await scope.ServiceProvider.GetRequiredService().GetDelaySec(); + var batchSize = setting == null ? 100 : setting.batchSize.Value; + for (var i = 0; i < batchSize; i++) + { + //ToDoEventSingleton.Instance.TryDequeue(delaySec, out EventDto? kafkaEvent); + var kafkaEvent = await Dequeue(); + if (kafkaEvent != null) + { + //需要新注册实体 + await scope.ServiceProvider.GetRequiredService().RunEvent(kafkaEvent); + // 任务处理完,移除缓存数据 + await RemoveCache(); + } + else + { + //如果拿出为null 则跳出 + break; + } + } + stopwatch.Stop(); + } + + private async Task test() + { + var ss = "{\"act_date\":\"2023-08-18\",\"act_time\":1692351466000,\"appid\":\"wx1d0e531a680d947b\",\"appuserid\":\"olxOo6KlSg_QP5PL42skLpozzelI\",\"channel\":0,\"customerid\":7729244,\"deptid\":40,\"env\":\"prod\",\"eventid\":17,\"eventmemo\":\"六维共振\",\"eventname\":\"听课\",\"ip\":\"223.106.130.63\",\"others\":\"86\",\"productplat\":\"\",\"productplatname\":null,\"resid\":\"436799775507061617\",\"sceneext\":\"\",\"sceneid\":\"156\",\"sceneidname\":null,\"scenename\":null,\"scenetype\":6,\"scenetypename\":\"直播间\",\"sinkClickhouseTable\":\"act_action_event\",\"uid\":7750620,\"unionid\":\"o5bj2wWFzxBwWj4eIepDE8OISFs0\",\"user_type\":1,\"with_eid\":0,\"with_groupid\":0,\"with_orgid\":0,\"leavetime\":null,\"update_time\":null,\"TaskTime\":\"2023-08-18T17:39:50.3985639+08:00\",\"RetryCount\":0}"; + var kafkaEvent = JsonHelper.FromJson(ss); + using var scope = _serviceProvider.CreateAsyncScope(); + await scope.ServiceProvider.GetRequiredService().RunEvent(kafkaEvent); + //await _redisManager.EnqueueAsync(_queueskey, kafkaEvent); + } + + /// + /// 任务出队 + /// + /// + private async Task Dequeue() + { + var now = DateTime.Now; + var kafkaEvent = default(EventDto?); + + // 是否存旧队列数据(兼容旧版) + if (await _redisManager.ExistsAsync(_oldQueueskey)) + { + var data = await _redisManager.GetListAsync(_oldQueueskey); + data = data.OrderByDescending(x => x.TaskTime).ToList(); + + foreach (var item in data) + { + // 任务入队 + item.TaskTime = DateTime.Now.AddSeconds(120); + item.RetryCount = 0; + await _redisManager.EnqueueAsync(_queueskey, item); + } + await _redisManager.RemoveAsync(_oldQueueskey); + } + // 判断是否存在缓存处理数据 + if (await _redisManager.ExistsAsync(_cachekey)) + { + kafkaEvent = await _redisManager.GetAsync(_cachekey); + if (kafkaEvent.TaskTime >= now) + { + return null; + } + //Log.Information($"任务出队处理, uid: [{kafkaEvent.uid}], resid: [{kafkaEvent.resid}]"); + return kafkaEvent; + } + + // 判断是否存在队列数据 + if (await _redisManager.ExistsAsync(_queueskey)) + { + kafkaEvent = await _redisManager.BlockingDequeueAsync(_queueskey); + if (kafkaEvent != null) + { + // 写入处理缓存 + await _redisManager.SetAsync(_cachekey, kafkaEvent); + if (kafkaEvent.TaskTime >= now) + { + return null; + } + return kafkaEvent; + } + } + + return kafkaEvent; + } + + /// + /// 移除缓存处理数据 + /// + /// + private async Task RemoveCache() + { + if (await _redisManager.ExistsAsync(_cachekey)) + { + var kafkaEvent = await _redisManager.GetAsync(_cachekey); + await _redisManager.RemoveAsync(_cachekey); + } + } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Workers/RepairDataWorker.cs b/code/ToDoWorker/Workers/RepairDataWorker.cs new file mode 100644 index 0000000..c58bb43 --- /dev/null +++ b/code/ToDoWorker/Workers/RepairDataWorker.cs @@ -0,0 +1,76 @@ +using DG.EntityFramework; +using DG.Redis; +using DG.Worker; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ToDoWorker.Domain; +using ToDoWorker.Dto; +using ToDoWorker.Helper; +using Zxd.Core.Shared.Helpers; +using Zxd.Entity.Action; +using Zxd.Entity.dim; +using Zxd.Entity.Zxd; +using Zxd.EntityFramework; +using Zxd.SqlSugar; + +namespace ToDoWorker.Workers +{ + /// + /// 消费队列 + /// + internal class RepairDataWorker : WorkerBase + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + private readonly IRedisManager _redisManager; + private static string _oldQueueskey = "queue:todoqueues"; + private static string _queueskey = "queue:todoItemQueues"; + private static string _cachekey = "queue:cacheItem"; + + public RepairDataWorker(ILogger logger, + IServiceProvider serviceProvider, + IConfiguration configuration, + IHttpClient httpClient, + IRedisManager redisManager + ) : base(logger) + { + _logger = logger; + _serviceProvider = serviceProvider; + _redisManager = redisManager; + } + + /// + /// + /// + /// + /// + protected override async Task DoWorkAsync() + { + // + Stopwatch stopwatch = Stopwatch.StartNew(); + using var scope = _serviceProvider.CreateAsyncScope(); + var isRepairData = await _redisManager.GetAsync("RepairData"); + if (isRepairData != 1) + { + await _redisManager.SetAsync("RepairData", 1); + try + { + await scope.ServiceProvider.GetRequiredService().Repairdata(); + stopwatch.Stop(); + } + catch (Exception ex) + { + Log.Error($"初始化数据出错{ex.Message}"); + } + } + await Task.Delay(100000); + } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/Workers/ToDoWorker.cs b/code/ToDoWorker/Workers/ToDoWorker.cs new file mode 100644 index 0000000..a0cdb5b --- /dev/null +++ b/code/ToDoWorker/Workers/ToDoWorker.cs @@ -0,0 +1,84 @@ +using DG.Redis; +using DG.Worker; +using Exceptionless.Utility; +using Microsoft.Extensions.Configuration; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ToDoWorker.Domain; +using ToDoWorker.Helper; +using Zxd.Entity.Dncms; + +namespace ToDoWorker.Workers +{ + internal class ToDoWorker : BatchKafkaWorkerBase + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + private readonly IRedisManager _redisManager; + private static string _queueskey = "queue:todoItemQueues"; + private static string _cachekey = "queue:cacheItem"; + + public ToDoWorker(ILogger logger, + IServiceProvider serviceProvider, + IRedisManager redisManager + ) : base(logger) + { + _logger = logger; + _serviceProvider = serviceProvider; + _redisManager = redisManager; + } + + /// + /// + /// + /// + /// + protected override async Task DoWorkAsync(List eventDtos) + { + foreach (var eventDto in eventDtos) + { + //Log.Information($"eventDtos:{eventDto.ToJson()}"); + if (eventDto.tableName == "act_action_event" && !string.IsNullOrEmpty(eventDto.data)) + { + try + { + EventDto model = JsonHelper.FromJson(eventDto.data); + //需要新注册实体 + using var scope = _serviceProvider.CreateAsyncScope(); + var eventService = scope.ServiceProvider.GetRequiredService(); + var setting = await scope.ServiceProvider.GetRequiredService().GetDelaySec(); + var delaySec = setting == null ? 120 : setting.delaytime.Value; + var deptSet = await eventService.GetSetting(model); + + if (deptSet != null && model.uid > 0) + { + //登录特殊处理 一天同一个人只出现一次 + if (!await eventService.FilterLogEvent(model, deptSet)) + { + return; + } + if (model != null) + { + // 任务入队 + model.TaskTime = DateTime.Now.AddSeconds(delaySec); + await _redisManager.EnqueueAsync(_queueskey, model); + } + } + /* else + { + Log.Information($"Event跳过{model.eventname}【{model.sceneid}】{model.uid}"); + }*/ + } + catch (Exception ex) + { + Log.Error($"DoWorkAsync处理失败{eventDto.ToJson()},{ex.Message}"); + } + } + } + } + } +} \ No newline at end of file diff --git a/code/ToDoWorker/appsettings.Production.json b/code/ToDoWorker/appsettings.Production.json new file mode 100644 index 0000000..f460d2d --- /dev/null +++ b/code/ToDoWorker/appsettings.Production.json @@ -0,0 +1,43 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "hgaction": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=hgaction;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "crmcloud": "Server=dgbigdata.mysql.rds.aliyuncs.com;Database=crm_cloud;UserId=crm_rd;Password=K#RQ1TYx9my;port=3306;" + }, + "TaskConfig": { + "TaskName": "ToDoWorker", + "TaskRemarks": "ToDoWorker", + "Enable": true, + "MilliSecondsDelay": 200 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "h6SHsDDLmWnC9E9WeEnRU7Sm3Em5RUuSKFVbSUWT" + }, + "machineId": 1, + "datacenterId": 1, + "Consumers": [ + { + "Host": "172.18.11.77:9092,172.18.11.76:9092", + "GroupId": "crm", + "Topic": "dwd_act_user_event_alert" + } + ], + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089", + "BdMarkting": "http://172.18.11.55:28065" + }, + "Redis": [ + { + "Name": "Hg", + "HostName": "172.18.11.63", + "Port": "6379", + "Password": "sa123456.", + "Defaultdatabase": "0" + } + ] +} \ No newline at end of file diff --git a/code/ToDoWorker/appsettings.json b/code/ToDoWorker/appsettings.json new file mode 100644 index 0000000..a84f068 --- /dev/null +++ b/code/ToDoWorker/appsettings.json @@ -0,0 +1,50 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "hgaction": "Server=192.168.11.141;Database=hgaction;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crmcloud": "Server=192.168.11.141;Database=crm_cloud;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "TaskConfig": { + "TaskName": "ToDoWorker", + "TaskRemarks": "ToDoWorker", + "Enable": true, + "MilliSecondsDelay": 500 + }, + "machineId": 1, + "datacenterId": 1, + "Consumers": [ + { + "Host": "192.168.11.104:9092,192.168.11.104:9092", + "GroupId": "crm", + "Topic": "dwd_act_user_alert_test1" + } + ], + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "AukFjLDBeABakHa1jS67DXoRFPh5J6TdVjDqFMwx" + }, + "SystemConfig": { + "zxdCoreApi": "http://192.168.11.81:8089", + "BdMarkting": "http://bd-markting.soft.dn8188.com" + }, + "Redis": [ + { + "Name": "ZXD", + "HostName": "192.168.11.81", + "Port": "6379", + "Password": "Abc@123456", + "Defaultdatabase": "1" + }, + { + "Name": "UserCenter", + "HostName": "192.168.11.103", + "Port": "6379", + "Password": "123", + "Defaultdatabase": "0" + } + ] +} \ No newline at end of file diff --git a/code/WeworkUserWorker/Config/SystemConfig.cs b/code/WeworkUserWorker/Config/SystemConfig.cs new file mode 100644 index 0000000..12ed286 --- /dev/null +++ b/code/WeworkUserWorker/Config/SystemConfig.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WeworkUserWorker.Config +{ + public class SystemConfig + { + public string zxdCoreApi { get; set; } + public string nodeWebApi { get; set; } + } +} \ No newline at end of file diff --git a/code/WeworkUserWorker/Dockerfile b/code/WeworkUserWorker/Dockerfile new file mode 100644 index 0000000..90a3762 --- /dev/null +++ b/code/WeworkUserWorker/Dockerfile @@ -0,0 +1,23 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["WeworkUserWorker/WeworkUserWorker.csproj", "WeworkUserWorker/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +RUN dotnet restore "WeworkUserWorker/WeworkUserWorker.csproj" +COPY . . +WORKDIR "/src/WeworkUserWorker" +RUN dotnet build "WeworkUserWorker.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "WeworkUserWorker.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "WeworkUserWorker.dll"] \ No newline at end of file diff --git a/code/WeworkUserWorker/Dto/ZXDApiResult.cs b/code/WeworkUserWorker/Dto/ZXDApiResult.cs new file mode 100644 index 0000000..a3599ff --- /dev/null +++ b/code/WeworkUserWorker/Dto/ZXDApiResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WeworkUserWorker.Dto +{ + public class ZXDApiResult where T : class + { + public int code { get; set; } + public string? message { get; set; } + public T data { get; set; } + } +} diff --git a/code/WeworkUserWorker/Program.cs b/code/WeworkUserWorker/Program.cs new file mode 100644 index 0000000..94f8800 --- /dev/null +++ b/code/WeworkUserWorker/Program.cs @@ -0,0 +1,89 @@ +using DG.EntityFramework; +using DG.Kafka.Worker; +using Exceptionless; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Serilog; +using WeworkUserWorker.Config; +using Zxd.Core.Shared.Dto; +using Zxd.EntityFramework; + +try +{ + var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + Console.WriteLine($"Env: {env}"); + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{env ?? "Production"}.json", true) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{env ?? "Production"}.json", true) + .Build(); + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) + .WriteTo.Exceptionless(config.GetValue("Exceptionless:ApiKey"), config.GetValue("Exceptionless:ServerUrl"), new string[] { "WeworkUserWorker" }) + .CreateLogger(); + Log.Logger = logger; + Log.Information("Starting WeworkUserWorker"); + IServiceCollection services = new ServiceCollection(); + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(config); + services.AddOptions() + .Configure(e => config.GetSection("SystemConfig").Bind(e)); + ExceptionlessClient.Default.Startup(config.GetValue("Exceptionless:ApiKey")); + ExceptionlessClient.Default.Configuration.ServerUrl = config.GetValue("Exceptionless:ServerUrl"); + //services.AddRedis(config); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(config.GetConnectionString("zxdcrm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(config.GetConnectionString("dncmsbase"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("usercenter"), ServerVersion.AutoDetect(config.GetConnectionString("usercenter"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("dncms"), ServerVersion.AutoDetect(config.GetConnectionString("dncms"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("crm"), ServerVersion.AutoDetect(config.GetConnectionString("crm"))); + }); + services.AddDGEntityFramework(options => + { + options.UseMySql(config.GetConnectionString("companyBaseConf"), ServerVersion.AutoDetect(config.GetConnectionString("companyBaseConf"))); + }); + services.AddKafkaWorker(config); + services.AddRedis(config); + services.AddDGHttpClient(); + services.AddRegisterWorker(); + //构建容器 + IServiceProvider serviceProvider = services.BuildServiceProvider(); + var workerManager = serviceProvider.GetRequiredService(); + await workerManager.RegisterWorker("crm-topic"); + await workerManager.RegisterWorker("crm-topic"); + await workerManager.RegisterWorker("crm-topic"); + await workerManager.RegisterWorker("crm-topic"); + await workerManager.RegisterWorker("crm-topic"); + var builder = new HostBuilder(); + await builder.RunConsoleAsync(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/code/WeworkUserWorker/Properties/launchSettings.json b/code/WeworkUserWorker/Properties/launchSettings.json new file mode 100644 index 0000000..38ab25f --- /dev/null +++ b/code/WeworkUserWorker/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "profiles": { + "WeworkUserWorker": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/code/WeworkUserWorker/Serilog.Production.json b/code/WeworkUserWorker/Serilog.Production.json new file mode 100644 index 0000000..491af8c --- /dev/null +++ b/code/WeworkUserWorker/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} \ No newline at end of file diff --git a/code/WeworkUserWorker/Serilog.json b/code/WeworkUserWorker/Serilog.json new file mode 100644 index 0000000..067e7b1 --- /dev/null +++ b/code/WeworkUserWorker/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/WeworkUserWorker/WeworkUserWorker.csproj b/code/WeworkUserWorker/WeworkUserWorker.csproj new file mode 100644 index 0000000..d6f4f67 --- /dev/null +++ b/code/WeworkUserWorker/WeworkUserWorker.csproj @@ -0,0 +1,71 @@ + + + + Exe + net6.0 + enable + enable + Linux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + diff --git a/code/WeworkUserWorker/Workers/WeworkTagWorker.cs b/code/WeworkUserWorker/Workers/WeworkTagWorker.cs new file mode 100644 index 0000000..770fc56 --- /dev/null +++ b/code/WeworkUserWorker/Workers/WeworkTagWorker.cs @@ -0,0 +1,723 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WeworkUserWorker.Config; +using Zxd.Entity.Dncms; +using Zxd.Entity.UserCenter; +using Zxd.EntityFramework; +using Microsoft.Extensions.Options; +using DG.Kafka; +using MySqlConnector; +using System.Diagnostics; +using Zxd.Core.Shared.Dto; +using DG.Redis; +using Zxd.Entity.Zxd; + +namespace WeworkUserWorker.Workers +{ + internal class WeworkTagWorker : KafkaWorkerBase + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + private readonly IOptionsSnapshot _systemConfig; + private readonly IHttpClient _httpClient; + private readonly IRedisManager _redisManager; + + public WeworkTagWorker( + IServiceProvider serviceProvider, + IOptionsSnapshot systemConfig, + ILogger logger, + IHttpClient httpClient, IRedisManager redisManager + ) : base(logger) + { + _serviceProvider = serviceProvider; + _httpClient = httpClient; + _systemConfig = systemConfig; + _logger = logger; + _redisManager = redisManager; + } + + /// + /// 处理好友最终关系 + /// 数据逻辑 + /// 1、通过appid和appuserid去usercenter.userinfo中找出customerid,并通过customerid查出userinfo中所有用户数据, + /// 2、假如数据中没有resid、忽略不处理。 + /// 3、假如有resid去dncms.weworkexternaluser中查找数据,subscribe = 1筛选数据,用subscribetime去 res_resid_weworkuser + /// 表中appid、appuserid数据取firsttime和最早的subscribetime 对比,有变动就修正,假如res_resid_weworkuser 中的在刚刚查找出来没有关注数据了, + /// 将status改成0 。假如res_resid_weworkuser 没有数据,插入一条数据。 + /// + /// + /// + protected override async Task DoWorkAsync(WeWorkTagDto t) + { + IList resResids = new List(); + IList users = new List(); + List rrWeworkUser = new List(); + List mainExternalUsers = new List(); + List secExternalUsers = new List(); + try + { + await EventLog(t); + switch (t.type?.ToLower()) + { + case "subscribe"://关注 + case "unsubscribe"://取关 + _logger.LogWarning("开始处理取关!"); + users = await GetUser(t.appid, t.appuserid); //请求此用户的所有用户信息 + rrWeworkUser = await BindWeworkUser(users, mainExternalUsers);//查询当前客户好友关系 + foreach (var item in rrWeworkUser) + { + await ChangeWeworkUser(item);//入库 + } + //await SetSourcePassInfo(mainExternalUsers, users, t); + _logger.LogWarning("结束处理取关!"); + break; + + case "merge"://合并 + _logger.LogWarning("开始处理合并!"); + if (int.TryParse(t.cid, out int incid)) + { + users = await GetUser(incid);//请求此用户的所有用户信息 + rrWeworkUser = await BindWeworkUser(users, mainExternalUsers);//查询当前客户好友关系 + foreach (var item in rrWeworkUser) + { + await ChangeWeworkUser(item);//入库 + } + } + //await SetSourcePassInfo(mainExternalUsers, users, t); + _logger.LogWarning("结束处理合并!"); + break; + + case "unmerge"://解绑 + _logger.LogWarning("开始处理解绑!"); + var cidarry = t.cid?.Trim().Split(','); + if (cidarry != null && cidarry.Count() == 2) + { + var scid = cidarry[0]; + var ecid = cidarry[1]; + var susers = await GetUser(int.Parse(scid));//分别查询出两个cid对应的客户信息 + var eusers = await GetUser(int.Parse(ecid));// + var swu = await BindWeworkUser(susers, mainExternalUsers);//查询当前客户好友关系 + //await SetSourcePassInfo(mainExternalUsers, susers, t); + var ewu = await BindWeworkUser(eusers, secExternalUsers);//查询当前客户好友关系 + //await SetSourcePassInfo(secExternalUsers, eusers, t); + foreach (var item in swu) + { + await ChangeWeworkUser(item);//入库 + } + foreach (var item in ewu) + { + await ChangeWeworkUser(item);//入库 + } + var unlist = await UnBindWeworkUser(susers, eusers);//拼接两个cid的 重叠部分 + foreach (var item in unlist) + { + //事业部不发生变化 + await ChangeWeworkUser(item, false);//解绑匹配的新数据不入库,旧数据标记删除 + } + } + _logger.LogWarning("结束处理解绑!"); + break; + + case "eidbind"://跨部门换绑工号 300秒超时 + if (t.olddeptid.HasValue && t.deptid.HasValue && t.olddeptid != t.deptid) + { + var kfuser = await GetKFUser(t.appid, t.userid); //请求此用户的所有用户信息 + if (kfuser.Count() > 300) + {//给队列逐条处理 + IList appidStr = new List(); + IList euseridStr = new List(); + foreach (var item in kfuser) + { + appidStr.Add(item.Appid_ext); + euseridStr.Add(item.Externaluserid); + if (appidStr.Count() > 9) + { + WeworkWorkerDto dto = new WeworkWorkerDto(); + dto.type = "inner_eidbind_item"; + dto.appuserid = String.Join(",", euseridStr); + dto.appid = String.Join(",", appidStr); + dto.deptid = t.deptid; + dto.olddeptid = t.olddeptid; + PushKafKa(dto); + appidStr = new List(); + euseridStr = new List(); + } + } + //循环结束验证是否有未完成 + if (euseridStr.Any()) + { + WeworkWorkerDto lastdto = new WeworkWorkerDto(); + lastdto.type = "inner_eidbind_item"; + lastdto.appuserid = String.Join(",", euseridStr); + lastdto.appid = String.Join(",", appidStr); + lastdto.deptid = t.deptid; + lastdto.olddeptid = t.olddeptid; + PushKafKa(lastdto); + } + } + else + {//直接批量处理 + foreach (var item in kfuser)//逐个好友处理数据 + { + var iusers = await GetUser(item.Appid, item.Externaluserid); + List kfExternal = new List(); + rrWeworkUser = await BindWeworkUser(iusers, kfExternal);//重新计算当前客户好友关系 + //await SetSourcePassInfo(kfExternal, iusers, t); + foreach (var rritem in rrWeworkUser) + { + await ChangeWeworkUser(rritem);//更新和插入 事业部变更后的好友关系 + if (rritem.deptid == t.deptid) + { + rritem.deptid = t.olddeptid.Value; + await ChangeWheorkUserDeptid(rritem);//查找 事业部变更前的好友关系,有则标记删除 + } + } + } + } + } + break; + + case "inner_eidbind_item"://逐个处理换绑资源 + if (!string.IsNullOrEmpty(t.appid) && !string.IsNullOrEmpty(t.appuserid) && t.olddeptid.HasValue && t.deptid.HasValue) + { + var appidList = t.appid.Split(',').ToList(); + var appuseridList = t.appuserid.Split(',').ToList(); + if (appidList.Count() == appuseridList.Count()) + {//一次性处理9个 + int index = 0; + foreach (var appid in appidList) + { + var appuserid = appuseridList[index]; + users = await GetUser(appid, appuserid); + List kfExternal = new List(); + rrWeworkUser = await BindWeworkUser(users, kfExternal);//重新计算当前客户好友关系 + //await SetSourcePassInfo(kfExternal, users, t); + foreach (var rritem in rrWeworkUser) + { + await ChangeDeptWeworkUser(rritem, t.olddeptid.Value);//更新和插入 事业部变更后的好友关系 + } + index++; + } + } + } + break; + + case "register": + users = await GetUser(t.appid, t.appuserid); + rrWeworkUser = await BindWeworkUser(users, mainExternalUsers);//重新计算当前客户好友关系 + //await SetSourcePassInfo(mainExternalUsers, users, t); + break; + } + } + catch (Exception ex) + { + _logger.LogWarning(ex.Message, ex); + } + } + + /// + /// 查询客服名下所有客户 + /// + /// + /// + /// + private async Task> GetKFUser(string appid, string userid) + { + MySqlParameter[] param = new MySqlParameter[] { + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=appid,ParameterName="appid"}, + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=userid,ParameterName="userid"} + }; + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + var extUser = await dncmsRepository.ExecuteSqlToListAsync($"select appid,userid,appid_ext,externaluserid,deptid,unionid,subscribe,subscribetime from WeworkExternalUser where appid=@appid and userid=@userid", param); + return extUser; + } + + /// + /// 获取客户当前 resid数据 + /// + /// + /// + /// + private async Task> GetUser(string appid, string appuserid) + { + IList res = new List(); + var url = $"{_systemConfig.Value.zxdCoreApi}/Api/UserInfo/list"; + var resModel = await _httpClient.GetAsync>>($"{url}?appid={appid}&appuserid={appuserid}"); + if (resModel.code == 0) + { + res = resModel.data; + } + return res; + } + + /// + /// 获取客户当前 resid数据 + /// + /// + /// + /// + private async Task> GetUser(int? customerid) + { + IList res = new List(); + if (customerid.HasValue) + { + var url = $"{_systemConfig.Value.zxdCoreApi}/Api/UserInfo/list"; + //var req = HttpHelper.GetData(url, $"?cid={customerid}", Encoding.UTF8); + //var resModel = JsonHelper.FromJson>>(req); + + var resModel = await _httpClient.GetAsync>>($"{url}?cid={customerid}"); + if (resModel.code == 0) + { + res = resModel.data; + } + } + return res; + } + + /// + /// 匹配两个好友解绑时的所有情况 + /// + /// + /// + /// + private async Task> UnBindWeworkUser(IList userInfo1, IList userInfo2) + { + IList res = new List(); + //var userGup1 = userInfo1.Where(m => !string.IsNullOrEmpty(m.resid)).GroupBy(m => m.resid).ToDictionary(m => m.Key, n => n.ToList()); + //var userGup2 = userInfo2.Where(m => !string.IsNullOrEmpty(m.resid)).GroupBy(m => m.resid).ToDictionary(m => m.Key, n => n.ToList()); + List mainExternalUsers = new List(); + List secExternalUsers = new List(); + //获取当前解绑后的 rrwu数据 + var wwuser1 = await BindWeworkUser(userInfo1, mainExternalUsers); + var wwuser2 = await BindWeworkUser(userInfo2, secExternalUsers); + //拼接两个数据的交集 + foreach (var u1 in wwuser1) + { + foreach (var u2 in wwuser2) + { + ResResidWeworkUser r = new ResResidWeworkUser(); + r.resid = u1.resid; + r.unionid = u1.unionid; + r.deptid = u1.deptid; + r.first_subscribetime = u1.first_subscribetime; + r.last_subscribetime = u1.last_subscribetime; + r.status = u1.status; + //删除集合1与集合2的 交集 + r.appid = u2.appid; + r.appuserid = u2.appuserid; + r.isdelete = 1; + r.utime = DateTime.Now; + res.Add(r); + } + } + //cid2 与1的交集数据 + foreach (var u1 in wwuser2) + { + foreach (var u2 in wwuser1) + { + ResResidWeworkUser r = new ResResidWeworkUser(); + r.resid = u1.resid; + r.unionid = u1.unionid; + r.deptid = u1.deptid; + r.first_subscribetime = u1.first_subscribetime; + r.last_subscribetime = u1.last_subscribetime; + r.status = u1.status; + //删除集合1与集合2的 交集 + r.appid = u2.appid; + r.appuserid = u2.appuserid; + r.isdelete = 1; + r.utime = DateTime.Now; + res.Add(r); + } + } + return res; + } + + /// + /// 匹配当前用户最终好友状态 + /// + /// + /// + private async Task> BindWeworkUser(IList userInfo, List weworkExternalUsers) + { + List resResidWeworkUsers = new List(); + if (userInfo.Count == 0) + { + return resResidWeworkUsers; + } + var extuserfilter = userInfo.Select(n => $"'{n.appuserid}'").Distinct().ToList(); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + MySqlParameter[] param = new MySqlParameter[] { }; + var extUserList = await dncmsRepository.ExecuteSqlToListAsync($"select appid,userid,appid_ext,externaluserid,deptid,unionid,subscribe,subscribetime,regdate from WeworkExternalUser where externaluserid in ({string.Join(",", extuserfilter)})", param); + foreach (var item in extUserList) + { + var userinfoItem = userInfo.FirstOrDefault(n => n.appid == item.Appid_ext && n.appuserid == item.Externaluserid && n.appid.EndsWith("_1")); + if (userinfoItem != null) + { + weworkExternalUsers.Add(item); + } + } + if (weworkExternalUsers.Any()) + { + //好友关系分组 + var weworkExternalUsersGup = weworkExternalUsers.GroupBy(m => m.deptid + ";" + m.Appid + ";" + m.Externaluserid) + .ToDictionary(m => m.Key, n => n.ToList()); + //resid分组 + var residGup = userInfo.Where(m => !string.IsNullOrEmpty(m.resid)) + .GroupBy(m => m.resid).ToDictionary(m => m.Key, n => n.Min(i => i.uid)); + //组合关系数据 + foreach (var resid in residGup) + { + foreach (var wwe in weworkExternalUsersGup) + { + var deptid = wwe.Key.Split(';')[0]; + var appid = wwe.Key.Split(';')[1]; + var extuserid = wwe.Key.Split(';')[2]; + var extList = wwe.Value; + var extSubList = extList.Where(m => m.subscribe == 1); + ResResidWeworkUser res = new ResResidWeworkUser(); + res.uid = int.Parse(resid.Value); + res.deptid = int.Parse(deptid); + res.resid = resid.Key; + res.appid = appid; + res.appuserid = extuserid; + res.unionid = extList.Where(m => !string.IsNullOrEmpty(m.unionid)).FirstOrDefault()?.unionid;//unionid有则取 + if (extSubList.Any()) + { + res.first_subscribetime = extSubList.Min(m => m.subscribetime ?? m.regdate); + res.last_subscribetime = extSubList.Max(m => m.subscribetime ?? m.regdate); + res.status = 1;//最终关注状态 + } + else + { + res.first_subscribetime = null; + res.last_subscribetime = null; + res.status = 0;//最终关注状态 + } + res.ctime = DateTime.Now; + res.isdelete = 0; + res.utime = DateTime.Now; + resResidWeworkUsers.Add(res); + } + } + } + return resResidWeworkUsers; + } + + /// + /// 入库ResResidWeworkUser + /// + /// + /// + private async Task ChangeWeworkUser(ResResidWeworkUser model, bool add = true) + { + if (model == null) return; + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var tag = dncmsbaseRepository.GetRepository().Query() + .FirstOrDefault(m => m.resid == model.resid && m.appuserid == model.appuserid && m.appid == model.appid && m.deptid == model.deptid); + using var transaction = await dncmsbaseRepository.BeginTransactionAsync(); + try + { + if (tag != null) + { + tag.status = model.status; + tag.first_subscribetime = model.first_subscribetime; + tag.last_subscribetime = model.last_subscribetime; + tag.isdelete = model.isdelete; + //更新已有好友关系 + await dncmsbaseRepository.GetRepository().UpdateAsync(tag); + //PushKafKa(MappingTolog(tag)); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(tag)); + } + else if (add) + { + //插入新的好友关系 + var outModel = await dncmsbaseRepository.GetRepository().InsertAsync(model); + //PushKafKa(MappingTolog(outModel)); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(outModel)); + } + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + _logger.LogError($"入库ResResidWeworkUser报错:{ex.Message}", ex); + } + } + + /// + /// 换事业部 + /// + /// + /// + private async Task ChangeDeptWeworkUser(ResResidWeworkUser model, int olddeptid) + { + if (model == null) return; + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var tag = dncmsbaseRepository.GetRepository().Query() + .FirstOrDefault(m => m.resid == model.resid && m.appuserid == model.appuserid && m.appid == model.appid && m.deptid == olddeptid); + using var transaction = await dncmsbaseRepository.BeginTransactionAsync(); + try + { + if (tag != null) + { + tag.status = model.status; + tag.first_subscribetime = model.first_subscribetime; + tag.last_subscribetime = model.last_subscribetime; + tag.isdelete = model.isdelete; + tag.deptid = model.deptid;//更新事业部 + //更新已有好友关系 + await dncmsbaseRepository.GetRepository().UpdateAsync(tag); + //插入新数据 + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(tag)); + //删除旧数据 + var delTag = MappingTolog(tag); + delTag.isdelete = 1; + delTag.deptid = olddeptid; + await dncmsbaseRepository.GetRepository().InsertAsync(delTag); + } + else + { + //插入新的好友关系 + var outModel = await dncmsbaseRepository.GetRepository().InsertAsync(model); + //PushKafKa(MappingTolog(outModel)); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(outModel)); + } + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + _logger.LogError($"换事业部报错:{ex.Message}", ex); + } + } + + /// + /// 事业部替换 + /// + /// + private async Task ChangeWheorkUserDeptid(ResResidWeworkUser oldrrw) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var tag = dncmsbaseRepository.GetRepository().Query().FirstOrDefault(m => m.appuserid == oldrrw.appuserid && m.appid == oldrrw.appid && m.deptid == oldrrw.deptid); + if (tag != null && tag.isdelete == 0) + { + //await dncmsbaseRepository.GetRepository().UpdateAsync(tag); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(tag));//旧事业部数据删除 + } + } + + /// + /// 隐射对象 + /// + /// + /// + private ResResidWeworkUserLog MappingTolog(ResResidWeworkUser model) + { + if (model == null) return null; + ResResidWeworkUserLog res = new ResResidWeworkUserLog(); + res.mainid = model.id; + res.uid = model.uid; + res.appid = model.appid; + res.appuserid = model.appuserid; + res.resid = model.resid; + res.deptid = model.deptid; + res.unionid = model.unionid; + res.status = model.status; + res.isdelete = model.isdelete; + res.first_subscribetime = model.first_subscribetime; + res.last_subscribetime = model.last_subscribetime; + res.ctime = model.ctime; + res.utime = model.utime; + return res; + } + + /// + /// 推送队列 + /// + /// + /// + private async Task PushKafKa(WeworkWorkerDto log) + { + //IList res = new List(); + //var url = $"{_systemConfig.Value.zxdCoreApi}/Api/WeWork/SyncBinding"; + //var req = HttpHelper.PostAjaxData(url, JsonHelper.ToJson(log), Encoding.UTF8); + + //var resModel = JsonHelper.FromJson>(req); + //if (resModel.code != 0) + //{ + // Log.Write(Serilog.Events.LogEventLevel.Error, req); + //} + var consumers = KafkaClient.GetConsumers(); + await KafkaClient.SendMessage(consumers.FirstOrDefault(n => n.Topic == "crm-topic"), log); + } + + /// + /// 记录日志 + /// + /// + private async Task EventLog(WeworkWorkerDto t) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + ResResidWeworkEventLog log = new ResResidWeworkEventLog(); + log.appid = t.appid; + log.userid = t.userid; + log.appuserid = t.appuserid; + log.type = t.type; + log.deptid = t.deptid; + log.olddeptid = t.olddeptid; + log.eventJson = JsonHelper.ToJson(t); + log.cid = t.cid; + log.ctime = DateTime.Now; + await dncmsbaseRepository.GetRepository().InsertAsync(log); + } + + /// + /// 外部联系人 赋值资源进线时间 + /// + /// + /// + /// + private async Task SetSourcePassInfo(List extUser, IList userInfoList, WeworkWorkerDto t) + { + try + { + if (extUser.Count == 0 || userInfoList.Count == 0) + { + return; + } + var uidFilter = userInfoList.Select(n => Convert.ToInt32(n.uid)).Distinct().ToList(); + var regdate = await GetRegDate(userInfoList); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var dbList = await dncmsbaseRepository.GetRepository().Query().Where(n => uidFilter.Contains(n.uid)).ToListAsync(); + var groupdeptid = extUser.GroupBy(n => n.deptid).ToList(); + List insertList = new List(); + List updateList = new List(); + List delList = new List(); + var customerid = 0; + Int32.TryParse(userInfoList.FirstOrDefault().customerid, out customerid); + using var transaction = await dncmsbaseRepository.BeginTransactionAsync(); + foreach (var deptid in groupdeptid) + { + var deptUser = extUser.Where(n => n.deptid == deptid.Key).ToList(); + var subItem = deptUser.OrderBy(n => n.subscribetime).OrderBy(n => n.regdate).FirstOrDefault(); + var dbItem = dbList.FirstOrDefault(n => n.deptid == deptid.Key && n.customerid == customerid); + var useritem = userInfoList.FirstOrDefault(n => n.appid == subItem.Appid_ext && n.appuserid == subItem.Externaluserid); + if (useritem == null) + { + continue; + } + var uid = 0; + Int32.TryParse(useritem.uid, out uid); + + if (dbItem == null) + { + ResourceProtectInfo model = new ResourceProtectInfo + { + uid = uid, + appid = useritem.appid, + appuserid = useritem.appuserid, + resid = useritem.resid, + unionid = useritem.unionid, + customerid = customerid, + deptid = subItem.deptid, + firstfollowtime = deptUser.Min(m => m.subscribetime ?? m.regdate), + followtime = deptUser.Where(n => n.subscribe == 1).Min(m => m.subscribetime ?? m.regdate), + ctime = DateTime.Now, + regtime = regdate, + eventtype = t.type, + }; + if (!model.followtime.HasValue) + { + model.isdelete = 1; + } + insertList.Add(model); + } + else + { + dbItem.deptid = subItem.deptid; + dbItem.uid = uid; + dbItem.resid = useritem.resid; + dbItem.unionid = useritem.unionid; + dbItem.customerid = customerid; + dbItem.deptid = subItem.deptid; + dbItem.firstfollowtime = deptUser.Min(m => m.subscribetime ?? m.regdate); + dbItem.followtime = deptUser.Where(n => n.subscribe == 1).Min(m => m.subscribetime ?? m.regdate); + dbItem.utime = DateTime.Now; + dbItem.regtime = regdate; + dbItem.eventtype = t.type; + if (!dbItem.followtime.HasValue) + { + dbItem.isdelete = 1; + } + updateList.Add(dbItem); + } + } + bool update = false; + if (updateList.Count > 0) + { + update = true; + await SetDeptInfo(updateList); + await dncmsbaseRepository.GetRepository().BatchUpdateAsync(updateList); + } + if (insertList.Count > 0) + { + update = true; + await SetDeptInfo(insertList); + await dncmsbaseRepository.GetRepository().BatchInsertAsync(insertList); + } + + if (update) + { + transaction.Commit(); + } + } + catch (Exception ex) + { + Log.Error($"计算资源进线时间错误{ex.Message}"); + } + } + + private async Task GetRegDate(IList userInfoList) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var zxdRepository = scope.ServiceProvider.GetRequiredService>(); + var userList = userInfoList.Select(n => n.appuserid).Distinct().ToList(); + var softuser = await zxdRepository.GetRepository().Query().Where(n => userList.Contains(n.USERNAME)).ToListAsync(); + return softuser.Min(n => n.REGDATE); + } + + private async Task SetDeptInfo(List model) + { + var key = "deptment_list_new"; + var deptInfo = new List(); + if (await _redisManager.ExistsAsync(key)) + { + deptInfo = await _redisManager.GetListAsync(key); + } + if (deptInfo != null && deptInfo.Count > 0) + { + foreach (var item in model) + { + var dept = deptInfo.FirstOrDefault(n => n.Id == item.deptid); + item.deptname = dept?.Title; + item.groupid = dept?.GroupId; + } + } + } + } +} \ No newline at end of file diff --git a/code/WeworkUserWorker/Workers/WeworkWorker.cs b/code/WeworkUserWorker/Workers/WeworkWorker.cs new file mode 100644 index 0000000..631e544 --- /dev/null +++ b/code/WeworkUserWorker/Workers/WeworkWorker.cs @@ -0,0 +1,723 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WeworkUserWorker.Config; +using Zxd.Entity.Dncms; +using Zxd.Entity.UserCenter; +using Zxd.EntityFramework; +using Microsoft.Extensions.Options; +using DG.Kafka; +using MySqlConnector; +using System.Diagnostics; +using Zxd.Core.Shared.Dto; +using DG.Redis; +using Zxd.Entity.Zxd; + +namespace WeworkUserWorker.Workers +{ + internal class WeworkWorker : KafkaWorkerBase + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + private readonly IOptionsSnapshot _systemConfig; + private readonly IHttpClient _httpClient; + private readonly IRedisManager _redisManager; + + public WeworkWorker( + IServiceProvider serviceProvider, + IOptionsSnapshot systemConfig, + ILogger logger, + IHttpClient httpClient, IRedisManager redisManager + ) : base(logger) + { + _serviceProvider = serviceProvider; + _httpClient = httpClient; + _systemConfig = systemConfig; + _logger = logger; + _redisManager = redisManager; + } + + /// + /// 处理好友最终关系 + /// 数据逻辑 + /// 1、通过appid和appuserid去usercenter.userinfo中找出customerid,并通过customerid查出userinfo中所有用户数据, + /// 2、假如数据中没有resid、忽略不处理。 + /// 3、假如有resid去dncms.weworkexternaluser中查找数据,subscribe = 1筛选数据,用subscribetime去 res_resid_weworkuser + /// 表中appid、appuserid数据取firsttime和最早的subscribetime 对比,有变动就修正,假如res_resid_weworkuser 中的在刚刚查找出来没有关注数据了, + /// 将status改成0 。假如res_resid_weworkuser 没有数据,插入一条数据。 + /// + /// + /// + protected override async Task DoWorkAsync(WeworkWorkerDto t) + { + IList resResids = new List(); + IList users = new List(); + List rrWeworkUser = new List(); + List mainExternalUsers = new List(); + List secExternalUsers = new List(); + try + { + await EventLog(t); + switch (t.type?.ToLower()) + { + case "subscribe"://关注 + case "unsubscribe"://取关 + _logger.LogWarning("开始处理取关!"); + users = await GetUser(t.appid, t.appuserid); //请求此用户的所有用户信息 + rrWeworkUser = await BindWeworkUser(users, mainExternalUsers);//查询当前客户好友关系 + foreach (var item in rrWeworkUser) + { + await ChangeWeworkUser(item);//入库 + } + //await SetSourcePassInfo(mainExternalUsers, users, t); + _logger.LogWarning("结束处理取关!"); + break; + + case "merge"://合并 + _logger.LogWarning("开始处理合并!"); + if (int.TryParse(t.cid, out int incid)) + { + users = await GetUser(incid);//请求此用户的所有用户信息 + rrWeworkUser = await BindWeworkUser(users, mainExternalUsers);//查询当前客户好友关系 + foreach (var item in rrWeworkUser) + { + await ChangeWeworkUser(item);//入库 + } + } + //await SetSourcePassInfo(mainExternalUsers, users, t); + _logger.LogWarning("结束处理合并!"); + break; + + case "unmerge"://解绑 + _logger.LogWarning("开始处理解绑!"); + var cidarry = t.cid?.Trim().Split(','); + if (cidarry != null && cidarry.Count() == 2) + { + var scid = cidarry[0]; + var ecid = cidarry[1]; + var susers = await GetUser(int.Parse(scid));//分别查询出两个cid对应的客户信息 + var eusers = await GetUser(int.Parse(ecid));// + var swu = await BindWeworkUser(susers, mainExternalUsers);//查询当前客户好友关系 + //await SetSourcePassInfo(mainExternalUsers, susers, t); + var ewu = await BindWeworkUser(eusers, secExternalUsers);//查询当前客户好友关系 + //await SetSourcePassInfo(secExternalUsers, eusers, t); + foreach (var item in swu) + { + await ChangeWeworkUser(item);//入库 + } + foreach (var item in ewu) + { + await ChangeWeworkUser(item);//入库 + } + var unlist = await UnBindWeworkUser(susers, eusers);//拼接两个cid的 重叠部分 + foreach (var item in unlist) + { + //事业部不发生变化 + await ChangeWeworkUser(item, false);//解绑匹配的新数据不入库,旧数据标记删除 + } + } + _logger.LogWarning("结束处理解绑!"); + break; + + case "eidbind"://跨部门换绑工号 300秒超时 + if (t.olddeptid.HasValue && t.deptid.HasValue && t.olddeptid != t.deptid) + { + var kfuser = await GetKFUser(t.appid, t.userid); //请求此用户的所有用户信息 + if (kfuser.Count() > 300) + {//给队列逐条处理 + IList appidStr = new List(); + IList euseridStr = new List(); + foreach (var item in kfuser) + { + appidStr.Add(item.Appid_ext); + euseridStr.Add(item.Externaluserid); + if (appidStr.Count() > 9) + { + WeworkWorkerDto dto = new WeworkWorkerDto(); + dto.type = "inner_eidbind_item"; + dto.appuserid = String.Join(",", euseridStr); + dto.appid = String.Join(",", appidStr); + dto.deptid = t.deptid; + dto.olddeptid = t.olddeptid; + PushKafKa(dto); + appidStr = new List(); + euseridStr = new List(); + } + } + //循环结束验证是否有未完成 + if (euseridStr.Any()) + { + WeworkWorkerDto lastdto = new WeworkWorkerDto(); + lastdto.type = "inner_eidbind_item"; + lastdto.appuserid = String.Join(",", euseridStr); + lastdto.appid = String.Join(",", appidStr); + lastdto.deptid = t.deptid; + lastdto.olddeptid = t.olddeptid; + PushKafKa(lastdto); + } + } + else + {//直接批量处理 + foreach (var item in kfuser)//逐个好友处理数据 + { + var iusers = await GetUser(item.Appid, item.Externaluserid); + List kfExternal = new List(); + rrWeworkUser = await BindWeworkUser(iusers, kfExternal);//重新计算当前客户好友关系 + //await SetSourcePassInfo(kfExternal, iusers, t); + foreach (var rritem in rrWeworkUser) + { + await ChangeWeworkUser(rritem);//更新和插入 事业部变更后的好友关系 + if (rritem.deptid == t.deptid) + { + rritem.deptid = t.olddeptid.Value; + await ChangeWheorkUserDeptid(rritem);//查找 事业部变更前的好友关系,有则标记删除 + } + } + } + } + } + break; + + case "inner_eidbind_item"://逐个处理换绑资源 + if (!string.IsNullOrEmpty(t.appid) && !string.IsNullOrEmpty(t.appuserid) && t.olddeptid.HasValue && t.deptid.HasValue) + { + var appidList = t.appid.Split(',').ToList(); + var appuseridList = t.appuserid.Split(',').ToList(); + if (appidList.Count() == appuseridList.Count()) + {//一次性处理9个 + int index = 0; + foreach (var appid in appidList) + { + var appuserid = appuseridList[index]; + users = await GetUser(appid, appuserid); + List kfExternal = new List(); + rrWeworkUser = await BindWeworkUser(users, kfExternal);//重新计算当前客户好友关系 + //await SetSourcePassInfo(kfExternal, users, t); + foreach (var rritem in rrWeworkUser) + { + await ChangeDeptWeworkUser(rritem, t.olddeptid.Value);//更新和插入 事业部变更后的好友关系 + } + index++; + } + } + } + break; + + case "register": + users = await GetUser(t.appid, t.appuserid); + rrWeworkUser = await BindWeworkUser(users, mainExternalUsers);//重新计算当前客户好友关系 + //await SetSourcePassInfo(mainExternalUsers, users, t); + break; + } + } + catch (Exception ex) + { + _logger.LogWarning(ex.Message, ex); + } + } + + /// + /// 查询客服名下所有客户 + /// + /// + /// + /// + private async Task> GetKFUser(string appid, string userid) + { + MySqlParameter[] param = new MySqlParameter[] { + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=appid,ParameterName="appid"}, + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=userid,ParameterName="userid"} + }; + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + var extUser = await dncmsRepository.ExecuteSqlToListAsync($"select appid,userid,appid_ext,externaluserid,deptid,unionid,subscribe,subscribetime from WeworkExternalUser where appid=@appid and userid=@userid", param); + return extUser; + } + + /// + /// 获取客户当前 resid数据 + /// + /// + /// + /// + private async Task> GetUser(string appid, string appuserid) + { + IList res = new List(); + var url = $"{_systemConfig.Value.zxdCoreApi}/Api/UserInfo/list"; + var resModel = await _httpClient.GetAsync>>($"{url}?appid={appid}&appuserid={appuserid}"); + if (resModel.code == 0) + { + res = resModel.data; + } + return res; + } + + /// + /// 获取客户当前 resid数据 + /// + /// + /// + /// + private async Task> GetUser(int? customerid) + { + IList res = new List(); + if (customerid.HasValue) + { + var url = $"{_systemConfig.Value.zxdCoreApi}/Api/UserInfo/list"; + //var req = HttpHelper.GetData(url, $"?cid={customerid}", Encoding.UTF8); + //var resModel = JsonHelper.FromJson>>(req); + + var resModel = await _httpClient.GetAsync>>($"{url}?cid={customerid}"); + if (resModel.code == 0) + { + res = resModel.data; + } + } + return res; + } + + /// + /// 匹配两个好友解绑时的所有情况 + /// + /// + /// + /// + private async Task> UnBindWeworkUser(IList userInfo1, IList userInfo2) + { + IList res = new List(); + //var userGup1 = userInfo1.Where(m => !string.IsNullOrEmpty(m.resid)).GroupBy(m => m.resid).ToDictionary(m => m.Key, n => n.ToList()); + //var userGup2 = userInfo2.Where(m => !string.IsNullOrEmpty(m.resid)).GroupBy(m => m.resid).ToDictionary(m => m.Key, n => n.ToList()); + List mainExternalUsers = new List(); + List secExternalUsers = new List(); + //获取当前解绑后的 rrwu数据 + var wwuser1 = await BindWeworkUser(userInfo1, mainExternalUsers); + var wwuser2 = await BindWeworkUser(userInfo2, secExternalUsers); + //拼接两个数据的交集 + foreach (var u1 in wwuser1) + { + foreach (var u2 in wwuser2) + { + ResResidWeworkUser r = new ResResidWeworkUser(); + r.resid = u1.resid; + r.unionid = u1.unionid; + r.deptid = u1.deptid; + r.first_subscribetime = u1.first_subscribetime; + r.last_subscribetime = u1.last_subscribetime; + r.status = u1.status; + //删除集合1与集合2的 交集 + r.appid = u2.appid; + r.appuserid = u2.appuserid; + r.isdelete = 1; + r.utime = DateTime.Now; + res.Add(r); + } + } + //cid2 与1的交集数据 + foreach (var u1 in wwuser2) + { + foreach (var u2 in wwuser1) + { + ResResidWeworkUser r = new ResResidWeworkUser(); + r.resid = u1.resid; + r.unionid = u1.unionid; + r.deptid = u1.deptid; + r.first_subscribetime = u1.first_subscribetime; + r.last_subscribetime = u1.last_subscribetime; + r.status = u1.status; + //删除集合1与集合2的 交集 + r.appid = u2.appid; + r.appuserid = u2.appuserid; + r.isdelete = 1; + r.utime = DateTime.Now; + res.Add(r); + } + } + return res; + } + + /// + /// 匹配当前用户最终好友状态 + /// + /// + /// + private async Task> BindWeworkUser(IList userInfo, List weworkExternalUsers) + { + List resResidWeworkUsers = new List(); + if (userInfo.Count == 0) + { + return resResidWeworkUsers; + } + var extuserfilter = userInfo.Select(n => $"'{n.appuserid}'").Distinct().ToList(); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsRepository = scope.ServiceProvider.GetRequiredService>(); + MySqlParameter[] param = new MySqlParameter[] { }; + var extUserList = await dncmsRepository.ExecuteSqlToListAsync($"select appid,userid,appid_ext,externaluserid,deptid,unionid,subscribe,subscribetime,regdate from WeworkExternalUser where externaluserid in ({string.Join(",", extuserfilter)})", param); + foreach (var item in extUserList) + { + var userinfoItem = userInfo.FirstOrDefault(n => n.appid == item.Appid_ext && n.appuserid == item.Externaluserid && n.appid.EndsWith("_1")); + if (userinfoItem != null) + { + weworkExternalUsers.Add(item); + } + } + if (weworkExternalUsers.Any()) + { + //好友关系分组 + var weworkExternalUsersGup = weworkExternalUsers.GroupBy(m => m.deptid + ";" + m.Appid + ";" + m.Externaluserid) + .ToDictionary(m => m.Key, n => n.ToList()); + //resid分组 + var residGup = userInfo.Where(m => !string.IsNullOrEmpty(m.resid)) + .GroupBy(m => m.resid).ToDictionary(m => m.Key, n => n.Min(i => i.uid)); + //组合关系数据 + foreach (var resid in residGup) + { + foreach (var wwe in weworkExternalUsersGup) + { + var deptid = wwe.Key.Split(';')[0]; + var appid = wwe.Key.Split(';')[1]; + var extuserid = wwe.Key.Split(';')[2]; + var extList = wwe.Value; + var extSubList = extList.Where(m => m.subscribe == 1); + ResResidWeworkUser res = new ResResidWeworkUser(); + res.uid = int.Parse(resid.Value); + res.deptid = int.Parse(deptid); + res.resid = resid.Key; + res.appid = appid; + res.appuserid = extuserid; + res.unionid = extList.Where(m => !string.IsNullOrEmpty(m.unionid)).FirstOrDefault()?.unionid;//unionid有则取 + if (extSubList.Any()) + { + res.first_subscribetime = extSubList.Min(m => m.subscribetime ?? m.regdate); + res.last_subscribetime = extSubList.Max(m => m.subscribetime ?? m.regdate); + res.status = 1;//最终关注状态 + } + else + { + res.first_subscribetime = null; + res.last_subscribetime = null; + res.status = 0;//最终关注状态 + } + res.ctime = DateTime.Now; + res.isdelete = 0; + res.utime = DateTime.Now; + resResidWeworkUsers.Add(res); + } + } + } + return resResidWeworkUsers; + } + + /// + /// 入库ResResidWeworkUser + /// + /// + /// + private async Task ChangeWeworkUser(ResResidWeworkUser model, bool add = true) + { + if (model == null) return; + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var tag = dncmsbaseRepository.GetRepository().Query() + .FirstOrDefault(m => m.resid == model.resid && m.appuserid == model.appuserid && m.appid == model.appid && m.deptid == model.deptid); + using var transaction = await dncmsbaseRepository.BeginTransactionAsync(); + try + { + if (tag != null) + { + tag.status = model.status; + tag.first_subscribetime = model.first_subscribetime; + tag.last_subscribetime = model.last_subscribetime; + tag.isdelete = model.isdelete; + //更新已有好友关系 + await dncmsbaseRepository.GetRepository().UpdateAsync(tag); + //PushKafKa(MappingTolog(tag)); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(tag)); + } + else if (add) + { + //插入新的好友关系 + var outModel = await dncmsbaseRepository.GetRepository().InsertAsync(model); + //PushKafKa(MappingTolog(outModel)); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(outModel)); + } + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + _logger.LogError($"入库ResResidWeworkUser报错:{ex.Message}", ex); + } + } + + /// + /// 换事业部 + /// + /// + /// + private async Task ChangeDeptWeworkUser(ResResidWeworkUser model, int olddeptid) + { + if (model == null) return; + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var tag = dncmsbaseRepository.GetRepository().Query() + .FirstOrDefault(m => m.resid == model.resid && m.appuserid == model.appuserid && m.appid == model.appid && m.deptid == olddeptid); + using var transaction = await dncmsbaseRepository.BeginTransactionAsync(); + try + { + if (tag != null) + { + tag.status = model.status; + tag.first_subscribetime = model.first_subscribetime; + tag.last_subscribetime = model.last_subscribetime; + tag.isdelete = model.isdelete; + tag.deptid = model.deptid;//更新事业部 + //更新已有好友关系 + await dncmsbaseRepository.GetRepository().UpdateAsync(tag); + //插入新数据 + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(tag)); + //删除旧数据 + var delTag = MappingTolog(tag); + delTag.isdelete = 1; + delTag.deptid = olddeptid; + await dncmsbaseRepository.GetRepository().InsertAsync(delTag); + } + else + { + //插入新的好友关系 + var outModel = await dncmsbaseRepository.GetRepository().InsertAsync(model); + //PushKafKa(MappingTolog(outModel)); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(outModel)); + } + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + _logger.LogError($"换事业部报错:{ex.Message}", ex); + } + } + + /// + /// 事业部替换 + /// + /// + private async Task ChangeWheorkUserDeptid(ResResidWeworkUser oldrrw) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var tag = dncmsbaseRepository.GetRepository().Query().FirstOrDefault(m => m.appuserid == oldrrw.appuserid && m.appid == oldrrw.appid && m.deptid == oldrrw.deptid); + if (tag != null && tag.isdelete == 0) + { + //await dncmsbaseRepository.GetRepository().UpdateAsync(tag); + await dncmsbaseRepository.GetRepository().InsertAsync(MappingTolog(tag));//旧事业部数据删除 + } + } + + /// + /// 隐射对象 + /// + /// + /// + private ResResidWeworkUserLog MappingTolog(ResResidWeworkUser model) + { + if (model == null) return null; + ResResidWeworkUserLog res = new ResResidWeworkUserLog(); + res.mainid = model.id; + res.uid = model.uid; + res.appid = model.appid; + res.appuserid = model.appuserid; + res.resid = model.resid; + res.deptid = model.deptid; + res.unionid = model.unionid; + res.status = model.status; + res.isdelete = model.isdelete; + res.first_subscribetime = model.first_subscribetime; + res.last_subscribetime = model.last_subscribetime; + res.ctime = model.ctime; + res.utime = model.utime; + return res; + } + + /// + /// 推送队列 + /// + /// + /// + private async Task PushKafKa(WeworkWorkerDto log) + { + //IList res = new List(); + //var url = $"{_systemConfig.Value.zxdCoreApi}/Api/WeWork/SyncBinding"; + //var req = HttpHelper.PostAjaxData(url, JsonHelper.ToJson(log), Encoding.UTF8); + + //var resModel = JsonHelper.FromJson>(req); + //if (resModel.code != 0) + //{ + // Log.Write(Serilog.Events.LogEventLevel.Error, req); + //} + var consumers = KafkaClient.GetConsumers(); + await KafkaClient.SendMessage(consumers.FirstOrDefault(n => n.Topic == "crm-topic"), log); + } + + /// + /// 记录日志 + /// + /// + private async Task EventLog(WeworkWorkerDto t) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + ResResidWeworkEventLog log = new ResResidWeworkEventLog(); + log.appid = t.appid; + log.userid = t.userid; + log.appuserid = t.appuserid; + log.type = t.type; + log.deptid = t.deptid; + log.olddeptid = t.olddeptid; + log.eventJson = JsonHelper.ToJson(t); + log.cid = t.cid; + log.ctime = DateTime.Now; + await dncmsbaseRepository.GetRepository().InsertAsync(log); + } + + /// + /// 外部联系人 赋值资源进线时间 + /// + /// + /// + /// + private async Task SetSourcePassInfo(List extUser, IList userInfoList, WeworkWorkerDto t) + { + try + { + if (extUser.Count == 0 || userInfoList.Count == 0) + { + return; + } + var uidFilter = userInfoList.Select(n => Convert.ToInt32(n.uid)).Distinct().ToList(); + var regdate = await GetRegDate(userInfoList); + using var scope = _serviceProvider.CreateAsyncScope(); + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var dbList = await dncmsbaseRepository.GetRepository().Query().Where(n => uidFilter.Contains(n.uid)).ToListAsync(); + var groupdeptid = extUser.GroupBy(n => n.deptid).ToList(); + List insertList = new List(); + List updateList = new List(); + List delList = new List(); + var customerid = 0; + Int32.TryParse(userInfoList.FirstOrDefault().customerid, out customerid); + using var transaction = await dncmsbaseRepository.BeginTransactionAsync(); + foreach (var deptid in groupdeptid) + { + var deptUser = extUser.Where(n => n.deptid == deptid.Key).ToList(); + var subItem = deptUser.OrderBy(n => n.subscribetime).OrderBy(n => n.regdate).FirstOrDefault(); + var dbItem = dbList.FirstOrDefault(n => n.deptid == deptid.Key && n.customerid == customerid); + var useritem = userInfoList.FirstOrDefault(n => n.appid == subItem.Appid_ext && n.appuserid == subItem.Externaluserid); + if (useritem == null) + { + continue; + } + var uid = 0; + Int32.TryParse(useritem.uid, out uid); + + if (dbItem == null) + { + ResourceProtectInfo model = new ResourceProtectInfo + { + uid = uid, + appid = useritem.appid, + appuserid = useritem.appuserid, + resid = useritem.resid, + unionid = useritem.unionid, + customerid = customerid, + deptid = subItem.deptid, + firstfollowtime = deptUser.Min(m => m.subscribetime ?? m.regdate), + followtime = deptUser.Where(n => n.subscribe == 1).Min(m => m.subscribetime ?? m.regdate), + ctime = DateTime.Now, + regtime = regdate, + eventtype = t.type, + }; + if (!model.followtime.HasValue) + { + model.isdelete = 1; + } + insertList.Add(model); + } + else + { + dbItem.deptid = subItem.deptid; + dbItem.uid = uid; + dbItem.resid = useritem.resid; + dbItem.unionid = useritem.unionid; + dbItem.customerid = customerid; + dbItem.deptid = subItem.deptid; + dbItem.firstfollowtime = deptUser.Min(m => m.subscribetime ?? m.regdate); + dbItem.followtime = deptUser.Where(n => n.subscribe == 1).Min(m => m.subscribetime ?? m.regdate); + dbItem.utime = DateTime.Now; + dbItem.regtime = regdate; + dbItem.eventtype = t.type; + if (!dbItem.followtime.HasValue) + { + dbItem.isdelete = 1; + } + updateList.Add(dbItem); + } + } + bool update = false; + if (updateList.Count > 0) + { + update = true; + await SetDeptInfo(updateList); + await dncmsbaseRepository.GetRepository().BatchUpdateAsync(updateList); + } + if (insertList.Count > 0) + { + update = true; + await SetDeptInfo(insertList); + await dncmsbaseRepository.GetRepository().BatchInsertAsync(insertList); + } + + if (update) + { + transaction.Commit(); + } + } + catch (Exception ex) + { + Log.Error($"计算资源进线时间错误{ex.Message}"); + } + } + + private async Task GetRegDate(IList userInfoList) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var zxdRepository = scope.ServiceProvider.GetRequiredService>(); + var userList = userInfoList.Select(n => n.appuserid).Distinct().ToList(); + var softuser = await zxdRepository.GetRepository().Query().Where(n => userList.Contains(n.USERNAME)).ToListAsync(); + return softuser.Min(n => n.REGDATE); + } + + private async Task SetDeptInfo(List model) + { + var key = "deptment_list_new"; + var deptInfo = new List(); + if (await _redisManager.ExistsAsync(key)) + { + deptInfo = await _redisManager.GetListAsync(key); + } + if (deptInfo != null && deptInfo.Count > 0) + { + foreach (var item in model) + { + var dept = deptInfo.FirstOrDefault(n => n.Id == item.deptid); + item.deptname = dept?.Title; + item.groupid = dept?.GroupId; + } + } + } + } +} \ No newline at end of file diff --git a/code/WeworkUserWorker/appsettings.Disaster.json b/code/WeworkUserWorker/appsettings.Disaster.json new file mode 100644 index 0000000..6f5b9cd --- /dev/null +++ b/code/WeworkUserWorker/appsettings.Disaster.json @@ -0,0 +1,30 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=10.22.15.61;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=10.22.15.68;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=10.22.15.68;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Consumers": [ + { + "Host": "172.18.11.77:9092,172.18.11.76:9092", + "GroupId": "crm", + "Topic": "crm-topic" + } + ], + "TaskConfig": { + "TaskName": "Zxd.WeworkUserWorker", + "TaskRemarks": "Zxd.WeworkUserWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "w8ktfSOJalWw6jZWjTs8qSOoLteO7WTSRdgIvja8" + }, + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089", + "nodeWebApi": "http://10.22.15.5:8080" + } +} \ No newline at end of file diff --git a/code/WeworkUserWorker/appsettings.Production.json b/code/WeworkUserWorker/appsettings.Production.json new file mode 100644 index 0000000..4efdd47 --- /dev/null +++ b/code/WeworkUserWorker/appsettings.Production.json @@ -0,0 +1,46 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "companyBaseConf": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Consumers": [ + { + "Host": "172.18.11.77:9092,172.18.11.76:9092", + "GroupId": "crm", + "Topic": "crm-topic" + } + ], + "TaskConfig": { + "TaskName": "Zxd.WeworkUserWorker", + "TaskRemarks": "Zxd.WeworkUserWorker", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "w8ktfSOJalWw6jZWjTs8qSOoLteO7WTSRdgIvja8" + }, + "SystemConfig": { + "zxdCoreApi": "http://120.77.165.155:8089", + "nodeWebApi": "https://r2.soft.dn8188.com" + }, + "Redis": [ + { + "Name": "ZXD", + "HostName": "redis-cngzdnddztrevahsz.redis.ivolces.com", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + }, + { + "Name": "UserCenter", + "HostName": "redis-cngzdnddztrevahsz.redis.ivolces.com", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } + ] +} \ No newline at end of file diff --git a/code/WeworkUserWorker/appsettings.json b/code/WeworkUserWorker/appsettings.json new file mode 100644 index 0000000..efd448d --- /dev/null +++ b/code/WeworkUserWorker/appsettings.json @@ -0,0 +1,52 @@ +{ + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "Consumers": [ + { + "Host": "192.168.11.101:9092,192.168.11.104:9092", + "GroupId": "crm", + "Topic": "crm-topic" + }, + { + "Host": "192.168.11.104:9092,192.168.11.104:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "TaskConfig": { + "TaskName": "DG.Worker.Sample", + "TaskRemarks": "DG.Worker.Sample", + "Enable": true, + "SecondsDelay": 5 + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "tmrp0GmwyTMe6UxJIw7LXAcIWYKEUgy2kprMiybd" + }, + "SystemConfig": { + "zxdCoreApi": "http://192.168.11.81:8089", + "nodeWebApi": "http://120.238.224.24:10034" + }, + "Redis": [ + { + "Name": "ZXD", + "HostName": "192.168.11.81", + "Port": "6379", + "Password": "Abc@123456", + "Defaultdatabase": "1" + }, + { + "Name": "UserCenter", + "HostName": "192.168.11.103", + "Port": "6379", + "Password": "123", + "Defaultdatabase": "0" + } + ] +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/ActivityDomain.cs b/code/Zxd.Core.Domain/ActivityDomain.cs new file mode 100644 index 0000000..4701c58 --- /dev/null +++ b/code/Zxd.Core.Domain/ActivityDomain.cs @@ -0,0 +1,31 @@ +using Zxd.Core.Domain.Dto.Activity; + +namespace Zxd.Core.Domain +{ + public class ActivityDomain : IActivityDomain + { + private readonly IBaseRepository _cmsRepository; + + public ActivityDomain( + IBaseRepository cmsRepository) + { + _cmsRepository = cmsRepository; + } + + /// + /// 获取活动名称 + /// + /// + /// + public async Task GetActivityNameAsync(GetActivityNameRequest request) + { + var tag = await _cmsRepository.GetRepository().Query().Where(w => w.remark == request.Code).FirstOrDefaultAsync(); + if (tag == null) + { + throw new ArgumentException($"活动编码无效:{request.Code}"); + } + + return tag.name; + } + } +} diff --git a/code/Zxd.Core.Domain/CacheDomain.cs b/code/Zxd.Core.Domain/CacheDomain.cs new file mode 100644 index 0000000..4ebb4e2 --- /dev/null +++ b/code/Zxd.Core.Domain/CacheDomain.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain +{ + internal class CacheDomain : ICacheDomain + { + private readonly IRedisManager _redisManager; + private readonly IBaseRepository _repository; + + public CacheDomain(IRedisManager redisManager, + IBaseRepository repository) + { + _redisManager = redisManager; + _repository = repository; + } + + private async Task> GetParameterList() + { + if (!await _redisManager.ExistsAsync(CacheKeys.ParameterList)) + { + var list = await _repository.GetRepository().QueryListAsync(); + await _redisManager.SetAsync(CacheKeys.ParameterList, list, new TimeSpan(0, 5, 0));//15分钟过期 + return list; + } + else + { + return await _redisManager.GetListAsync(CacheKeys.ParameterList); + } + } + + public async Task GetValueParameter(string key) + { + var list = await GetParameterList(); + return list.FirstOrDefault(x => x.PARAKEY == key)?.PARAVALUE ?? ""; + } + + public async Task GetEarlyWarningValue() + { + var data = await GetValueParameter("EarlyWarningValue"); + if (string.IsNullOrEmpty(data) || int.TryParse(data, out int value)) + { + return 5; + } + return value; + } + + public async Task> GetTokens() + { + var key = CacheKeys.TokenList; + if (await _redisManager.ExistsAsync(key)) + { + return await _redisManager.GetListAsync(key); + } + return new List(); + } + + public async Task AddToken(SsoUserTokenInfo token) + { + var key = CacheKeys.TokenList; + if (!await _redisManager.ExistsAsync(key)) + { + await _redisManager.SetAsync(key, new List() { token }); + } + else + { + var list = await _redisManager.GetListAsync(key); + list.Add(token); + await _redisManager.SetAsync(key, list, TimeSpan.FromDays(1)); + } + } + } +} diff --git a/code/Zxd.Core.Domain/Config/CacheKeys.cs b/code/Zxd.Core.Domain/Config/CacheKeys.cs new file mode 100644 index 0000000..697c6ab --- /dev/null +++ b/code/Zxd.Core.Domain/Config/CacheKeys.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Config +{ + internal class CacheKeys + { + public const string ProductModuleList = "product_module_list"; + + public const string ProductGroupList = "product_group_list"; + + public const string ProductTypeList = "product_type_list"; + + public const string ProductTeacherList = "product_teacher_list"; + + public const string ProductList = "product_list"; + + public const string StandardType = "standard_product_type"; + + public const string StandardWay = "standard_product_way"; + + public const string DeptmentList = "deptment_list_new"; + + public const string ModuleList = "module_list"; + + public const string ParameterList = "cache_parameter_list"; + + public const string TokenList = "cache_token_list"; + } +} diff --git a/code/Zxd.Core.Domain/Config/ClientKey.cs b/code/Zxd.Core.Domain/Config/ClientKey.cs new file mode 100644 index 0000000..a5137a4 --- /dev/null +++ b/code/Zxd.Core.Domain/Config/ClientKey.cs @@ -0,0 +1,13 @@ +namespace Zxd.Domain.Config +{ + public class ClientKey + { + public string Id { get; set; } + + public string Name { get; set; } + + public string AccessKey { get; set; } + public string Vi { get; set; } + public string NewAccessKey { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Config/Enum.cs b/code/Zxd.Core.Domain/Config/Enum.cs new file mode 100644 index 0000000..4f752d4 --- /dev/null +++ b/code/Zxd.Core.Domain/Config/Enum.cs @@ -0,0 +1,191 @@ + +using System.ComponentModel; + +namespace Zxd.Domain.Config +{ + #region 注册,认证码表 + + public enum EnumInterfaceErrcode + { + 调用成功 = 10000, + 调用成功且有数据 = 10001,//新增的code + 用户名已存在 = 10002, + 参数错误 = 10003, + 手机号码错误 = 10004, + 系统错误 = 10005, + 用户已经认证 = 10006, + 验证码过期 = 10007, + 该订单已开通不能撤销 = 10008, + 用户无手机号码 = 10009, + 手机号码已认证 = 10010, + 用户付款失败 = 10011, + 无手机号码不能重置密码 = 10012, + 订单已开通只充值 = 10013, + 订单不存在账户充值成功 = 10014, + 非法请求 = 10015, + 支付金额不足开通失败 = 10016, + 数据不存在 = 10017, + 类型已存在不能重复添加 = 10018, + 非认证用户 = 10019, + 该用户没有手机号码 = 10020, + 十五分钟已连续发送三次 = 10021, + 积分不够业务失败 = 10022, + 验证码错误 = 10023, + 已提交不同身份证开户信息请联系客服处理 = 10024, + 该资源已被他人认领 = 10025, + 资源无须覆盖 = 10026, + 该客户的身份证已存在不能重复提交 = 10027, + 此申请已经授权 = 10028, + 不存在此代理商 = 10029, + 不存在此用户 = 10030, + 平台信息出错请审核数据 = 10031, + 此号码的已被使用 = 10032, + 该渠道禁止申请 = 10033, + 已拥有相同或更高版本 = 10034, + 开通则撤销之前低版本 = 10035, + 正在处理 = 10036, + 交易商号已注册好视通 = 10037, + 好视通用户名不能重复注册 = 10038, + 好视通注册失败 = 10039, + 好视通授权失败 = 10040, + 不能重复提交 = 10041, + 无效产品大类 = 10042, + 无效产品小类 = 10043, + 订单已开通 = 10044, + 订单已取消 = 10045, + 支付步骤出错 = 10046, + 订单未开通 = 10047, + 订单不可取消 = 10048, + 该openID已存在绑定 = 10049, + 密码不正确 = 10050, + 该UP账号已存在绑定 = 10051, + 验证码不能重复使用 = 10052, + 该UP账号已被管理员禁止修改密码 = 10053, + 调用成功但有错误 = 10054, + 找不到订单 = 10055, + 此订单状态不能再开通 = 10056, + 文件路径不能为空 = 10057 + } + + #endregion 注册,认证码表 + + #region 系统参数配置 + + public enum Parameter + { + 资源, 转换, 导出资源, 是否开启加密, + ORD_MemoStatistics_01, //工单统计 + ORD_MemoStatistics_ZhenGu, //诊股资源工单统计 + + Sys_Environment_DeptCode,//当前系统部门编码 + Sys_ExlceImport_PhoneRule,//手机号码生成规则 + Sys_ExcelImport_SkipOran,//是否跳过机构验证导入等于配置的机构数据 + Sys_IsShowFXH,//是否显示渤海信息 + Sys_RetrievePwd_Name,//找回密码短信配置 您好,密码找回短信配置:{0}是密码,{1}是帐号 + Is_ShowCustomerMobileArea,//是否显示号码地区 + Sys_HomeTab_Javascript,//系统home页面的主题框架脚本 主页面的js,Tab打开风格JS + Sys_IsFreeze_Wdzm,//是否冻结我的桌面 默认是不冻结可以关闭的true=冻结,false=可以关闭 + Sys_IsMiniCustomerInfo,//显示简单详细资料 + ISVR_AD_CheckUserNameCompetence, + ISVR_AD_upAgentCreateActiveOrder, + ISVR_AD_upAgentOpenOrder, + ISVR_AD_CancelActiveOrder, + ISVR_AD_HstRegUser, + ISVR_AD_HstDelUserName, + ISVR_AD_HstRoomConfig, + ISVR_AD_HstBatchAddUserRight, + ISVR_AD_HstAddUserPower, + ISVR_AD_TbHstRegUser, + ISVR_AD_TbHstRight, + ISVR_AD_TGHstRoomConfig, + ISVR_AD_HstBlackConfig, + + ISVR_IAD_localhostOpenOrder, + ISVR_IAD_localhostSimpleOpenOrder, + ISVR_IAD_localhostCanclOrder, + ISVR_IAD_localhostHstBatchAddUserRight, + ISVR_IAD_localhostHstRoomConfig, + ISVR_IAD_localhostHstDelUserName, + ISVR_IAD_localhostHstRegUser, + ISVR_IAD_localhostHstAddUserPower, + + HQ_RiaService_ActiveMaunl, + + Sms_TencentResetPwdTid, //腾讯云重置密码模板ID + Sms_TencentHgMsgTid, //腾讯云合规消息模板ID + Sms_TencentOpenOrderTid, + Sms_TencentRegisterTid,//腾讯云用户注册模板ID + Sms_TencentOpenOrderDonateTid, + Sms_TencentSign, //腾讯云短信签名 + Sms_TencentPayMsgTid, //腾讯云在线支付消息模板ID + + CustomerCheckData,//质检抓取时间 + Res_EffectAnalysis_01, //资源效果分析 + ISVR_AD_UpdateManager, + + Sys_Bussiness_Code, //营业部Code + Sys_Environment_LogOn, //当前系统部门编码 + WeiXin_OrderCountShowColumn, //微信订单统计产品小类展示列 + WeiXin_WorkAccountInitCount, //客服工作微信号数量 + WeiXIn_SzzyOrderUnPayDayInterval, //上证综研未支付订单间隔天数 + UserCenter_RiaService_AddOrderOpen,//创建订单 + UserCenter_RiaService_OpenOrder,//开通订单 + UserCenter_RiaService_AddOrderOpenFree,//免费订单 + UserCenter_RiaService_refund,//退款接口 + UserCenter_RiaService_closeFreeOrder,//关闭活动免费订单 + UserCenter_RiaService_ResetPwd,//重置密码接口 + UserCenter_RiaService_ResetMobile,//重置手机号接口 + UserCenter_RiaService_UnBindQW,//软件和企业微信关系解绑 + UserCenter_RiaService_ContractSign,//签订合同 + UserCenter_RiaService_Settlement,//和解协议 + UserCenter_RiaService_CancelComplaint,//撤销投诉协议 + UserCenter_RiaService_SignPdf,//合同pdf地址 + UserCenter_RiaService_OrderGet,//订单信息获取 + UserCenter_RiaService_ForceMerge,//调用Node用户中心进行客户合并 + UserCenter_RiaService_UnBind,//调用Node用户中心进行客户解绑 + UserCenter_RiaService_Risk,//获取风险评测信息 + UserCenter_RiaService_Flag,//获取是否适合信息 + + //UserCenter_RiaService_Riske,//风控URL + Sys_ProjectType, //项目类型,1:证券之星广州 2:南京鼎迈 + + Sys_OrderOpenCountByTimeType, //订单开通统计的时间周期 otime:开通时间 arrivaltime:到账时间 + Sys_ShowMobileStartDate, //为空:就都不显示手机 日期:从该日期之后的资源,显示电话 + Sys_UserComBoxAllShow, //员工分组下拉菜单显示所有员工 0:不显示离职 1:显示全部 + WeiXin_GroupLeaderPasueReceiveRes, //主管是否暂停接收资源 1:暂停 0:接收 + WeiXin_TotalPauseReceiveRes, //微信总资源客户数较多暂停接收资源 1:暂停 0:接收 + Sys_CanExportAllocate, //是否能导出资源 + Sys_OrderClientIdKey, //订单加密客户端ID的键名 + Sys_CanShowResMobile, //是否在资源页面显示手机号 + WeiXin_TotalPauseUserNum, //总资源暂停客服人数 + WeiXin_OrderUserNameRequired, //订单用户微信用户名必填项 + WeiXin_IllegalKewords, //合规关键词词配置 + MonthCommission, //月份提成 + WeiXin_CrossDBSzzyOrder, //跨库订单数据 + Sys_QHData, //期货业务 + WeiXin_OfflineResTypeIds, //线下资源类型id + Sys_IsShowMobileOfContent, //是否显示内容中的手机号 + WeiXin_IsShowOpenOrderTip, //是否显示我的微信客户开通订单提示 + Sys_SaleDeptId_Three, //三部的SaleDeptId + Sys_SaleDeptId_OneAndTwo, //一二部的SaleDeptId + Sys_rpt_json_config,//业绩预测配置 + UserCenter_RiaService_RefundContract, //退款合同 + WeiXin_IllegalKewordsDeptConfig,//合规关键词推送deptcode + UserCenter_UserEnter,//用户中心注册接口 + UserCenter_HandelLabel,//用户中心写标签接口 + HG_Level,//合规类型等级 + AI_CallTaskConfig //回访机器人配置 + } + + public enum ParameterGroup + { + ORD_MemoStatistics, + FavoritesCustType, + SystemConfig,//系统配置 + ExternalInterfaceAddress, + SMS_CONFIG, + OrderPayType + } + + #endregion 系统参数配置 +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Config/SystemConfig.cs b/code/Zxd.Core.Domain/Config/SystemConfig.cs new file mode 100644 index 0000000..4e0dca8 --- /dev/null +++ b/code/Zxd.Core.Domain/Config/SystemConfig.cs @@ -0,0 +1,177 @@ +namespace Zxd.Domain.Config +{ + /// + /// 系统参数 + /// + public class SystemConfig + { + public List Apps { get; set; } + + public string Appid { get; set; } + + public string AppSecret { get; set; } + + public string SsoUrl { get; set; } + public string ZxdCroeUrl { get; set; } + + public string SsoOrganizationUrl { get; set; } + + /// + /// 销售线索URL + /// + public string? SalesLeadUrl { get; set; } + + /// + /// CRM号码加密key(clientKey) + /// + public string? CRMClientKey { get; set; } + + /// + /// 推送部门编码 + /// + + public string? DataClientCode { get; set; } + + public string WeworkSendUrl { get; set; } + + /// + /// 深海捷固定坐席 + /// + public string? Shj { get; set; } + + /// + /// 客户端密钥 + /// + public List? ClientKey { get; set; } + + /// + /// + /// + + public string DataSyncApiUrl { get; set; } + + /// + /// 短信注册信息 + /// + public string SoftRegisterMsg { get; set; } + + public string SsoTokenUrl { get; set; } + + public string CrmBaseUrl { get; set; } + + public string AddStandardProduct { get; set; } + + public string AddStandardPackage { get; set; } + + public string AddVirtualProduct { get; set; } + + public string AddVirtualPackage { get; set; } + public string ActiveProduct { get; set; } + public string ActivePackage { get; set; } + public string UserGroupList { get; set; } + public string GroupUrl { get; set; } + + /// + /// 数据中台 + /// + public string BdMarkting { get; set; } + + public string KfUserCount { get; set; } + + + public string UsercenterUrl { get; set; } + + public string GetAddStandardProduct() + { + return $"{CrmBaseUrl}{AddStandardProduct}"; + } + + public string GetActiveProduct() + { + return $"{CrmBaseUrl}{ActiveProduct}"; + } + + public string GetUserGroupList() + { + return $"{GroupUrl}{UserGroupList}"; + } + + public string GetKFSourceCount() + { + return $"{BdMarkting}{KfUserCount}"; + } + + public string GetActivePackage() + { + return $"{CrmBaseUrl}{ActivePackage}"; + } + + public string GetAddStandardPackage() + { + return $"{CrmBaseUrl}{AddStandardPackage}"; + } + + public string GetAddVirtualProduct() + { + return $"{CrmBaseUrl}{AddVirtualProduct}"; + } + + public string GetAddVirtualPackage() + { + return $"{CrmBaseUrl}{AddVirtualPackage}"; + } + + public string CrmCoreUrl { get; set; } + + public string GetSsoOrganizationUrl() + { + return $"{SsoUrl}{SsoOrganizationUrl}"; + } + public string GetZxdCroeUrl() { + return $"{ZxdCroeUrl}/Api/Deptment/Depts"; + } + public string GetSsoTokenUrl() + { + return $"{SsoUrl}{SsoTokenUrl}"; + } + + /// + /// 资源系统ip地址 + /// + public string CmsUrl { get; set; } + + public string[] ClearCacheUrls { get; set; } + + public string GetAccessKey(string id) + { + return ClientKey?.First(x => x.Id == id).AccessKey ?? ""; + } + + public string GetUserList() + { + return $"{UsercenterUrl}usercenter/cgi/getUserList"; + } + } + + public class App + { + public List Deptids { get; set; } + + public string AppName { get; set; } + + public string Appid { get; set; } + + public string AppSecret { get; set; } + + public string CrmUrl { get; set; } + } + + public class PayCallbackConfig + { + public string AppId { get; set; } + + public string Secret { get; set; } + + public string PushUrl { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/CustomerDomain.cs b/code/Zxd.Core.Domain/CustomerDomain.cs new file mode 100644 index 0000000..423dfab --- /dev/null +++ b/code/Zxd.Core.Domain/CustomerDomain.cs @@ -0,0 +1,338 @@ +using MySqlConnector; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Wework; +using Zxd.EntityFramework; +using static Zxd.Domain.Impl.ICustomerDomain; + +namespace Zxd.Domain +{ + public class CustomerDomain : ICustomerDomain + { + private readonly IConfiguration _configuration; + private readonly IHttpClient _httpClient; + private readonly ICacheDomain _cacheDomain; + private readonly IBaseRepository _repository; + private readonly IBaseRepository _dncmsbaseRepository; + + public CustomerDomain(IConfiguration configuration, + IHttpClient httpClient, + ICacheDomain cacheDomain, + IBaseRepository dncmsbaseRepository, + IBaseRepository repository) + { + _configuration = configuration; + _httpClient = httpClient; + _cacheDomain = cacheDomain; + _repository = repository; + _dncmsbaseRepository = dncmsbaseRepository; + } + /// + /// 添加标签数据 + /// + /// + /// + /// + /// + public async Task AddTag(string resid, string tag,int ceid) + { + tag = tag.Trim(); + resid = resid.Trim(); + if (string.IsNullOrEmpty(tag)) + throw new ApiException("参数错误"); + if (string.IsNullOrEmpty(resid)) + throw new ApiException("参数错误"); + var info = await _repository.GetRepository().Query().Where(m => m.resid == resid && m.tag == tag && m.isdelete==0).FirstOrDefaultAsync(); + if (info != null) + throw new ApiException("已存在此标签"); + + await _repository.GetRepository().InsertAsync(new Res_Tag() + { + resid = resid, + tag = tag, + ceid = ceid + }); + return true; + } + public async Task DelTag(int id,int deleteeid) + { + var info = await _repository.GetRepository().Query().Where(m => m.id == id).FirstOrDefaultAsync(); + if (info == null) + throw new ApiException("找不到这个标签"); + info.deleteeid = deleteeid; + info.isdelete = 1; + await _repository.GetRepository().UpdateAsync(info); + return true; + } + /// + /// 获取标签列表 + /// + /// + /// + public async Task> GetTag(string resid) + { + resid = resid.Trim(); + return await _repository.GetRepository().Query().Where(m => m.resid == resid && m.isdelete==0).ToListAsync(); + } + + + + public async Task> GetUsernames(string? resid) + { + if (string.IsNullOrEmpty(resid)) return new List(); + var usernames = await _repository.GetRepository().Query() + .Where(x => x.RESID == resid) + .Select(x => x.USERNAME) + .ToListAsync(); + return usernames; + } + + public async Task> GetUsernamesByOrderid(string orderidListIn) + { + if (orderidListIn == null) return new List { }; + var orderidList = orderidListIn.Split(";").ToList(); + if (orderidList.Count == 0) return new List(); + + var usernamesList = await _repository.GetRepository().Query() + .Where(x => orderidList.Contains(x.ORDERID.ToString())) + .Select(x => new userRet { orderid = x.ORDERID.ToString(), softwarename = x.SOFTUSERNAME }) + .ToListAsync(); + + var res = new List(); + + orderidList.ForEach(orderid => + { + var findOder = usernamesList.Find(u => u.orderid == orderid); + if (findOder != null) + { + res.Add(findOder); + } + }); + return res; + } + + public async Task CreateCustomer(string MOBILE, string ResId, string CustomerFrom) + { + CreateCustomerRes res = new CreateCustomerRes(); + var customer = await _repository.GetRepository().Query().FirstOrDefaultAsync(x => x.RESID == ResId); + if (customer == null) + { + //开始创建 + var mobile = MOBILE.Replace("+86", ""); + if (mobile.StartsWith("01") && mobile.Length == 12) + { + mobile = mobile.Substring(1); + } + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var key = systemConfig.GetAccessKey(systemConfig.CRMClientKey); + var CNumber = SecurityHelper.EncyptData(mobile, key); + var param = new List + { + new MySqlParameter() { ParameterName = "p_CNumber", DbType = DbType.String, Value =CNumber}, + new MySqlParameter() { ParameterName = "p_ResId", DbType = DbType.String, Value = ResId }, + new MySqlParameter() { ParameterName = "p_CustomerFrom", DbType = DbType.String, Value = CustomerFrom } + }; + param.Add(!string.IsNullOrEmpty(mobile) ? new MySqlParameter() { ParameterName = "p_ECNumber", DbType = DbType.String, Value = NumberFormat(mobile) } : new MySqlParameter() { ParameterName = "p_ECNumber", DbType = DbType.String, Value = DBNull.Value }); + + var i = await _repository.ExecuteSqlCommandNonQueryAsync(System.Data.CommandType.StoredProcedure, "res_ResgisterCustomer", param.ToArray()); + res.code = CCenum.成功; + } + else + { + res.code = CCenum.客户存在; + } + return res; + } + + public async Task> GetFollow(List queryList) + { + var extuseridList = queryList.Select(s => s.extuserid).ToList(); + // 依据appid userid extuserid 找出表中对应的数据,并根据subscribe判断是否关注 + var temp = await _dncmsbaseRepository.GetRepository().Query() + .Where(w => extuseridList.Contains(w.Externaluserid)) + .Select(x => new WwUserFollowOutDto() + { + appid = x.Appid, + userid = x.Userid, + extuserid = x.Externaluserid, + isFollow = x.subscribe + }) + .ToListAsync(); + List res = new List(); + queryList.ForEach(q => + { + var t = temp.Find(f => f.appid == q.appid && f.userid == q.userid && f.extuserid == q.extuserid); + if (t != null) + { + res.Add(new WwUserFollowOutDto + { + appid = t.appid, + userid = t.userid, + extuserid = t.extuserid, + isFollow = t.isFollow + }); + } + }); + + return res; + } + + public async Task> GetSalesLeadList(string? resId) + { + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var result = new List(); + var url = systemConfig.SalesLeadUrl; + var key = systemConfig.GetAccessKey(systemConfig.CRMClientKey); + var reslist = await _repository.GetRepository().Query() + .Where(x => x.RESID == resId).ToListAsync(); + var mobiles = new List(); + foreach (var res in reslist) + { + if (res == null) continue; + mobiles.Add(SecurityHelper.DecyptData(res.MOBILE, key)); + } + + if (mobiles == null || !mobiles.Any()) + { + throw new ApiException("暂无销售线索!", -1); + } + + var parameter = await _cacheDomain.GetValueParameter("ISVR_Saleclus_Get"); + if (string.IsNullOrEmpty(parameter)) return result; + var response = await _httpClient.PostAsync>(parameter, new { mobiles }); + if (response.Ret != 0 || response.List == null) + { + return result; + } + foreach (var saleRelation in response.List) + { + if (result.Any(x => x.Appuserid == saleRelation.Appuserid && x.Appid == saleRelation.Appid)) + { + continue; + } + var name = saleRelation.Appuserid.Length > 10 ? + saleRelation.Appuserid[..10] + "*****" : + saleRelation.Appuserid; + + result.Add(new SalesLeadDto + { + Name = name, + Appid = saleRelation.Appid, + Appuserid = saleRelation.Appuserid, + Url = $"{url}?appid={saleRelation.Appid}&appuserid={saleRelation.Appuserid}" + }); + } + return result; + } + + public string NumberFormat(string number) + { + if (string.IsNullOrEmpty(number) || number.Length <= 6) + { + return number; + } + return number.Substring(0, 3) + new string('*', number.Length - 6) + number.Substring(number.Length - 3); + } + + /// + /// + /// + /// + /// + /// + public async Task> GetWorkWXUserSelectAsync(string? resId, string? DeptCode) + { + if (string.IsNullOrEmpty(resId)) + { + return new List(); + } + var customerQuery = _repository.GetRepository().Query(); + var allCustomer = (from a in customerQuery + join b in customerQuery on a.CUSTOMERID equals b.CUSTOMERID + where b.RESID == resId + select a.RESID).ToList(); + var data = await _repository.GetRepository().Query() + .Where(x => allCustomer.Contains(x.Resid) || x.Resid == resId) + .ToListAsync(); + var result = new List(); + var unameList = data.Select(n => n.Userid).Distinct().ToList(); + foreach (var name in unameList) + { + ExUserModel newModel = new ExUserModel + { + Userid = name, + }; + var names = data.Where(n => n.Userid == name).OrderByDescending(n => n.Ctime).ToList(); + var seftItem = names.FirstOrDefault(n => n.Deptcode == DeptCode); + if (seftItem != null) + { + newModel.Ctime = seftItem.Ctime; + newModel.Deptcode = seftItem.Deptcode; + newModel.Resid = seftItem.Resid; + } + else + { + newModel.Ctime = names.FirstOrDefault().Ctime; + newModel.Deptcode = names.FirstOrDefault().Deptcode; + newModel.Resid = names.FirstOrDefault().Resid; + } + result.Add(newModel); + } + return result.OrderByDescending(n => n.Ctime).ToList(); + } + + public async Task> ExtUserBandGetAsync(string? resId) + { + if (string.IsNullOrEmpty(resId)) + { + return new List(); + } + var customerQuery = _repository.GetRepository().Query(); + var allCustomer = (from a in customerQuery + join b in customerQuery on a.CUSTOMERID equals b.CUSTOMERID + where b.RESID == resId + select a.RESID).ToList(); + var userList = await _repository.GetRepository().Query().Where(n => allCustomer.Contains(n.Resid) || n.Resid == resId).ToListAsync(); + List result = new List(); + foreach (var item in userList) + { + result.Add(item.Userid); + } + result = result.Distinct().ToList(); + return result; + } + + public async Task> GetResidByExtuser(List extUser) + { + if (!extUser.Any()) return new List(); + var resids = await _repository.GetRepository().Query() + .Where(x => extUser.Contains(x.Userid)) + .Select(x => x.Userid + ":" + x.Resid) + .ToListAsync(); + return resids; + } + + public async Task> GetPhoneByUnionid(string unionid) + { + IList mobiles = new List(); + var unionlist = await _repository.GetRepository().Query() + .Where(x => x.unionid == unionid || x.appuserid == unionid).ToListAsync(); + if (unionlist.Any()) + { + mobiles = await _repository.GetRepository().Query() + .Where(x => x.cid == unionlist.First().cid && !string.IsNullOrEmpty(x.mobile)).Select(m => m.mobile).Distinct().ToListAsync(); + } + return mobiles; + } + } + + public class ExtUserItem + { + public string userid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/DeptmentDomain.cs b/code/Zxd.Core.Domain/DeptmentDomain.cs new file mode 100644 index 0000000..2fd6b86 --- /dev/null +++ b/code/Zxd.Core.Domain/DeptmentDomain.cs @@ -0,0 +1,100 @@ +using Zxd.Core.Domain.Dto.Wework; +using Zxd.Entity.Dncms; + +namespace Zxd.Domain +{ + public class DeptmentDomain : IDeptmentDomain + { + private readonly IBaseRepository _repository; + private readonly IBaseRepository _companyBaseConfRepository; + private readonly IRedisManager _redisManager; + + public DeptmentDomain(IBaseRepository repository, + IBaseRepository companyBaseConfRepository, + IRedisManager redisManager) + { + _repository = repository; + _companyBaseConfRepository = companyBaseConfRepository; + _redisManager = redisManager; + } + + public async Task> GetDeptments(bool? IsDept = null) + { + var key = CacheKeys.DeptmentList; + var data = new List(); + if (await _redisManager.ExistsAsync(key)) + { + data = await _redisManager.GetListAsync(key); + data = data.AsQueryable().If(IsDept != null, y => y.Where(x => x.IsDept.HasValue && x.IsDept.Value == IsDept)) + .ToList(); + return data; + } + var query = from a in _companyBaseConfRepository.GetRepository().Query() + join b in _companyBaseConfRepository.GetRepository().Query() on a.DepartmentId equals b.Id + into temp + from t1 in temp.DefaultIfEmpty() + select new { a, t1 }; + + var deptments = await query.ToListAsync(); + var deptids = deptments.Where(x => x.a.Saledeptid != null).Select(x => x.a.Saledeptid).ToList(); + var deptmentList = await _repository.GetRepository().Query() + .Include(x => x.DeptmentCampainIds) + .Where(x => deptids.Contains(x.Id)) + .ToListAsync(); + foreach (var deptment in deptments) + { + var item = new DeptmentDto() + { + Id = deptment.a.Saledeptid.HasValue ? deptment.a.Saledeptid.Value : 0, + Title = deptment.t1 == null ? deptment.a.Title : deptment.t1.DepartmentName, + Code = deptment.a.CompanyCode, + Appid = deptment.a.Appid, + DepartmentId = deptment.a.DepartmentId, + IsDept = deptment.a.IsDept, + CompanyCode = deptment.a.CompanyCode, + SortNo = deptment.a.SortNo, + DeptmentCampains = new List() + }; + if (deptmentList.Count == 0 || !deptmentList.Any(x => x.Id == deptment.a.Saledeptid)) + { + data.Add(item); + continue; + } + var dept = deptmentList.FirstOrDefault(n => n.Id == deptment.a.Saledeptid); + if (dept != null) + { + item.GroupId = dept.Groupid; + foreach (var deptmentCampain in dept.DeptmentCampainIds) + { + item.DeptmentCampains.Add(new DeptmentCampainDto + { + EndCampainId = deptmentCampain.EndCampainId, + StartCampainId = deptmentCampain.StartCampainId + }); + } + } + data.Add(item); + } + + await _redisManager.SetAsync(key, data, TimeSpan.FromDays(1)); + data = data.If(IsDept != null, x => x.Where(x => x.IsDept.HasValue && x.IsDept.Value == IsDept)).ToList(); + return data; + } + + public async Task GetDeptmentByChannel(int channel) + { + var depts = await GetDeptments(); + foreach (var dept in depts) + { + foreach (var ch in dept.DeptmentCampains) + { + if (channel >= ch.StartCampainId && channel <= ch.EndCampainId) + { + return dept; + } + } + } + return null; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Activity/GetActivityNameRequest.cs b/code/Zxd.Core.Domain/Dto/Activity/GetActivityNameRequest.cs new file mode 100644 index 0000000..7edd175 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Activity/GetActivityNameRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Activity +{ + public class GetActivityNameRequest + { + public string Code { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/AddVirtualProductDto.cs b/code/Zxd.Core.Domain/Dto/AddVirtualProductDto.cs new file mode 100644 index 0000000..b146dbe --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/AddVirtualProductDto.cs @@ -0,0 +1,33 @@ +using System; +namespace Zxd.Core.Domain.Dto +{ + public class AddVirtualProductDto + { + public AddVirtualProductDto() + { + } + + [JsonPropertyName("outProductCode")] + public string? OutProductCode { get; set; } + + [JsonPropertyName("price")] + public decimal Price { get; set; } + + [JsonPropertyName("day")] + public string? Day { get; set; } + + [JsonPropertyName("num")] + public int Num { get; set; } + + [JsonPropertyName("productName")] + public string? ProductName { get; set; } + + [JsonPropertyName("sBasicProductCode")] + public string? BasicPorductCode { get; set; } + + [JsonPropertyName("productCode")] + public string? ProductCode { get; set; } + + } +} + diff --git a/code/Zxd.Core.Domain/Dto/AssignQuery.cs b/code/Zxd.Core.Domain/Dto/AssignQuery.cs new file mode 100644 index 0000000..29edfcb --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/AssignQuery.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class WeworkUserAssignDto + { + public WeworkUserAssignDto() + { + } + + public WeworkUserAssignDto(string appuserid, int channel, int curchannel, string remark) : this(1, "com.dongniu", appuserid, string.Empty, channel, curchannel, 0, string.Empty, remark) + { + this.appuserid = appuserid; + this.channel = channel; + this.curchannel = curchannel; + this.remark = remark; + } + + public WeworkUserAssignDto(int apptype, string appid, string appuserid, string unionid, int channel, int curchannel, int type, string livecode, string remark) + { + this.apptype = apptype; + this.appid = appid; + this.appuserid = appuserid; + this.unionid = unionid; + this.channel = channel; + this.curchannel = curchannel; + this.type = type; + this.livecode = livecode; + this.remark = remark; + } + + public int apptype { get; set; } + public string appid { get; set; } + public string appuserid { get; set; } + public string unionid { get; set; } + public int channel { get; set; } + public int curchannel { get; set; } + public int type { get; set; } + public string livecode { get; set; } + public string remark { get; set; } + } + + public class AssignQuery + { + public AssignQuery(string appid, string appuserid, int channel, int curchannel, string remark) : this(appid, appuserid, string.Empty, channel, curchannel, 0, string.Empty, remark, string.Empty, string.Empty, string.Empty) + { + } + + public AssignQuery(string appid, string appuserid, string unionid, int channel, int curchannel, int type, string livecode, string remark, string remarkext, string memo, string eid) + { + this.appid = appid; + this.appuserid = appuserid; + this.unionid = unionid; + this.channel = channel; + this.curchannel = curchannel; + this.type = type; + this.livecode = livecode; + this.remark = remark; + this.remarkext = remarkext; + this.memo = memo; + this.eid = eid; + } + + public string appid { get; set; } + public string appuserid { get; set; } + public string unionid { get; set; } + public int channel { get; set; } + public int curchannel { get; set; } + public int type { get; set; }//1、返回二维码链接、0、不需要返回二码码链接 + public string livecode { get; set; } //活码标识,30字符以内 + public string remark { get; set; }//标记,30字符以内 + public string remarkext { get; set; }//标记补充,30字符以内 + public string memo { get; set; } + public string eid { get; set; }//工号 + } + + public class WeworkUserAssignMessage + { + public int errcode { get; set; } + public string errmsg { get; set; } + public WeworkUserAssignResult data { get; set; } + } + + public class WeworkUserAssignResult + { + public string eid { get; set; } + public int? groupid { get; set; } + public string qr { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Contract/ContractResultView.cs b/code/Zxd.Core.Domain/Dto/Contract/ContractResultView.cs new file mode 100644 index 0000000..cc50180 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Contract/ContractResultView.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Contract +{ + public class ContractQueryDto + { + public decimal orderid { get; set; } + public int? Eid { get; set; } + public string? ViewSource { get; set; } + public string? UserName { get; set; } + public string? PageSource { get; set; } + } + + public class ContractResultView + { + /// + /// 风险揭示书 + /// + public string fxjssUrl { get; set; } + + /// + /// 投顾服务协议.pdf + /// + public string tgfwxyUrl { get; set; } + + /// + /// 风险评测页面 + /// + public string fxpcUrl { get; set; } + + public string businesstype { get; set; } + + /// + /// 产品或服务不适当警示及投资者确认书.pdf + /// + public string cphfwUrl { get; set; } + + /// + /// 适当性评估结果确认书.pdf + /// + public string sdxpgUrl { get; set; } + + /// + /// 合同编码 + /// + public string CONTRACTCODE { get; set; } + + /// + /// 合同编码 + /// + public int? CONTRACTSTATUS { get; set; } + + /// + /// 合同url + /// + public string htUrl { get; set; } + } + + public class RiskInfoDto + { + public int ret { get; set; } + public string answer { get; set; } + public Int64 createTime { get; set; } + public string idCard { get; set; } + public string name { get; set; } + public string key { get; set; } + public string style { get; set; } + public int index { get; set; } + public string businesstype { get; set; } + public int paperId { get; set; } + } + + public class ContractOrderInfo + { + public string ContractCode { get; set; } + public string productname { get; set; } + public string? szzyorderid { get; set; } + public string? productcode { get; set; } + public int? day { get; set; } + public string? username { get; set; } + public int? ContractStatus { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/BaseProductInfoDto.cs b/code/Zxd.Core.Domain/Dto/Crm/BaseProductInfoDto.cs new file mode 100644 index 0000000..d4cf763 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/BaseProductInfoDto.cs @@ -0,0 +1,51 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class BaseProductInfoDto + { + public BaseProductInfoDto() + { + } + + /// + /// 产品编码 + /// + public string Code { get; set; } + + /// + /// 产品名称 + /// + public string ProductName { get; set; } + + /// + /// 产品类别 + /// + public string ProductType { get; set; } + + /// + /// 权限 + /// + public List ProductModules { get; set; } + + /// + /// 价格 + /// + public decimal Price { get; set; } + + /// + /// 时长 + /// + public int Day { get; set; } + + /// + /// 状态 + /// + public string Status { get; set; } + + /// + /// 产品类型(基础产品/组合产品) + /// + public string ProductProperty { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/ChangeProductStatusDto.cs b/code/Zxd.Core.Domain/Dto/Crm/ChangeProductStatusDto.cs new file mode 100644 index 0000000..857fa4e --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/ChangeProductStatusDto.cs @@ -0,0 +1,16 @@ +using System; + +namespace Zxd.Domain.Dto.Crm +{ + public class ChangeProductStatusDto + { + public ChangeProductStatusDto() + { + } + + /// + /// 产品编码 + /// + public string? ProductCode { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDetailDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDetailDto.cs new file mode 100644 index 0000000..616cf19 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDetailDto.cs @@ -0,0 +1,36 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class CreateFinishedProductDetailDto + { + public CreateFinishedProductDetailDto() + { + } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 事业部id + /// + public int Deptid { get; set; } + + /// + /// 成品价格 + /// + public decimal Price { get; set; } + + /// + /// 成品时长 + /// + public string? Day { get; set; } + + /// + /// 产品系数 + /// + public int Coefficient { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDto.cs new file mode 100644 index 0000000..7edc06b --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateFinishedProductDto.cs @@ -0,0 +1,138 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Domain.Dto.Crm +{ + public class CreateFinishedProductDto + { + public CreateFinishedProductDto() + { + } + + /// + /// 基准产品编码 + /// + public string? ProductCode { get; set; } + + /// + /// 基准产品id + /// + public int StandardProductId { get; set; } + + /// + /// 产品系列 + /// + public int ProductSeriesId { get; set; } + + /// + /// 产品大类 + /// + public int ProductCategoryId { get; set; } + + /// + /// 产品服务交付 + /// + public int ProductServerType { get; set; } + + /// + /// 自动开通 + /// + public bool AutoOpen { get; set; } + + /// + /// 开通方式 + /// + public int OpenCondition { get; set; } + + /// + /// 状态 + /// + public int Status { get; set; } + + /// + /// 是否赠送 + /// + public bool Give { get; set; } + + /// + /// 是否折扣 + /// + public bool Discount { get; set; } + + /// + /// 折扣区间 + /// + public bool Custom { get; set; } + + /// + /// 是否可升级 + /// + public bool Upgrade { get; set; } + + /// + /// 第三方分类 + /// + public bool OtherClassify { get; set; } + + /// + /// 是否在线购买 + /// + public bool BuyOnline { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + [JsonIgnore] + public string? DiscounSections + { + get + { + return DiscounSectionList == null ? null + : JsonSerializer.Serialize(DiscounSectionList); + } + } + + [JsonInclude] + public string? GiveProducts + { + get + { + return GiveProductList == null ? null + : JsonSerializer.Serialize(GiveProductList); + } + } + + [JsonIgnore] + public string? CustomPrices + { + get + { + return CustomPriceList == null ? null + : JsonSerializer.Serialize(CustomPriceList); + } + } + + /// + /// 赠送设置 + /// + public List? GiveProductList { get; set; } + + /// + /// 折扣设置 + /// + public List? DiscounSectionList { get; set; } + + /// + /// 折扣区间设置 + /// + public List? CustomPriceList { get; set; } + + /// + /// 产品信息填写 + /// + public List FinishedProductDetails { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateProductCodeDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateProductCodeDto.cs new file mode 100644 index 0000000..c6a92a4 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateProductCodeDto.cs @@ -0,0 +1,15 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class CreateProductCodeDto + { + public CreateProductCodeDto() + { + } + + public string ProductCode { get; set; } + + public decimal Price { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateProductDto.cs new file mode 100644 index 0000000..ddc4ccf --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateProductDto.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Crm +{ + public class CreateProductDto + { + public string? ProductCode { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 是否免费 + /// + public bool Free { get; set; } + + /// + /// 产品类型 + /// + public int ProductType { get; set; } + + /// + /// 产品权限 + /// + public int ProductModule { get; set; } + + /// + /// 产品价格 + /// + public decimal Price { get; set; } + + /// + /// 产品时长 + /// + public int Day { get; set; } + + /// + /// 投顾老师 + /// + public List? Teachers { get; set; } + + /// + /// 自动开通 + /// + public bool AutoOpen { get; set; } + /// + /// 权限 + /// + public List ProductModules { get; set; } + } + + public class ImportProductDto + { + /// + /// 产品名称 + /// + public string ProductName { get; set; } + + /// + /// 产品类型 + /// + public string ProductType { get; set; } + + /// + /// 产品价格 + /// + public string Price { get; set; } + + /// + /// 投顾老师 + /// + public string Teachers { get; set; } + + /// + /// 是否免费 + /// + public string Free { get; set; } + } + + public class ImportBasicsProductDto : ImportProductDto + { + /// + /// 时长 + /// + public string Day { get; set; } + + /// + /// 产品权限 + /// + public string ProductModule { get; set; } + } + + public class ImportComProductDto : ImportProductDto + { + /// + /// 子产品 + /// + public string ProductCodes { get; set; } + } + + public class ImportBasicsProductViewModel + { + public string? ProductName { get; set; } + public bool Free { get; set; } + public int ProductType { get; set; } + public string? ProductTypeName { get; set; } + public string? ProductModule { get; set; } + public string? ProductModuleName { get; set; } + public double Price { get; set; } + public int Day { get; set; } + public List? Teachers { get; set; } = new List(); + public bool AutoOpen { get; set; } + + /// + /// 是否能成功 + /// + public string Msg { get; set; } + } + + public class ImportCombinationViewModel + { + public string ProductName { get; set; } + public bool Free { get; set; } + public int ProductType { get; set; } + public string ProductTypeName { get; set; } + public List ProductCodes { get; set; } + public double Price { get; set; } + public int Day { get; set; } + public List Teachers { get; set; } + public bool AutoOpen { get; set; } + + /// + /// 是否能成功 + /// + public string Msg { get; set; } + } + + public class ProductInfo + { + public string? Code { get; set; } + public string? Name { get; set; } + public decimal Price { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateProductPackageDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateProductPackageDto.cs new file mode 100644 index 0000000..ba5552f --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateProductPackageDto.cs @@ -0,0 +1,101 @@ +using System; +using Zxd.Core.Domain.Dto.Crm; + +namespace Zxd.Domain.Dto.Crm +{ + public class CreateProductPackageDto + { + public CreateProductPackageDto() + { + } + + public string? ProductCode { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 是否免费 + /// + public bool Free { get; set; } + + /// + /// 产品类型 + /// + public int ProductType { get; set; } + + /// + /// 产品价格 + /// + public decimal Price { get; set; } + + /// + /// 产品时长 + /// + public int Day { get; set; } + + /// + /// 投顾老师 + /// + public List? Teachers { get; set; } + + /// + /// 子产品 + /// + public List ProductCodes { get; set; } + + /// + /// 自动开通 + /// + public bool AutoOpen { get; set; } + } + + public class EditProductPackageDto : DroplistEnumDto + { + public EditProductPackageDto() + { + } + + public string? ProductCode { get; set; } + public List ProductList { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 是否免费 + /// + public bool Free { get; set; } + + /// + /// 产品类型 + /// + public int? ProductType { get; set; } + + public int? Status { get; set; } + + /// + /// 产品价格 + /// + public decimal Price { get; set; } + + /// + /// 投顾老师 + /// + public List? ProTeacherInfo { get; set; } + + /// + /// 子产品 + /// + public List ProductCodes { get; set; } + + /// + /// 自动开通 + /// + public bool? EffectiveImmediately { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateProductTeacherDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateProductTeacherDto.cs new file mode 100644 index 0000000..8e58108 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateProductTeacherDto.cs @@ -0,0 +1,45 @@ +using System; + +namespace Zxd.Domain.Dto.Crm +{ + public class CreateProductTeacherDto + { + public CreateProductTeacherDto() + { + } + + /// + /// 事业线id + /// + public int Deptid { get; set; } + + /// + /// 老师编号 + /// + public List? TeacherCodes { get; set; } + } + + public class ImportProductTeacherDto + { + /// + /// 事业线id + /// + public int Deptid { get; set; } + + /// + /// 事业线名称 + /// + public string DeptName { get; set; } + + /// + /// 老师编号 + /// + public List? TeacherCodes { get; set; } = new List { }; + } + + public class TeacherInfo + { + public string? Code { get; set; } + public string? Name { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateStandardProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateStandardProductDto.cs new file mode 100644 index 0000000..e2d69f1 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateStandardProductDto.cs @@ -0,0 +1,18 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class CreateStandardProductDto + { + public CreateStandardProductDto() + { + } + + public string ProductCode { get; set; } + + public int StandardType { get; set; } + + public int StandardWay { get; set; } + + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/CreateSuperProductPackageDto.cs b/code/Zxd.Core.Domain/Dto/Crm/CreateSuperProductPackageDto.cs new file mode 100644 index 0000000..827785f --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/CreateSuperProductPackageDto.cs @@ -0,0 +1,58 @@ +using System; +using Zxd.Core.Domain.Dto.Crm; + +namespace Zxd.Domain.Dto.Crm +{ + public class CreateSuperProductPackageDto + { + public CreateSuperProductPackageDto() + { + } + + public string? ProductCode { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 是否免费 + /// + public bool Free { get; set; } + + /// + /// 产品类型 + /// + public int ProductType { get; set; } + + + /// + /// 投顾老师 + /// + public List? Teachers { get; set; } + + ///// + ///// 子产品 + ///// + //public List ProductCodes { get; set; } + + /// + /// 自动开通 + /// + public bool AutoOpen { get; set; } + /// + /// 天数,数组 + /// + + public string[] days { get; set; } + /// + /// 金额,数组 + /// + public string[] prices { get; set; } + public string [] productModule { get; set; } + + } + + +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/DroplistEnumDto.cs b/code/Zxd.Core.Domain/Dto/Crm/DroplistEnumDto.cs new file mode 100644 index 0000000..82f0b17 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/DroplistEnumDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Crm +{ + /// + /// 下拉框枚举 + /// + public class DroplistEnumDto + { + public List Group { get; set; } + public List Module { get; set; } + public List Teacher { get; set; } + public List Dept { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/EditFinishedProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/EditFinishedProductDto.cs new file mode 100644 index 0000000..a17db41 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/EditFinishedProductDto.cs @@ -0,0 +1,128 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class EditFinishedProductDto + { + public EditFinishedProductDto() + { + } + + public int Id { get; set; } + + /// + /// 基准产品id + /// + public int StandardProductId { get; set; } + + /// + /// 产品系列 + /// + public int ProductSeriesId { get; set; } + + /// + /// 产品大类 + /// + public int ProductCategoryId { get; set; } + + /// + /// 产品服务交付 + /// + public ProductServerType ProductServerType { get; set; } + + /// + /// 自动开通 + /// + public bool AutoOpen { get; set; } + + /// + /// 开通方式 + /// + public int OpenCondition { get; set; } + + /// + /// 状态 + /// + public ProductStatus Status { get; set; } + + /// + /// 是否赠送 + /// + public bool Give { get; set; } + + /// + /// 是否折扣 + /// + public bool Discount { get; set; } + + /// + /// 折扣区间 + /// + public bool Custom { get; set; } + + /// + /// 是否可升级 + /// + public bool Upgrade { get; set; } + + /// + /// 第三方分类 + /// + public bool OtherClassify { get; set; } + + /// + /// 是否在线购买 + /// + public bool BuyOnline { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + [JsonIgnore] + public string? DiscounSections + { + get + { + return DiscounSectionList == null ? null + : JsonSerializer.Serialize(DiscounSectionList); + } + } + + [JsonInclude] + public string? GiveProducts + { + get + { + return GiveProductList == null ? null + : JsonSerializer.Serialize(GiveProductList); + } + } + + [JsonIgnore] + public string? CustomPrices + { + get + { + return CustomPriceList == null ? null + : JsonSerializer.Serialize(CustomPriceList); + } + } + + /// + /// 赠送设置 + /// + public List? GiveProductList { get; set; } + + /// + /// 折扣设置 + /// + public List? DiscounSectionList { get; set; } + + /// + /// 折扣区间设置 + /// + public List? CustomPriceList { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/FinishedCustomPriceDto.cs b/code/Zxd.Core.Domain/Dto/Crm/FinishedCustomPriceDto.cs new file mode 100644 index 0000000..90dc9c0 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/FinishedCustomPriceDto.cs @@ -0,0 +1,15 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class FinishedCustomPriceDto + { + public FinishedCustomPriceDto() + { + } + + public decimal? Max { get; set; } + + public decimal? Min { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/FinishedGiveProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/FinishedGiveProductDto.cs new file mode 100644 index 0000000..6d3292b --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/FinishedGiveProductDto.cs @@ -0,0 +1,19 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class FinishedGiveProductDto + { + public FinishedGiveProductDto() + { + } + + public string? ProductCode { get; set; } + + public bool? OrderPaymentPresenter { get; set; } + + public bool? AfterPaymentPresenter { get; set; } + + public int? Sort { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/FinishedProductDetailDto.cs b/code/Zxd.Core.Domain/Dto/Crm/FinishedProductDetailDto.cs new file mode 100644 index 0000000..cf04296 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/FinishedProductDetailDto.cs @@ -0,0 +1,235 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Domain.Dto.Crm +{ + public class FinishedProductDetailDto + { + public FinishedProductDetailDto() + { + } + + /// + /// 成品产品id + /// + public int Id { get; set; } + + /// + /// 基准产品id + /// + public int StandardProductId { get; set; } + + /// + /// 基准产品分类 + /// + public string? StandardProductType { get; set; } + + /// + /// 基准产品名称 + /// + public string? StandardProductName { get; set; } + + /// + /// 基准产品价格 + /// + public decimal? StandardProductPrice { get; set; } + + /// + /// 基准产品时长 + /// + public string? StandardProductDay { get; set; } + + /// + /// 基准产品权限 + /// + public List? StandardProductModules { get; set; } + + /// + /// 产品系列 + /// + public int ProductSeriesId { get; set; } + + /// + /// 产品系列 + /// + public string? ProductSeries { get; set; } + + /// + /// 产品大类 + /// + public int ProductCategoryId { get; set; } + + /// + /// 产品大类 + /// + public string? ProductCategory { get; set; } + + /// + /// 产品编码 + /// + public string? ProductCode { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 事业部id + /// + public int Deptid { get; set; } + + /// + /// 事业部 + /// + public string? Department { get; set; } + + /// + /// 产品价格 + /// + public decimal ProductPrice { get; set; } + + /// + /// 产品时长 + /// + public string? Day { get; set; } + + /// + /// 系数 + /// + public int Coefficient { get; set; } + + /// + /// 产品服务交付编号 + /// + public ProductServerType ProductServerType { get; set; } + + /// + /// 产品服务交付 + /// + public string? ProductServerTypeName + { + get + { + return ProductServerType.GetDescription(); + } + } + + /// + /// 是否自动开通 + /// + public bool AutoOpen { get; set; } + + /// + /// 开通方式 + /// + public int OpenCondition { get; set; } + + /// + /// 状态 + /// + public ProductStatus Status { get; set; } + + /// + /// 状态 + /// + public string? StatusName + { + get + { + return Status.GetDescription(); + } + } + + /// + /// 是否赠送 + /// + public bool Give { get; set; } + + /// + /// 是否折扣 + /// + public bool Discount { get; set; } + + /// + /// 折扣区间 + /// + public bool Custom { get; set; } + + /// + /// 是否可升级 + /// + public bool Upgrade { get; set; } + + /// + /// 第三方分类 + /// + public bool OtherClassify { get; set; } + + /// + /// 是否在线购买 + /// + public bool BuyOnline { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 折扣设置 + /// + [JsonIgnore] + public string? DiscounSections { get; set; } + + /// + /// 赠送设置 + /// + [JsonIgnore] + public string? GiveProducts { get; set; } + + /// + /// 折扣区间设置 + /// + [JsonIgnore] + public string? CustomPrices { get; set; } + + /// + /// 赠送设置 + /// + public List? GiveProductList + { + get + { + return string.IsNullOrEmpty(GiveProducts) ? null + : JsonSerializer.Deserialize>(GiveProducts); + } + } + + /// + /// 折扣设置 + /// + public List? DiscounSectionList + { + get + { + return string.IsNullOrEmpty(DiscounSections) ? null + : JsonSerializer.Deserialize>(DiscounSections); + } + } + + /// + /// 折扣区间设置 + /// + public List? CustomPriceList + { + get + { + return string.IsNullOrEmpty(CustomPrices) ? null + : JsonSerializer.Deserialize>(CustomPrices); + } + } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/FinishedProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/FinishedProductDto.cs new file mode 100644 index 0000000..9c6df04 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/FinishedProductDto.cs @@ -0,0 +1,87 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class FinishedProductDto + { + public FinishedProductDto() + { + } + + /// + /// 成品产品id + /// + public int Id { get; set; } + + /// + /// 基准产品id + /// + public int StandardProductId { get; set; } + + /// + /// 产品系列 + /// + public int ProductSeriesId { get; set; } + + /// + /// 产品系列 + /// + public string? ProductSeries { get; set; } + + /// + /// 产品大类 + /// + public int ProductCategoryId { get; set; } + + /// + /// 产品大类 + /// + public string? ProductCategory { get; set; } + + /// + /// 事业部 + /// + public string? Department { get; set; } + + /// + /// 事业部id + /// + [JsonIgnore] + public int Deptid { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 产品价格 + /// + public decimal ProducPrice { get; set; } + + /// + /// 产品时长 + /// + public string? ProducDay { get; set; } + + /// + /// 基准产品权限 + /// + public List? StandardProductModules { get; set; } + + /// + /// 是否自动开通 + /// + public string? AutoOpen { get; set; } + + /// + /// 产品服务交付 + /// + public string? ProductServerType { get; set; } + + /// + /// 状态 + /// + public string? Status { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/ProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/ProductDto.cs new file mode 100644 index 0000000..11253f3 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/ProductDto.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Crm; + +namespace Zxd.Domain.Dto.Crm +{ + public class ProductDto + { + public int Id { get; set; } + + public string? ProdcutName { get; set; } + + public string? ProdcutType { get; set; } + + public string? ProductModule { get; set; } + + public string? Price { get; set; } + + public string? Day { get; set; } + + public string? Status { get; set; } + + public string? ProdcutCode { get; set; } + + public string? EffectiveImmediately { get; set; } + + public string? Ctime { get; set; } + } + + public class ProductEdit : DroplistEnumDto + { + public int Id { get; set; } + + public string? ProductName { get; set; } + + public int? ProductType { get; set; } + + public string? ProductModule { get; set; } + + public decimal Price { get; set; } + + public int? Day { get; set; } + + public int? Status { get; set; } + + public string? ProductCode { get; set; } + public bool Free { get; set; } + public bool? EffectiveImmediately { get; set; } + public List ProTeacherInfo { get; set; } + } + + public class ProTeacherInfo + { + public int dept_val { get; set; } + public string? dept_txt { get; set; } + public List teacherInfos { get; set; } + } + + public class teacherInfo + { + public string? name { get; set; } + public string? code { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/ProductModuleInfo.cs b/code/Zxd.Core.Domain/Dto/Crm/ProductModuleInfo.cs new file mode 100644 index 0000000..f310078 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/ProductModuleInfo.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Crm +{ + public class ProductModuleInfo + { + public int? productlevel { get; set; } + public int? productinvesttype { get; set; } + public int? productinvesttime { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/ProductPackageDto.cs b/code/Zxd.Core.Domain/Dto/Crm/ProductPackageDto.cs new file mode 100644 index 0000000..70fdabf --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/ProductPackageDto.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Crm +{ + public class ProductPackageDto + { + public int Id { get; set; } + + public string? ProdcutName { get; set; } + + public string? ProdcutType { get; set; } + + public List? ProductModule { get; set; } + + public string? Price { get; set; } + + public string? Day { get; set; } + + public string? Status { get; set; } + + public string? ProdcutCode { get; set; } + + public string? EffectiveImmediately { get; set; } + + public string? Ctime { get; set; } + + [JsonIgnore] + public List ProductCodes { get + { + return SubProductsInfos == null || !SubProductsInfos.Any() ? new List() + : SubProductsInfos.Select(x => x.SubProductId).ToList(); + } + } + + [JsonIgnore] + public string? SubProductsInfo { get; set; } + + [JsonIgnore] + public List? SubProductsInfos + { + get + { + return string.IsNullOrEmpty(SubProductsInfo) ? new List() + : JsonSerializer.Deserialize>(SubProductsInfo); + } + } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Crm/ResTagAddDto.cs b/code/Zxd.Core.Domain/Dto/Crm/ResTagAddDto.cs new file mode 100644 index 0000000..3fd9718 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/ResTagAddDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Crm +{ + public class ResTagAddDto + { + public string tag { get; set; } + public string resid { get; set; } + public int ceid { get; set; } + } + public class DelResTagDto + { + + public int id { get; set; } + public int deleteeid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Crm/SearchFinishedProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/SearchFinishedProductDto.cs new file mode 100644 index 0000000..0be1661 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/SearchFinishedProductDto.cs @@ -0,0 +1,47 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class SearchFinishedProductDto : SearchPageBase + { + public SearchFinishedProductDto() + { + } + + /// + /// 事业部 + /// + public int? Deptid { get; set; } + + /// + /// 成品产品名称 + /// + public string? Name { get; set; } + + /// + /// 产品编码 + /// + public string? ProductCode { get; set; } + + /// + /// 成品价格 + /// + public decimal? Price { get; set; } + + /// + /// 成品时长 + /// + public int? Day { get; set; } + + /// + /// 权限 + /// + public string? Module { get; set; } + + /// + /// 状态 + /// + public ProductStatus? Status { get; set; } + + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/SearchProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/SearchProductDto.cs new file mode 100644 index 0000000..5a609e5 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/SearchProductDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Crm +{ + public class SearchProductDto : SearchPageBase + { + public string? ProductName { get; set; } + + public string? ProductModule { get; set; } + + public string? ProductCode { get; set; } + + public int? Active { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Crm/SearchProductPackageDto.cs b/code/Zxd.Core.Domain/Dto/Crm/SearchProductPackageDto.cs new file mode 100644 index 0000000..d9523d9 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/SearchProductPackageDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Crm +{ + public class SearchProductPackageDto : SearchPageBase + { + public string? ProductName { get; set; } + + public string? ProductModule { get; set; } + + public string? ProductCode { get; set; } + + public bool? Active { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Crm/SearchStandardProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/SearchStandardProductDto.cs new file mode 100644 index 0000000..51df63d --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/SearchStandardProductDto.cs @@ -0,0 +1,17 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class SearchStandardProductDto : SearchPageBase + { + public SearchStandardProductDto() + { + } + + public int? Id { get; set; } + + public string? ProductName { get; set; } + + public int? StandardType { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/StandardProductDto.cs b/code/Zxd.Core.Domain/Dto/Crm/StandardProductDto.cs new file mode 100644 index 0000000..b9cab07 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/StandardProductDto.cs @@ -0,0 +1,65 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class StandardProductDto + { + public StandardProductDto() + { + } + /// + /// 基准产品ID + /// + public int Id { get; set; } + + /// + /// 产品类型 + /// + public string? ProductProperty { get; set; } + + /// + /// 产品编码 + /// + public string? ProductCode { get; set; } + + /// + /// 基准产品分类 + /// + public string? StandardProductType { get; set; } + + /// + /// 基准产品名称 + /// + public string? StandardProductName { get; set; } + + /// + /// 基准产品权限 + /// + public List? StandardProductModule { get; set; } + + /// + /// 基准产品价格 + /// + public string? Price { get; set; } + + /// + /// 基准产品时长 + /// + public string? Day { get; set; } + + /// + /// 基准产品状态 + /// + public string? Status { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 关联成品产品数量 + /// + public int? FinishedProductCount { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/StandardProductInfoDto.cs b/code/Zxd.Core.Domain/Dto/Crm/StandardProductInfoDto.cs new file mode 100644 index 0000000..1e2908e --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/StandardProductInfoDto.cs @@ -0,0 +1,47 @@ +using System; +namespace Zxd.Domain.Dto.Crm +{ + public class StandardProductInfoDto + { + public StandardProductInfoDto() + { + } + + /// + /// 基准产品编码 + /// + public string? ProductCode { get; set; } + + /// + /// 基准产品分类 + /// + public string? ProductType { get; set; } + + /// + /// 基准产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 基准产品价格 + /// + public string? Price { get; set; } + + /// + /// 基准产品时长 + /// + public string? Day { get; set; } + + /// + /// 基准产品权限 + /// + public List? Module { get; set; } + + /// + /// 是否需要合规 + /// + public string? Compliance { get; set; } + + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Crm/WwHhuserEidDto.cs b/code/Zxd.Core.Domain/Dto/Crm/WwHhuserEidDto.cs new file mode 100644 index 0000000..6b7d77a --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Crm/WwHhuserEidDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Crm +{ + public class WwHhuserEidDto + { + public string? USERID { get; set; } + public string? CORPID { get; set; } + public decimal EID { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Dncmsbase/DeptStatistcsDto.cs b/code/Zxd.Core.Domain/Dto/Dncmsbase/DeptStatistcsDto.cs new file mode 100644 index 0000000..a0d9c19 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Dncmsbase/DeptStatistcsDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Dncmsbase +{ + public class DeptStatistcsDto + { + public string? Title { get; set; } + + public int? Only { get; set; } + + public int? Total { get; set; } + + public int? Increment { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Dncmsbase/MonthAttentionDto.cs b/code/Zxd.Core.Domain/Dto/Dncmsbase/MonthAttentionDto.cs new file mode 100644 index 0000000..bd2eb07 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Dncmsbase/MonthAttentionDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Dncmsbase +{ + public class MonthAttentionDto + { + public string? Date { get; set; } + + public List? DeptData { get; set; } + + public List? ConterData { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Dncmsbase/WeWorkUser2EidDto.cs b/code/Zxd.Core.Domain/Dto/Dncmsbase/WeWorkUser2EidDto.cs new file mode 100644 index 0000000..c0fcded --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Dncmsbase/WeWorkUser2EidDto.cs @@ -0,0 +1,25 @@ +using System.ComponentModel; + +namespace Zxd.Core.Domain.Dto.Dncmsbase +{ + public class WeWorkUser2EidDto + { + /// + /// + /// + [Description("")] + public string userid { get; set; } + + /// + /// + /// + [Description("")] + public int? eid { get; set; } + + /// + /// + /// + [Description("")] + public int? deptid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorLogDto.cs b/code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorLogDto.cs new file mode 100644 index 0000000..b0b4c5d --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorLogDto.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.ImportanceItem +{ + public class CustomerBehaviorLogDto + { + public int Id { get; set; } + + public string? Content { get; set; } + + public string? Deptname { get; set; } + + public int Eventid { get; set; } + + public string? Eventname { get; set; } + + public string? Scenetypename { get; set; } + + public string? Sceneidname { get; set; } + + public int? Deptid { get; set; } + + public DateTime? ActTime { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorStatisticsDto.cs b/code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorStatisticsDto.cs new file mode 100644 index 0000000..8802159 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/ImportanceItem/CustomerBehaviorStatisticsDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.ImportanceItem +{ + public class CustomerBehaviorStatisticsDto + { + public int Eventid { get; set; } + + public string? EventName { get; set; } + + public int Count { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/ImportanceItem/SearchCustomerBehaviorLogDto.cs b/code/Zxd.Core.Domain/Dto/ImportanceItem/SearchCustomerBehaviorLogDto.cs new file mode 100644 index 0000000..f593a29 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/ImportanceItem/SearchCustomerBehaviorLogDto.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.ImportanceItem +{ + public class SearchCustomerBehaviorLogDto + { + public string? Resid { get; set; } + + public int? Eventid { get; set; } + + public int? Uid { get; set; } + + public string? Appid { get; set; } + + public string? Appuserid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Resource/GroupPageDto.cs b/code/Zxd.Core.Domain/Dto/Resource/GroupPageDto.cs new file mode 100644 index 0000000..017f74b --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Resource/GroupPageDto.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Resource +{ + public class LivePageDto + { + /// + /// 当前页码 + /// + [JsonPropertyName("currentPage")] + public int? CurrentPage { get; set; } + + /// + /// 每页记录数 + /// + [JsonPropertyName("pageSize")] + public int? PageSize { get; set; } + + /// + /// 列表数据 + /// + [JsonPropertyName("tableData")] + public List TableData { get; set; } + + /// + /// 总记录数 + /// + [JsonPropertyName("total")] + public long Total { get; set; } + } + public class GroupPageDto + { + /// + /// 当前页码 + /// + [JsonPropertyName("currentPage")] + public string CurrentPage { get; set; } + + /// + /// 每页记录数 + /// + [JsonPropertyName("pageSize")] + public string PageSize { get; set; } + + /// + /// 列表数据 + /// + [JsonPropertyName("tableData")] + public List TableData { get; set; } + + /// + /// 总记录数 + /// + [JsonPropertyName("total")] + public long Total { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Resource/WxworkResponse.cs b/code/Zxd.Core.Domain/Dto/Resource/WxworkResponse.cs new file mode 100644 index 0000000..41b3a21 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Resource/WxworkResponse.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Resource +{ + public class WxworkResponse + { + [JsonPropertyName("errcode")] + public int? ErrCode { get; set; } + + [JsonPropertyName("errmsg")] + public string? RrrMessage { get; set; } + + [JsonPropertyName("data")] + public T? Data { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/SalesLeadDto.cs b/code/Zxd.Core.Domain/Dto/SalesLeadDto.cs new file mode 100644 index 0000000..80a2bab --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/SalesLeadDto.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class SalesLeadDto + { + /// + /// 名称 + /// + public string? Name { get; set; } + + /// + /// 连接 + /// + public string? Url { get; set; } + + /// + /// + /// + public string? Appid { get; set; } + + /// + /// + /// + public string? Appuserid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/SsoOrganizationDto.cs b/code/Zxd.Core.Domain/Dto/SsoOrganizationDto.cs new file mode 100644 index 0000000..b8da342 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/SsoOrganizationDto.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto +{ + public class SsoOrganizationDto + { + /// + /// 部门id + /// + public int Id { get; set; } + /// + /// 部门状态 + /// + public int Status { get; set; } + /// + /// 父级部门id + /// + public int? ParentId { get; set; } + /// + /// 部门名称 + /// + public string? DepartmentName { get; set; } + /// + /// 部门编号 + /// + public string? DepartmentCode { get; set; } + + /// + /// 子部门 + /// + public List? Children { get; set; } + + /// + /// 员工信息 + /// + public List SsoStaffs { get; set; } = new List(); + } +} diff --git a/code/Zxd.Core.Domain/Dto/SsoStaffDto.cs b/code/Zxd.Core.Domain/Dto/SsoStaffDto.cs new file mode 100644 index 0000000..e87c6de --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/SsoStaffDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto +{ + public class SsoStaffDto + { + public int Eid { get; set; } + + public string? Name { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/TodoItem/EditReadRequest.cs b/code/Zxd.Core.Domain/Dto/TodoItem/EditReadRequest.cs new file mode 100644 index 0000000..498a65c --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/TodoItem/EditReadRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.TodoItem +{ + public class EditReadRequest + { + public int? Id { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/TodoItem/GetEventTypeSelectRequest.cs b/code/Zxd.Core.Domain/Dto/TodoItem/GetEventTypeSelectRequest.cs new file mode 100644 index 0000000..b7cb15c --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/TodoItem/GetEventTypeSelectRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.TodoItem +{ + public class GetEventTypeSelectRequest + { + public string? eventid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/TodoItem/GetListRequest.cs b/code/Zxd.Core.Domain/Dto/TodoItem/GetListRequest.cs new file mode 100644 index 0000000..b7adff6 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/TodoItem/GetListRequest.cs @@ -0,0 +1,33 @@ +namespace Zxd.Core.Domain.Dto.TodoItem +{ + public class GetListRequest : SearchPageBase + { + public int? deptid { get; set; } + + public int? eid { get; set; } + + public string? resid { get; set; } + + public int? customerid { get; set; } + + public string? cname { get; set; } + + public string? eventid { get; set; } + + public string? eventtypename { get; set; } + + public string? eventmemo { get; set; } + + public DateTime? noticetimeBegin { get; set; } + + public DateTime? noticetimeEnd { get; set; } + + public int? isread { get; set; } + + public DateTime? readtimeBegin { get; set; } + + public DateTime? readtimeEnd { get; set; } + + public string lineid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/TodoItem/TodoItemDto.cs b/code/Zxd.Core.Domain/Dto/TodoItem/TodoItemDto.cs new file mode 100644 index 0000000..56c3e44 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/TodoItem/TodoItemDto.cs @@ -0,0 +1,50 @@ +namespace Zxd.Core.Domain.Dto.TodoItem +{ + public class TodoItemDto + { + public int? id { get; set; } + + public int deptid { get; set; } + + public string? deptname { get; set; } + + public int? eid { get; set; } + + public string ename { get; set; } + + public string? resid { get; set; } + public string? umid { get; set; } + public int? customerid { get; set; } + + public string cname { get; set; } + + public int eventid { get; set; } + + public string? eventname { get; set; } + + public string? eventmemo { get; set; } + + public DateTime? noticetime { get; set; } + + public string? eventtypename { get; set; } + + public int? isread { get; set; } + + public DateTime? readtime { get; set; } + + public string appid { get; set; } + + public string appuserid { get; set; } + + public int neweventid { get; set; } + public string? sceneid { get; set; } + public string? linkurl { get; set; } + } + + public class ToDoItemNoticeDto + { + public string StartTime { get; set; } + public string EndTime { get; set; } + public bool IsNotice { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/UserInfoDto.cs b/code/Zxd.Core.Domain/Dto/UserInfoDto.cs new file mode 100644 index 0000000..5e52a2e --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/UserInfoDto.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto +{ + public class UserInfoDto + { + [JsonPropertyName("uid")] + public string? Uid { get; set; } + + [JsonPropertyName("appid")] + public string? Appid { get; set; } + + [JsonPropertyName("appuserid")] + public string? Appuserid { get; set; } + + [JsonPropertyName("customerid")] + public string? Customerid { get; set; } + + [JsonPropertyName("resid")] + public string? Resid { get; set; } + + [JsonPropertyName("unionid")] + public string? Unionid { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserDto.cs b/code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserDto.cs new file mode 100644 index 0000000..b73a503 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Wework +{ + public class WwUserExtuserDto + { + public string USERID { get; set; } + public string CORPID { get; set; } + public string Extuserid { get; set; } + public DateTime Ctime { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserIdDto.cs b/code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserIdDto.cs new file mode 100644 index 0000000..6fa7ac9 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Wework/WwUserExtuserIdDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Wework +{ + public class WwUserExtuserIdDto + { + public int Count { get; set; } + public string? USERID { get; set; } + public string? CORPID { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Wework/WwUserFollowDto.cs b/code/Zxd.Core.Domain/Dto/Wework/WwUserFollowDto.cs new file mode 100644 index 0000000..3301d1e --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Wework/WwUserFollowDto.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Wework +{ + public class WwUserFollowInDto + { + /// + /// 客服ID + /// + public string userid { get; set; } + /// + /// 客服公司ID + /// + public string appid { get; set; } + /// + /// 关联客户ID + /// + public string extuserid { get; set; } + } + public class WwUserFollowOutDto + { + /// + /// 客服ID + /// + public string userid { get; set; } + /// + /// 客服公司ID + /// + public string appid { get; set; } + /// + /// 关联客户ID + /// + public string extuserid { get; set; } + /// + /// 是否关注(是否仍为好友) + /// + public int isFollow { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/WxResource/ResourceConfigCreateDto.cs b/code/Zxd.Core.Domain/Dto/WxResource/ResourceConfigCreateDto.cs new file mode 100644 index 0000000..5571794 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/WxResource/ResourceConfigCreateDto.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.WxResource +{ + public class ResourceConfigCreateDto + { + public string appid { get; set; } + public int groupid { get; set; } + public int eid { get; set; } + public string? ename { get; set; } + public string? gname { get; set; } + public int flowCount { get; set; } + + public int deptId { get; set; } + public List FromUser { get; set; } + + public List ToUser { get; set; } + } + + public class FromUser + { + public int eid { get; set; } + public string? ename { get; set; } + public string? userid { get; set; } + } + + public class ToUser + { + public int eid { get; set; } + public string? ename { get; set; } + public string userid { get; set; } + public int flowCount { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/WxResource/SearchSourceTaskDto.cs b/code/Zxd.Core.Domain/Dto/WxResource/SearchSourceTaskDto.cs new file mode 100644 index 0000000..65a61ae --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/WxResource/SearchSourceTaskDto.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.WxResource +{ + public class SearchSourceTaskDto : SearchPageBase + { + public string? deptids { get; set; } + } + + public class SourceTaskModel + { + public int Id { get; set; } + + /// + /// 人群包id + /// + public int GroupId { get; set; } + + /// + /// 企微id + /// + public string? Appid { get; set; } + + /// + /// 操作人id + /// + public int Eid { get; set; } + + /// + /// 操作人 + /// + public string? Ename { get; set; } + + /// + /// 人群包名称 + /// + public string? GroupName { get; set; } + + public DateTime Ctime { get; set; } + public string? Date { get; set; } + + public DateTime Utime { get; set; } + + /// + /// 流转数量 + /// + public int FlowCount { get; set; } + + public int SuccessCount { get; set; } + + /// + /// 事业线ID + /// + public int? Deptid { get; set; } + } + + public class SearchFromDto + { + public int Id { get; set; } + } + + public class SearchToDto + { + public int Id { get; set; } + } + + public class ToUserTotalModel + { + public int FailCount { get; set; } + public List ToUserModel { get; set; } + } + + public class ToUserModel + { + /// + /// 人员id + /// + public int Eid { get; set; } + + /// + /// 人员名称 + /// + public string? Ename { get; set; } + + /// + /// 联系人 + /// + public string? Userid { get; set; } + + /// + /// 分配数量 + /// + public int FlowCount { get; set; } + + public int SuccessCount { get; set; } + public int NoneCount { get; set; } + public int ForbidCount { get; set; } + public int RefundCount { get; set; } + public int OtherCount { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/WxResource/UserGroupQueryDto.cs b/code/Zxd.Core.Domain/Dto/WxResource/UserGroupQueryDto.cs new file mode 100644 index 0000000..bd51ec4 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/WxResource/UserGroupQueryDto.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.WxResource +{ + public class UserGroupQueryDto + { + public string? deptid { get; set; } + public int? cateKey { get; set; } //类型 + public int? page { get; set; } + public int? limit { get; set; } + } + + /// + /// 人群包信息 + /// + public class UserGroupDto + { + /// + /// 人群包id + /// + public int Id { get; set; } + + /// + /// 名称 + /// + public string? Name { get; set; } + + /// + /// 描述 + /// + public string? Description { get; set; } + + /// + /// 共享范围 + /// 0:全局 + /// 1:部门 + /// 2:个人 + /// + public int? ShareWay { get; set; } + + /// + /// 用户数量 + /// + public int UserCount { get; set; } + + /// + /// 客户数量 + /// + public int CustomerCount { get; set; } + + public int? deptId { get; set; } + public string? catekeyName { get; set; } = "企微资源流转"; + } + + #region 查询资源数量 + + public class ResourceCountQueryDto + { + public string? groupids { get; set; } + public string userids { get; set; } + public string appid { get; set; } + public int page { get; set; } = 1; + public int limit { get; set; } = 100000; + + public int? status { get; set; } = 1; + + public int? subscribe { get; set; } = 1; + } + + public class ResourceCountReturnModel + { + public string? _nickname { get; set; } + public string? _appuserid { get; set; } + public string? _headimgurl { get; set; } + public string? _appid { get; set; } + } + + public class ResRelationModel + { + public string? _nickname { get; set; } + public string? _appuserid { get; set; } + public string? _headimgurl { get; set; } + public string? _appid { get; set; } + public string? _fromuserid { get; set; } + public bool _done { get; set; } + } + + public class ResourceCountPage + { + public long Total { get; set; } + public long UseCount { get; set; } + public List Data { get; set; } + public List UseData { get; set; } + public int RelationCount { get; set; } + public int DoneCount { get; set; } + public List ResRelationModel { get; set; } + public List DoneModel { get; set; } + } + + #endregion 查询资源数量 +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Zxd/Callback/BindOrderDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/Callback/BindOrderDto.cs new file mode 100644 index 0000000..aece696 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/Callback/BindOrderDto.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.Callback +{ + public class BindOrderDto + { + /// + /// 支付类型 wechat|wxWork|alipay + /// + [Required(ErrorMessage = "必填")] + public string payType { get; set; } + + /// + /// 交易流水号 + /// + [Required(ErrorMessage = "必填")] + public string tradeNo { get; set; } + + /// + /// 外部交易流水号 + /// + [Required(ErrorMessage = "必填")] + public string outTradeNo { get; set; } + + /// + /// 商户交易流水号 + /// + [Required(ErrorMessage = "必填")] + public string userTradeNo { get; set; } + + /// + /// 交易金额 + /// + [Required(ErrorMessage = "必填")] + public int? totalAmount { get; set; } + + /// + /// 交易状态 1|0 + /// + [Required(ErrorMessage = "必填")] + public int? tradeStatus { get; set; } + + /// + /// 交易时间 + /// + public string? payTime { get; set; } + + /// + /// UnionId + /// + [Required(ErrorMessage = "必填")] + public string unionId { get; set; } + + /// + /// 员工Id + /// + [Required(ErrorMessage = "必填")] + public int? eId { get; set; } + + /// + /// 渠道 + /// + [Required(ErrorMessage = "必填")] + public string channel { get; set; } + + /// + /// 身份密钥 + /// + public string identityKey { get; set; } + } + + public class OrderDepositDto + { + public long id { get; set; } + public string orderid { get; set; } + public string resid { get; set; } + public int paytype { get; set; } + public string paytypename { get; set; } + public DateTime? paydate { get; set; } + public decimal payprice { get; set; } + public string payname { get; set; } + public string remark { get; set; } + public string payno { get; set; } + public int isuse { get; set; } + public string companycode { get; set; } + public int? channel { get; set; } + public string tradeno { get; set; } + public int? creator { get; set; } + public string creatorname { get; set; } + /// + /// 部门编码 + /// + public string deptcode { get; set; } + + /// + /// 来源 + /// + public string source { get; set; } + + /// + /// 身份密钥 + /// + public string identityKey { get; set; } + } + + public class retMsg + { + public bool result { get; set; } + public int retcode { get; set; } + public string retmsg { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/CreateMeetingAccessoryDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/CreateMeetingAccessoryDto.cs new file mode 100644 index 0000000..ffa7c8c --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/CreateMeetingAccessoryDto.cs @@ -0,0 +1,31 @@ +using System; +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class CreateMeetingAccessoryDto + { + public CreateMeetingAccessoryDto() + { + } + + /// + /// 会议id + /// + public int MeetingId { get; set; } + + /// + /// 文件名称 + /// + public string FileName { get; set; } + + /// + /// 文件大小 + /// + public string FileSize { get; set; } + + /// + /// 文件地址 + /// + public string FileUrl { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditActiveDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditActiveDto.cs new file mode 100644 index 0000000..07b7f12 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditActiveDto.cs @@ -0,0 +1,39 @@ +using System; +namespace Zxd.Domain.Dto.Zxd +{ + public class CreateOrEditActiveDto + { + public CreateOrEditActiveDto() + { + } + + + public int? Id { get; set; } + + /// + /// 产品编码 + /// + public string? ProductCode { get; set; } + + /// + /// 事业部id + /// + public int Deptid { get; set; } + + /// + /// 赠送的产品编码 + /// + public string? ActiveCode { get; set; } + + /// + /// 是否跟随订单赠送,1:用订单表的giftdays字段作为赠送时长,0:用本表的donateday字段作为赠送时长 + /// + public int IsFollowOrder { get; set; } + + /// + /// [Order][HandGif] + /// + public string? GifType { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditMeetingDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditMeetingDto.cs new file mode 100644 index 0000000..b5bf9b6 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditMeetingDto.cs @@ -0,0 +1,52 @@ +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class CreateOrEditMeetingDto + { + public CreateOrEditMeetingDto() + { + } + + public int? Id { get; set; } + + /// + /// 会议名称 + /// + public string MeetingName { get; set; } + + /// + /// 会议类型 + /// + public int MeetingType { get; set; } + + /// + /// 开始时间 + /// + public DateTime BigenTime { get; set; } + + /// + /// 会议时长 + /// + public int ContinueHour { get; set; } + + /// + /// 会议时长 + /// + public int ContinueMinute { get; set; } + + /// + /// 会议地点 + /// + public string MeetingSite { get; set; } + + /// + /// 主讲人 + /// + public string Compere { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditProducGiftDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditProducGiftDto.cs new file mode 100644 index 0000000..c7d4955 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/CreateOrEditProducGiftDto.cs @@ -0,0 +1,38 @@ +using System; +namespace Zxd.Domain.Dto.Zxd +{ + public class CreateOrEditProducGiftDto + { + public CreateOrEditProducGiftDto() + { + } + + public int? Id { get; set; } + + /// + /// 赠送天数 + /// + public int GiftDays { get; set; } + + /// + /// 排序 + /// + public int Sort { get; set; } + + /// + /// 是否默认 + /// + public int IsDefault { get; set; } + + /// + /// 赠送产品名称 + /// + public string? GiftName { get; set; } + + /// + /// Activeid + /// + public int Activeid { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningDetailDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningDetailDto.cs new file mode 100644 index 0000000..fdd4328 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningDetailDto.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class EarlyWarningDetailDto + { + public EarlyWarningDetailDto() + { + EarlyWarningGroups = new List(); + EarlyWarningResources = new List(); + } + + /// + /// id + /// + public int Id { get; set; } + + /// + /// 工号 + /// + public int Eid { get; set; } + + /// + /// 姓名 + /// + public string? Name { get; set; } + + /// + /// 接粉周期 + /// + public string? Period + { + get { return $"{PeriodFrom:yyyy-MM-dd} ~ {PeriodTo:yyyy-MM-dd}"; } + } + + /// + /// 接粉周期 + /// + [JsonIgnore] + public DateTime? PeriodFrom { get; set; } + + /// + /// 接粉周期 + /// + [JsonIgnore] + public DateTime? PeriodTo { get; set; } + + /// + /// 达量时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 最大资源量 + /// + public int MaxResource { get; set; } + + /// + /// 预警值 + /// + public string? MaxCount { get; set; } + + /// + /// 去重加微数 + /// + public int Distinct { get; set; } + + /// + /// 状态 + /// + public string? Status { get; set; } + + /// + /// 所在组别 + /// + public List EarlyWarningGroups { get; set; } + + /// + /// 客服添加详情 + /// + public List EarlyWarningResources { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningGroupDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningGroupDto.cs new file mode 100644 index 0000000..48f44bb --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningGroupDto.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + /// + /// 所在组别 + /// + public class EarlyWarningGroupDto + { + /// + /// 所在组别 + /// + public string? Group { get; set; } + + /// + /// 分配类型 + /// + public string? Type { get; set; } + + /// + /// 企微账号 + /// + public string? Account { get; set; } + + /// + /// 添加资源数 + /// + public int Resource { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningLogDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningLogDto.cs new file mode 100644 index 0000000..2f00bdc --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningLogDto.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class EarlyWarningLogDto + { + public int Id { get; set; } + + /// + /// 工号 + /// + public int Eid { get; set; } + + /// + /// 姓名 + /// + public string? Name { get; set; } + + /// + /// 接粉周期 + /// + public string? Period + { + get { return $"{PeriodFrom:yyyy-MM-dd} ~ {PeriodTo:yyyy-MM-dd}"; } + } + + /// + /// 接粉周期 + /// + [JsonIgnore] + public DateTime? PeriodFrom { get; set; } + + /// + /// 接粉周期 + /// + [JsonIgnore] + public DateTime? PeriodTo { get; set; } + + /// + /// 达量时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 最大资源量 + /// + public int MaxResource { get; set; } + + /// + /// 预警值 + /// + public string? MaxCount { get; set; } + + /// + /// 去重加微数 + /// + public int Distinct { get; set; } + + /// + /// 状态 + /// + public string? Status { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningResourceDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningResourceDto.cs new file mode 100644 index 0000000..255708a --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/EarlyWarningResourceDto.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + /// + /// 客服添加详情 + /// + public class EarlyWarningResourceDto + { + /// + /// 资源id + /// + public string? Resid { get; set; } + + /// + /// 添加时间 + /// + public DateTime? CreateTime { get; set; } + + /// + /// 来源活动 + /// + public string? Activity { get; set; } + + /// + /// 所在组别 + /// + public string? Group { get; set; } + + /// + /// 分配类型 + /// + public string? Type { get; set; } + + /// + /// 企微账号 + /// + public string? Account { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/ExternalUserTotalDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/ExternalUserTotalDto.cs new file mode 100644 index 0000000..c54c803 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/ExternalUserTotalDto.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class ExternalUserTotalDto + { + /// + /// 员工工号 + /// + public int Eid { get; set; } + + /// + /// 总好友数 + /// + public int? Total { get; set; } + + /// + /// 新加微数 + /// + public int? Newsubscribe { get; set; } + + /// + /// 工号去重 + /// + public int? Eidrepeattypenew { get; set; } + + /// + /// 部门去重加微数 + /// + public int? Eidrepeattype1deptnew { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/InneruserDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/InneruserDto.cs new file mode 100644 index 0000000..32e4fbf --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/InneruserDto.cs @@ -0,0 +1,17 @@ +using System; +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class InneruserDto + { + public InneruserDto() + { + } + + public int Inneruserid { get; set; } + + public int Eid { get; set; } + + public string Username { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/MeetingAccessoryDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/MeetingAccessoryDto.cs new file mode 100644 index 0000000..17e195a --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/MeetingAccessoryDto.cs @@ -0,0 +1,68 @@ +using System; +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class MeetingAccessoryDto + { + public MeetingAccessoryDto() + { + Accessories = new List(); + } + + public int Id { get; set; } + + /// + /// 会议名称 + /// + public string? MeetingName { get; set; } + + /// + /// 会议类型 + /// + public string? MeetingType { get; set; } + + /// + /// 主讲人 + /// + public string? Compere { get; set; } + + /// + /// 附件列表 + /// + public List Accessories { get; set; } + } + + public class AccessoryDto + { + public AccessoryDto() + { + } + public int Id { get; set; } + + /// + /// 文件名称 + /// + public string? FileName { get; set; } + + /// + /// 文件大小 + /// + public string? FileSize { get; set; } + + /// + /// 文件地址 + /// + public string? FileUrl { get; set; } + + /// + /// 上传人 + /// + public string? Uploader { get; set; } + + /// + /// 上传时间 + /// + public DateTime UploadTime { get; set; } + } + +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/MeetingDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/MeetingDto.cs new file mode 100644 index 0000000..7370af1 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/MeetingDto.cs @@ -0,0 +1,63 @@ +using System; +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class MeetingDto + { + public MeetingDto() + { + } + + public int Id { get; set; } + + /// + /// 会议名称 + /// + public string? MeetingName { get; set; } + + /// + /// 会议类型 + /// + public string? MeetingType { get; set; } + + /// + /// 会议时间 + /// + public string? MeetingTime { get; set; } + + /// + /// 会议地点 + /// + public string? MeetingSite { get; set; } + + /// + /// 主讲人 + /// + public string? Compere { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 创建人 + /// + public string? CreateUser { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 更新人 + /// + public string? UpdateUser { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdateTime { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/MeetingParticipantDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/MeetingParticipantDto.cs new file mode 100644 index 0000000..915cc8e --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/MeetingParticipantDto.cs @@ -0,0 +1,19 @@ +using System; +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class MeetingParticipantDto + { + public MeetingParticipantDto() + { + } + + public int Id { get; set; } + + /// + /// 参与者 + /// + public string Participant { get; set; } + + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/Order/BindListDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/Order/BindListDto.cs new file mode 100644 index 0000000..9e47629 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/Order/BindListDto.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.Order +{ + public class BindListDto + { + public int? Id { get; set; } + + /// + /// 绑定状态 0=未绑定,1=自动绑定,2=手动绑定 + /// + public int? BindType { get; set; } + + /// + /// 支付类型 wechat|wxWork|alipay + /// + public string PayType { get; set; } + + /// + /// 客户Id + /// + public string ResId { get; set; } + + /// + /// 手机号 + /// + public string Phone { get; set; } + + /// + /// UnionId + /// + public string UnionId { get; set; } + + /// + /// 流水号 + /// + public string PayNo { get; set; } + + /// + /// 金额 + /// + public decimal? Amount { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } + + /// + /// 员工Id + /// + public int? EId { get; set; } + + /// + /// 支付时间 + /// + public DateTime? PayTime { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/Order/ImportGiftOrderDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/Order/ImportGiftOrderDto.cs new file mode 100644 index 0000000..71f3146 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/Order/ImportGiftOrderDto.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.Order +{ + public class ImportGiftOrderDto + { + public string? OrderId { get; set; } + + public string? ProductName { get; set; } + public string? ProductCode { get; set; } + public string? DeptName { get; set; } + public string? Day { get; set; } + } + + public class ImportGiftOrderViewModel + { + public string Umid { get; set; } + public string Name { get; set; } + public string UserName { get; set; } + public string? OrderId { get; set; } + + public string? ProductName { get; set; } + public string? ProductCode { get; set; } + public int? Day { get; set; } + public decimal? Channel { get; set; } + + /// + /// 是否能成功 + /// + public string Msg { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Zxd/Order/OrderChangeDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/Order/OrderChangeDto.cs new file mode 100644 index 0000000..10b7caf --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/Order/OrderChangeDto.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.Order +{ + public class OrderChangeDto + { + public decimal OrderId { get; set; } + public string? RESID { get; set; } + + public decimal? FINALPAY { get; set; } + + /// + /// 订单原价 + /// + public decimal? ORIGINPAY { get; set; } + + public decimal? NEEDPAY { get; set; } + public decimal? ARRIVALPAY { get; set; } + public long? SZZYORDERID { get; set; } + + /// + /// 订单状态:新订单180、已支付200、已开通220、已停用/已退款90、已过期80、已取消70,去掉"已支付200、暂缓开通210"状态 + /// + public string? ORDERSTATUS { get; set; } + + public string? ORDERSTATUSNAME { get; set; } + + /// + /// 事业部id + /// + public int? Deptid { get; set; } + + /// + /// 事业部id + /// + public string? DeptName { get; set; } + + /// + /// 群id + /// + public int? GroupId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Zxd/Order/ResPassTimeDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/Order/ResPassTimeDto.cs new file mode 100644 index 0000000..9f71e9f --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/Order/ResPassTimeDto.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.Order +{ + public class ResPassTimeDto + { + public string ResId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Zxd/Order/SearchBindListDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/Order/SearchBindListDto.cs new file mode 100644 index 0000000..9979983 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/Order/SearchBindListDto.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.Order +{ + public class SearchBindListDto : SearchPageBase + { + public int? Id { get; set; } + + public string? txt_companyId { get; set; } + + public string? txt_deptId { get; set; } + + public string? txt_groupIds { get; set; } + + public string? txt_userId { get; set; } + + /// + /// 绑定状态 0=未绑定,1=自动绑定,2=手动绑定 + /// + public int? BindType { get; set; } + + /// + /// 支付类型 wechat|wxWork|alipay + /// + public string? PayType { get; set; } + + /// + /// 客户Id + /// + public string? ResId { get; set; } + + /// + /// 手机号 + /// + public string? Phone { get; set; } + + /// + /// UnionId + /// + public string? UnionId { get; set; } + + /// + /// 流水号 + /// + public string? PayNo { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 员工Id + /// + public int? EId { get; set; } + + /// + /// 渠道Id + /// + public string? Channel { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/OrderDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/OrderDto.cs new file mode 100644 index 0000000..90778df --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/OrderDto.cs @@ -0,0 +1,121 @@ +using System; +namespace Zxd.Domain.Dto.Zxd +{ + public class OrderDto + { + public OrderDto() + { + } + + /// + /// 订单号 + /// + public int Orderid { get; set; } + + /// + /// 资源ID + /// + public string? Resid { get; set; } + + /// + /// 客户姓名 + /// + public string? ClientName { get; set; } + + /// + /// 成品产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 订单状态 + /// + public string? OrderStatus { get; set; } + + /// + /// 审核时间 + /// + public DateTime? AuditTime { get; set; } + + /// + /// 订单原价 + /// + public decimal? OriginPrice { get; set; } + + /// + /// 到账金额 + /// + public decimal? ArrivalAmount { get; set; } + + /// + /// 下单金额 + /// + public decimal? OrderAmount { get; set; } + + /// + /// 时长 + /// + public string? Day { get; set; } + + /// + /// 下单时间 + /// + public DateTime? OrderTime { get; set; } + + /// + /// 升级订单 + /// + public string? UpgradeOrder { get; set; } + + /// + /// 小类 + /// + public string? Type { get; set; } + + /// + /// 事业部 + /// + public string? Department { get; set; } + + /// + /// 赠送 + /// + public string? Give { get; set; } + + /// + /// 软件用户名 + /// + public string? SoftUserName { get; set; } + + /// + /// 权限单号 + /// + public string? ModuleOrder { get; set; } + + /// + /// 产品编号 + /// + public string? ProductCode { get; set; } + + /// + /// 合同编号 + /// + public string? ContractNo { get; set; } + + /// + /// 回访录音 + /// + public string? Hashgrecord { get; set; } + + /// + /// 录音 + /// + public string? Call { get; set; } + + /// + /// 聊天记录 + /// + public string? ChattingRecords { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/ProductActiveDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/ProductActiveDto.cs new file mode 100644 index 0000000..db88d85 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/ProductActiveDto.cs @@ -0,0 +1,37 @@ +using System; +namespace Zxd.Domain.Dto.Zxd +{ + public class ProductActiveDto + { + public ProductActiveDto() + { + } + public int Id { get; set; } + + /// + /// 赠送类型 + /// + public string? Name { get; set; } + + public string? GiftType { get; set; } + + public string? Giftype { get; set; } + + public int? Deptid { get; set; } + + /// + /// 活动产品ID + /// + public string? ActiveCode { get; set; } + + public int ActiveType { get; set; } + + /// + /// 是否跟随订单赠送,1:用订单表的giftdays字段作为赠送时长,0:用本表的donateday字段作为赠送时长 + /// + public int IsFollowOrder { get; set; } + + public List? GiftList { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/QwWeiSide/SearchOrderDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/QwWeiSide/SearchOrderDto.cs new file mode 100644 index 0000000..8caae05 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/QwWeiSide/SearchOrderDto.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd.QwWeiSide +{ + public class SearchSideOrderDto + { + public string? AppId { get; set; } + public string? AppUserId { get; set; } + public int? Eid { get; set; } + } + + public class SideOrderModel + { + public int? OrderId { get; set; } + public string? SzzyOrderId { get; set; } + public string? ProductName { get; set; } + public string? ProductCode { get; set; } + public int? Opendays { get; set; } + public int? Giftdays { get; set; } + public DateTime? Ctime { get; set; } + public DateTime? Otime { get; set; } + public string? OrderStatus { get; set; } + public string? OrderStatusName { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Dto/Zxd/SearchEarlyWarningLogDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/SearchEarlyWarningLogDto.cs new file mode 100644 index 0000000..73102e6 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/SearchEarlyWarningLogDto.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class SearchEarlyWarningLogDto : SearchPageBase + { + /// + /// 达量日期 + /// + public DateTime? AttainTimeFrom { get; set; } + + /// + /// 达量日期 + /// + public DateTime? AttainTimeTo { get; set; } + + /// + /// 工号 + /// + public int? Eid { get; set; } + + /// + /// 姓名 + /// + public string? Name { get; set; } + + /// + /// 状态 + /// + public EarlyWaningLogStatus? Status { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/SearchExternalUserTotalDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/SearchExternalUserTotalDto.cs new file mode 100644 index 0000000..f298214 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/SearchExternalUserTotalDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class SearchExternalUserTotalDto + { + /// + /// 查询日期 + /// + public string? DateFrom { get; set; } + + /// + /// 查询日期 + /// + public string? DateTo { get; set; } + + /// + /// 工号 + /// + public List? Eids { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/Zxd/SearchMeetingDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/SearchMeetingDto.cs new file mode 100644 index 0000000..982a14a --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/SearchMeetingDto.cs @@ -0,0 +1,56 @@ +using System; +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class SearchMeetingDto : SearchPageBase + { + public SearchMeetingDto() + { + } + + /// + /// 会议名称 + /// + public string? MeetingName { get; set; } + + /// + /// 会议类型 + /// + public int? MeetingType { get; set; } + + /// + /// 主讲人 + /// + public string? Compere { get; set; } + + /// + /// 参与人 + /// + public string? Paricipant { get; set; } + + /// + /// 创建人 + /// + public string? CreateUser { get; set; } + + /// + /// 会议日期 + /// + public DateTime? MeetingDateForm { get; set; } + + /// + /// 会议日期 + /// + public DateTime? MeetingDateTo { get; set; } + + /// + /// 创建时间 + /// + public DateTime? CreateTimeForm { get; set; } + + /// + /// 创建时间 + /// + public DateTime? CreateTimeTo { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/SearchOrderDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/SearchOrderDto.cs new file mode 100644 index 0000000..5fd8a0b --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/SearchOrderDto.cs @@ -0,0 +1,126 @@ +using System; +namespace Zxd.Domain.Dto.Zxd +{ + public class SearchOrderDto : SearchPageBase + { + public SearchOrderDto() + { + } + + /// + /// + /// + public long? Orderid { get; set; } + + /// + /// 手机号 + /// + public string? Phone { get; set; } + + /// + /// 资源id + /// + public string? Resid { get; set; } + + /// + /// 客户姓名 + /// + public string? ClientName { get; set; } + + /// + /// 软件用户名 + /// + public string? SoftUserName { get; set; } + + /// + /// 订单状态 + /// + public string? OrderStatus { get; set; } + + /// + /// 合规审核 + /// + public int? RiskctrlStatus { get; set; } + + /// + /// 事业部id + /// + public int? Deptid { get; set; } + + /// + /// 系列 + /// + public int? ProductSeriesId { get; set; } + + /// + /// 产品大类 + /// + public int? ProductCategoryId { get; set; } + + /// + /// 产品小类 + /// + public int? ProductTypeId { get; set; } + + /// + /// 活动 + /// + public int? Activity { get; set; } + + /// + /// 产品名称 + /// + public string? ProductName { get; set; } + + /// + /// 权限单号 + /// + public long? SzzyOrderid { get; set; } + + /// + /// 下单金额 + /// + public decimal? OrderAmountMax { get; set; } + + /// + /// 下单时间 + /// + public DateTime? OrderTimeFrom { get; set; } + + /// + /// 下单时间 + /// + public DateTime? OrderTimeTo { get; set; } + + /// + /// 到账日期 + /// + public DateTime? AccountingDateFrom { get; set; } + + /// + /// 到账日期 + /// + public DateTime? AccountingDateTo { get; set; } + + /// + /// 开通日期 + /// + public DateTime? OpenDateFrom { get; set; } + + /// + /// 开通日期 + /// + public DateTime? OpenDateTo { get; set; } + + /// + /// 包含未开通 + /// + public bool IncludeNotOpen { get; set; } + + /// + /// 产品编码 + /// + public string? ProductCode { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/SubProductGiftDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/SubProductGiftDto.cs new file mode 100644 index 0000000..a1bfe4a --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/SubProductGiftDto.cs @@ -0,0 +1,49 @@ +using System; +namespace Zxd.Domain.Dto.Zxd +{ + public class SubProductGiftDto + { + public SubProductGiftDto() + { + } + + public int Id { get; set; } + /// + /// 成品产品ID + /// + public int SubProductId { get; set; } + /// + /// 产品名称 + /// + public string? SubProductName { get; set; } + /// + /// 天数 + /// + public int GiftDays { get; set; } + /// + /// 显示名称 + /// + public string? GiftDaysName { get; set; } + /// + /// 排序 + /// + public int Sort { get; set; } + /// + /// 默认选中 + /// + public int IsDefault { get; set; } + /// + /// 类型 + /// + public int Type { get; set; } + /// + /// 赠送产品名称 + /// + public string? GiftName { get; set; } + /// + /// 外键,赠送ID + /// + public int Activeid { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Dto/Zxd/UpdateEarlyWarningStatusDto.cs b/code/Zxd.Core.Domain/Dto/Zxd/UpdateEarlyWarningStatusDto.cs new file mode 100644 index 0000000..94bd59e --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/Zxd/UpdateEarlyWarningStatusDto.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Dto.Zxd +{ + public class UpdateEarlyWarningStatusDto + { + public int Id { get; set; } + + /// + /// 状态 + /// + public EarlyWaningLogStatus? Status { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Dto/retMsg.cs b/code/Zxd.Core.Domain/Dto/retMsg.cs new file mode 100644 index 0000000..9d15bf7 --- /dev/null +++ b/code/Zxd.Core.Domain/Dto/retMsg.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain +{ + public class retMsg + { + public bool result { get; set; } + public int retcode { get; set; } + public string retmsg { get; set; } + } + + public class retMsg + { + public bool result { get; set; } + public int retcode { get; set; } + public T retmsg { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/EarlyWarningDomain.cs b/code/Zxd.Core.Domain/EarlyWarningDomain.cs new file mode 100644 index 0000000..eaacddc --- /dev/null +++ b/code/Zxd.Core.Domain/EarlyWarningDomain.cs @@ -0,0 +1,461 @@ +using Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using Zxd.Core.Domain.Dto.Crm; +using Zxd.Core.Domain.Dto.Wework; +using Zxd.Entity.Wework; +using Zxd.Entity.Zxd; + +namespace Zxd.Core.Domain +{ + internal class EarlyWarningDomain : IEarlyWarningDomain + { + private readonly IConfiguration _configuration; + private readonly IHttpClient _httpClient; + private readonly ICacheDomain _cacheDomain; + private readonly SystemConfig _systemConfig; + private readonly IBaseRepository _zxdRepository; + private readonly IBaseRepository _dncmsRepository; + private readonly IRedisManager _redisManager; + + public EarlyWarningDomain(IConfiguration configuration, + IHttpClient httpClient, + ICacheDomain cacheDomain, + IBaseRepository zxdRepository, + IBaseRepository dncmsRepository, + IRedisManager redisManager) + { + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _configuration = configuration; + _httpClient = httpClient; + _cacheDomain = cacheDomain; + _zxdRepository = zxdRepository; + _dncmsRepository = dncmsRepository; + _redisManager = redisManager; + } + + public async Task> GetEarlyWarningLogPage(SearchEarlyWarningLogDto dto, string? sgin) + { + if (string.IsNullOrEmpty(sgin)) throw new ApiException("签名不能为空!"); + + if (!await _redisManager.ExistsAsync(sgin)) + { + throw new ApiException("签名已过期!"); + } + var deptidValue = await _redisManager.GetAsync(sgin); + if (string.IsNullOrEmpty(deptidValue) || !int.TryParse(deptidValue, out int deptid)) + { + throw new ApiException("签名已过期!"); + } + var query = _zxdRepository.GetRepository().Query() + .Where(x => x.Deptid == deptid) + .If(dto.AttainTimeFrom != null, x => x.Where(x => x.CreateTime >= dto.AttainTimeFrom)) + .If(dto.AttainTimeTo != null, x => x.Where(x => x.CreateTime < dto.AttainTimeTo.Value.AddDays(1))) + .If(dto.Eid != null, x => x.Where(x => x.Eid == dto.Eid)) + .If(!string.IsNullOrEmpty(dto.Name), x => x.Where(x => x.Name.Contains(dto.Name))) + .If(dto.Status != null, x => x.Where(x => x.Status == dto.Status)); + + var total = await query.CountAsync(); + var data = await query + .OrderByDescending(x => x.CreateTime) + .Select(x => new EarlyWarningLogDto + { + Id = x.Id, + Distinct = x.Distinct, + CreateTime = x.CreateTime, + Eid = x.Eid, + MaxCount = x.Type == EarlyWarningType.百分比 ? $"到达{x.EarlyWarning}%" + : $"到达{x.EarlyWarning}人", + MaxResource = x.Resource, + Name = x.Name, + PeriodFrom = x.PeriodFrom, + PeriodTo = x.PeriodTo, + Status = x.Status.GetDescription() + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + public async Task GetEarlyWarningDetail(int id) + { + var detail = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == id) + .Select(x => new EarlyWarningDetailDto + { + Id = x.Id, + Distinct = x.Distinct, + CreateTime = x.CreateTime, + Eid = x.Eid, + MaxCount = x.Type == EarlyWarningType.百分比 ? $"到达{x.EarlyWarning}%" + : $"到达{x.EarlyWarning}人", + MaxResource = x.Resource, + Name = x.Name, + PeriodFrom = x.PeriodFrom, + PeriodTo = x.PeriodTo, + Status = x.Status.GetDescription() + }) + .FirstOrDefaultAsync(); + + + return new EarlyWarningDetailDto(); + } + + public async Task UpdateEarlyWarningStatus(UpdateEarlyWarningStatusDto dto) + { + var data = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == dto.Id) + .FirstOrDefaultAsync(); + if (data == null) + { + throw new ApiException("数据不存在或已删除!"); + } + if (!dto.Status.HasValue) + { + throw new ApiException("请选择更变状态!"); + } + data.Status = dto.Status.Value; + await _zxdRepository.GetRepository().UpdateAsync(data); + } + + public async Task EarlyWarningSync() + { + var time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")); + var stime = time; + var etime = time.AddDays(1).AddSeconds(-1); + + var settings = await _zxdRepository.GetRepository().Query() + .Include(x => x.EarlyWarningTemplate) + .ToListAsync(); + var users = await _zxdRepository.GetRepository().Query() + .ToListAsync(); + var settingEids = settings.Select(x => x.Eid).Distinct().ToList(); + //var totals = await _dncmsRepository.GetRepository().Query() + // .Where(x => settingEids.Contains(x.Eid)) + // .ToListAsync(); + var result = false; + var logs = new List(); + //var wwHhuserEids = new List(); + //foreach (var deptid in settings.Select(x => x.Deptid).Distinct()) + //{ + // var deptSettings = settings.Where(x => x.Deptid == deptid).Select(x => x.Eid).ToList(); + // var size = 30; + // var maxIndex = (deptSettings.Count / size) + 1; + // for (var page = 0; page < maxIndex; page++) + // { + // var url = $"{_systemConfig.CrmCoreUrl}api/Customer/WwHhuserEids?deptid={deptid}"; + // var crmData = await _httpClient.PostAsync>>(url, deptSettings.Skip(page * size).Take(size).ToList()); + // if (crmData.Code == 0) + // { + // wwHhuserEids.AddRange(crmData.Data); + // } + // } + //} + + //var sql = $@"select * from ww_user_extuser where CONCAT(corpid,userid) + // in ('{string.Join("','", wwHhuserEids.Select(m => m.CORPID + m.USERID))}')"; + + //var extuserList = await _weworkRepository.ExecuteSqlToListAsync(sql); + + foreach (var setting in settings) + { + var messages = new List(); + var url = ""; + var template = setting.EarlyWarningTemplate ?? new EarlyWarningTemplate(); + if (template.Id < 1) + { + continue; + } + var max = template.Maxnum; + // 判断是否接粉周期 + if (time < template.PeriodFrom || time > template.PeriodTo.AddDays(1).AddSeconds(-1)) + { + continue; + } + int? total = 0; + // 在东三等其他坐席,以加微数(部门去重)作为达量通知的标准。六合的坐席,以加微数(工号去重)作为达量通知的标准 + if (new int[] { 27, 32, 33, 40 }.Contains(setting.Deptid)) + { + total = await _dncmsRepository.GetRepository().Query() + .Where(x => x.Eid == setting.Eid && x.Ctime >= template.PeriodFrom && x.Ctime <= template.PeriodTo.AddDays(1).AddSeconds(-1)).SumAsync(x => x.Eidrepeattypenew); + } + else + { + total = await _dncmsRepository.GetRepository().Query() + .Where(x => x.Eid == setting.Eid && x.Ctime >= template.PeriodFrom && x.Ctime <= template.PeriodTo.AddDays(1).AddSeconds(-1)).SumAsync(x => x.Eidrepeattype1deptnew); + } + //var total = GetTotalByEid(extuserList, wwHhuserEids, template.PeriodFrom, template.PeriodTo, setting.Eid); + if (total == 0 || !total.HasValue) continue; + var index = 0; + if (total >= max) + { + var templateIndex = max.ToString(); + if (await _zxdRepository.GetRepository().Query().AnyAsync(x => x.Eid == setting.Eid && x.TemplateId == setting.TemplateId && x.TemplateIndex == templateIndex)) + { + continue; + } + url = await GetCrmUrl(setting.Deptid, setting.Eid); + messages.Add(new MessageInfo { Eid = setting.Eid, Message = $"客服{setting.Eid}({setting.Name})已达量100%,点击查看添加详情:{url}" }); + logs.Add(new EarlyWarningLog + { + Distinct = total.Value, + CreateTime = DateTime.Now, + EarlyWarning = 100, + Eid = setting.Eid, + Name = setting.Name, + PeriodFrom = template.PeriodFrom, + PeriodTo = template.PeriodTo, + Resource = max, + Status = EarlyWaningLogStatus.未处理, + Type = EarlyWarningType.百分比, + TemplateId = setting.TemplateId, + TemplateIndex = templateIndex, + Deptid = setting.Deptid, + }); + } + var isPercent = false; + foreach (var prewarning in template.PrewarningValueJson) + { + if (string.IsNullOrEmpty(prewarning.Guid)) continue; + if (prewarning.Type == EarlyWarningType.百分比) + { + result = total >= max * ((decimal)prewarning.Value / 100); + var percent = (decimal)total / max * 100; + if (result) + { + if (await _zxdRepository.GetRepository().Query().AnyAsync(x => x.Eid == setting.Eid && x.TemplateId == setting.TemplateId && x.TemplateIndex == prewarning.Guid && x.Resource >= max)) + { + continue; + } + url = await GetCrmUrl(setting.Deptid, setting.Eid); + messages.Add(new MessageInfo { Eid = setting.Eid, Message = $"客服{setting.Eid}({setting.Name})已达量{percent:0.0}%,点击查看添加详情:{url}" }); + logs.Add(new EarlyWarningLog + { + Distinct = total.Value, + CreateTime = DateTime.Now, + EarlyWarning = prewarning.Value, + Eid = setting.Eid, + Name = setting.Name, + PeriodFrom = template.PeriodFrom, + PeriodTo = template.PeriodTo, + Resource = max, + Status = EarlyWaningLogStatus.未处理, + Type = EarlyWarningType.百分比, + TemplateId = setting.TemplateId, + TemplateIndex = prewarning.Guid, + Deptid = setting.Deptid, + }); + isPercent = true; + continue; + } + } + else + { + result = total >= prewarning.Value; + if (result) + { + if (await _zxdRepository.GetRepository().Query().AnyAsync(x => x.Eid == setting.Eid && x.TemplateId == setting.TemplateId && x.TemplateIndex == prewarning.Guid)) + { + continue; + } + url = await GetCrmUrl(setting.Deptid, setting.Eid); + messages.Add(new MessageInfo { Eid = setting.Eid, Message = $"客服{setting.Eid}({setting.Name})已达量{total}人,点击查看添加详情:{url}" }); + logs.Add(new EarlyWarningLog + { + Distinct = total.Value, + CreateTime = DateTime.Now, + EarlyWarning = prewarning.Value, + Eid = setting.Eid, + Name = setting.Name, + PeriodFrom = template.PeriodFrom, + PeriodTo = template.PeriodTo, + Resource = max, + Status = EarlyWaningLogStatus.未处理, + Type = EarlyWarningType.数量, + TemplateId = setting.TemplateId, + TemplateIndex = prewarning.Guid, + Deptid = setting.Deptid, + }); + continue; + } + } + index++; + } + foreach (var message in messages) + { + foreach (var user in users.Where(x => x.ParticipantIds.Contains(message.Eid))) + { + try + { + await WeworkSend(user.WxWorkId, user.CropId, user.AppId, message.Message); + } + catch + { + + } + } + } + if (setting.HasChangeNum == 1 && isPercent) + { + setting.HasChangeNum = 0; + await _zxdRepository.GetRepository().UpdateAsync(setting); + } + } + if (logs.Any()) + { + await _zxdRepository.GetRepository().BatchInsertAsync(logs); + } + } + + /// + /// 获取去重加微数 + /// + /// + /// + /// + /// + /// + /// + private int GetTotalByEid(List extuserList, List wwHhuserEids, DateTime stime, DateTime etime, int eid) + { + var trueExtuser = new List(); + + //去重 + var extuser_gup_dis = extuserList.GroupBy(m => m.Extuserid); + foreach (var item in extuser_gup_dis) + { + var first = item.ToList().OrderBy(m => m.Ctime).First();//获取最早添加好友的记录 + trueExtuser.Add(first); + } + + //统计 时间范围内 去重后加微数 + var extuserDis = trueExtuser + .Where(m => m.Ctime >= stime && m.Ctime <= etime.AddDays(1).AddSeconds(-1))//时间筛选 + .GroupBy(m => m.CORPID + m.USERID).Select(i => + new WwUserExtuserIdDto() + { + CORPID = i.First().CORPID, + USERID = i.First().USERID, + Count = i.Count() + }).ToList(); + + //匹配eid + var gupDis = wwHhuserEids.Join(extuserDis, m => m.CORPID + m.USERID, n => n.CORPID + n.USERID, (m, n) => + { + return new + { + eid = m.EID, + count = n.Count + }; + }).GroupBy(m => m.eid).ToDictionary(m => m.Key.ToString(), n => n.Sum(i => i.count)); + + if (!gupDis.TryGetValue(eid.ToString(), out int total)) + { + return 0; + } + return total; + } + + private async Task GetCrmUrl(int deptid, int eid) + { + var app = _systemConfig.Apps.Where(x => x.Deptids.Contains(deptid)).FirstOrDefault(); + var sgin = ResUtil.EncryptMD5($"{deptid}_{eid}"); + await _redisManager.SetAsync(sgin, deptid.ToString(), TimeSpan.FromDays(7)); + return $"{app?.CrmUrl}MessageCenter/EarlyWarning?sgin={sgin}&createTime={DateTime.Now:yyyy-MM-dd}&eid={eid}"; + } + + /// + /// 推送企微消息 + /// + /// + /// + /// + /// + /// + public async Task WeworkSend(string? wxworkid, string? corpid, string? appid, string? message) + { + if(string.IsNullOrEmpty(wxworkid) || string.IsNullOrEmpty(corpid) || string.IsNullOrEmpty(appid) || string.IsNullOrEmpty(message)) + { + Log.Error($"推送企微消息参数不能为空!"); + return; + } + var clientid = "UPWEBSITE"; + var param = new + { + Account = "dn.uc", + Password = "dn.uc.password", + Time = SignHelper.GetTimeStamp() + }; + + var content = JsonSerializer.Serialize(new + { + msgtype = "text", + text = new + { + content = message + }, + agentid = appid, + toparty = "", + totag = "", + touser = wxworkid, + safe = 0 + }); + var data = new + { + appid = corpid, + agentid = appid, + data = content + }; + var response = await _httpClient.PostSecurityAsync>(_systemConfig.WeworkSendUrl, param, data, clientid, _systemConfig.GetAccessKey(clientid)); + if (response.ErrCode != 0) + { + Log.Error($"请求企微推送消息接口报错:{response.RrrMessage}, ex:{JsonSerializer.Serialize(response)}"); + } + + } + + public async Task> GetExternalUserTotal(SearchExternalUserTotalDto dto) + { + if(string.IsNullOrEmpty(dto.DateFrom) || !DateTime.TryParse(dto.DateFrom, out DateTime dateFrom)) + { + throw new ApiException("请输入查询日期!"); + } + if (string.IsNullOrEmpty(dto.DateTo) || !DateTime.TryParse(dto.DateTo, out DateTime dateTo)) + { + throw new ApiException("请输入查询日期!"); + } + if (dto.Eids == null || !dto.Eids.Any()) + { + throw new ApiException("请输入员工工号!"); + } + var data = await _dncmsRepository.GetRepository().Query() + .Where(x => dto.Eids.Contains(x.Eid) && x.Ctime >= dateFrom && x.Ctime <= dateTo.AddDays(1).AddSeconds(-1)) + .GroupBy(x => new + { + x.Eid + }) + .Select(x => new ExternalUserTotalDto + { + Eid = x.Key.Eid, + Eidrepeattype1deptnew = x.Sum(y => y.Eidrepeattype1deptnew), + Newsubscribe = x.Sum(y => y.Newsubscribe), + Total = x.Sum(y => y.Total), + Eidrepeattypenew = x.Sum(y => y.Eidrepeattypenew) + }).ToListAsync(); + return data; + } + + class MessageInfo + { + public int Eid { get; set; } + + public string? Message { get; set; } + } + } +} diff --git a/code/Zxd.Core.Domain/FinishedProductDomain.cs b/code/Zxd.Core.Domain/FinishedProductDomain.cs new file mode 100644 index 0000000..3ececc6 --- /dev/null +++ b/code/Zxd.Core.Domain/FinishedProductDomain.cs @@ -0,0 +1,634 @@ +using System; +using Microsoft.Extensions.Configuration; +using Zxd.Core.Domain.Dto; +using Zxd.Core.Domain.Response; +using Zxd.Domain.Impl; +using Zxd.Entity.Crm; + +namespace Zxd.Domain +{ + /// + /// 成品产品 + /// + public class FinishedProductDomain : IFinishedProductDomain + { + private readonly IBaseRepository _crmRepository; + private readonly IBaseRepository _zxdRepository; + private readonly IRedisManager _redisManager; + private readonly IConfiguration _configuration; + private readonly IDeptmentDomain _deptmentDomain; + private readonly IHttpClient _httpClient; + private readonly IMapper _mapper; + private readonly SystemConfig _systemConfig; + + public FinishedProductDomain(IBaseRepository crmRepository, + IBaseRepository zxdRepository, + IRedisManager redisManager, + IConfiguration configuration, + IDeptmentDomain deptmentDomain, + IMapper mapper, + IHttpClient httpClient) + { + _crmRepository = crmRepository; + _zxdRepository = zxdRepository; + _redisManager = redisManager; + _deptmentDomain = deptmentDomain; + _mapper = mapper; + _httpClient = httpClient; + _configuration = configuration; + _systemConfig = _configuration.GetSection("SystemConfig").Get(); + } + + private async Task> GetProductTypeList() + { + var key = CacheKeys.ProductTypeList; + var data = new List(); + if (!await _redisManager.ExistsAsync(key)) + { + data = await _zxdRepository.GetRepository().QueryListAsync(); + await _redisManager.SetAsync(key, data, TimeSpan.FromHours(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + } + + return data; + } + + public async Task> GetProductSeriesSelect() + { + var list = await GetProductTypeList(); + var data = new List(); + list = list.Where(x => x.Level == 1).ToList(); + foreach (var item in list) + { + data.Add(new SelectItem(item.ProductId, item.ProductName ?? "")); + } + return data; + } + + public async Task> GetProductCategorySelect(int? productSeriesId) + { + var list = await GetProductTypeList(); + var data = new List(); + list = list.Where(x => x.Level == 2).If(productSeriesId != null, x => x.Where(x => x.Parentid == productSeriesId)).ToList(); + foreach (var item in list) + { + data.Add(new SelectItem(item.ProductId, item.ProductName ?? "")); + } + return data; + } + + /// + /// 成品产品明细 + /// + /// + /// + /// + public async Task GetFinishedProductDetail(int productid) + { + var finishProductDetail = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == productid) + .Select(x => new FinishedProductDetailDto + { + Id = x.Id, + StandardProductId = x.StandardProductId, + ProductSeriesId = x.ProductSeriesId, + ProductCategoryId = x.ProductCategoryId, + Day = x.Day, + Deptid = x.Deptid, + Discount = x.Discount, + AutoOpen = x.AutoOpen, + BuyOnline = x.BuyOnline, + Coefficient = x.Coefficient, + Custom = x.Custom, + Give = x.Give, + OpenCondition = x.OpenCondition, + OtherClassify = x.OtherClassify, + ProductCode = x.ProductCode, + ProductName = x.ProductName, + ProductPrice = x.ProducPrice, + ProductServerType = x.ProductServerType, + Remark = x.Remark, + Upgrade = x.Upgrade, + Status = x.Status, + DiscounSections = x.DiscounSections, + GiveProducts = x.GiveProducts, + CustomPrices = x.CustomPrices + }) + .FirstOrDefaultAsync(); + + if (finishProductDetail == null) + { + throw new ApiException("成品产品不存在或已删除!"); + } + + var standardProduct = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == finishProductDetail.StandardProductId) + .FirstOrDefaultAsync(); + if (standardProduct == null) + { + throw new ApiException("基准产品不存在或已删除!"); + } + var productTypeList = await GetProductTypeList(); + finishProductDetail.ProductSeries = productTypeList.Where(x => x.ProductId == finishProductDetail.ProductSeriesId).Select(x => x.ProductName).FirstOrDefault(); + finishProductDetail.ProductCategory = productTypeList.Where(x => x.ProductId == finishProductDetail.ProductCategoryId).Select(x => x.ProductName).FirstOrDefault(); + var deptments = await _deptmentDomain.GetDeptments(); + finishProductDetail.Department = deptments.First(y => y.Id == finishProductDetail.Deptid).Title; + if (!string.IsNullOrEmpty(standardProduct.ProductCode)) + { + var baseProduct = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Code == standardProduct.ProductCode); + finishProductDetail.StandardProductDay = baseProduct.Day.ToString(); + finishProductDetail.StandardProductName = baseProduct.Name; + finishProductDetail.StandardProductPrice = (decimal)baseProduct.Price; + finishProductDetail.StandardProductType = standardProduct.StandardType.GetDescription(); + finishProductDetail.StandardProductModules = new List { $"{baseProduct.Name}【{baseProduct.Moduleid}】【{baseProduct.Day}】" }; + } + if (!string.IsNullOrEmpty(standardProduct.ProductPackageCode)) + { + var baseProductPackage = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Code == standardProduct.ProductPackageCode); + finishProductDetail.StandardProductDay = string.Join("/", baseProductPackage.BaseProductPackageRelations.Select(x => x.Day).ToList()); + finishProductDetail.StandardProductName = baseProductPackage.Name; + finishProductDetail.StandardProductPrice = (decimal)baseProductPackage.Price; + finishProductDetail.StandardProductType = standardProduct.StandardType.GetDescription(); + finishProductDetail.StandardProductModules = baseProductPackage.BaseProductPackageRelations.Select(x => $"{x.ProductName}【{x.Moduleid}】【{x.Day}】").ToList(); + } + + return finishProductDetail; + } + + /// + /// 基准产品信息 + /// + /// + /// + /// + public async Task GetStandardProduct(int productid) + { + var standardProduct = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == productid) + .FirstOrDefaultAsync(); + if (standardProduct == null) + { + throw new ApiException("基准产品不存在或已删除!"); + } + if (!string.IsNullOrEmpty(standardProduct.ProductCode)) + { + var baseProduct = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Code == standardProduct.ProductCode); + return new StandardProductInfoDto + { + Price = $"{baseProduct.Price:0.00}", + Day = baseProduct.Day.ToString(), + ProductName = baseProduct.Name, + ProductCode = baseProduct.Code, + ProductType = standardProduct.StandardType.GetDescription(), + Module = new List { $"{baseProduct.Name}【{baseProduct.Moduleid}】【{baseProduct.Day}】" } + }; + } + if (!string.IsNullOrEmpty(standardProduct.ProductPackageCode)) + { + var baseProductPackage = await _zxdRepository.GetRepository().Query().Include(x => x.BaseProductPackageRelations) + .FirstOrDefaultAsync(x => x.Code == standardProduct.ProductPackageCode); + return new StandardProductInfoDto + { + Price = $"{baseProductPackage.Price:0.00}", + Day = string.Join("/", baseProductPackage.BaseProductPackageRelations.Select(x => x.Day).ToList()), + ProductName = baseProductPackage.Name, + ProductCode = baseProductPackage.Code, + ProductType = standardProduct.StandardType.GetDescription(), + Module = baseProductPackage.BaseProductPackageRelations.Select(x => $"{x.ProductName}【{x.Moduleid}】【{x.Day}】").ToList() + }; + + } + return new StandardProductInfoDto(); + } + + /// + /// 修改成品产品 + /// + /// + /// + /// + public async Task EditFinishedProduct(EditFinishedProductDto dto) + { + var finishedProduct = await _zxdRepository.GetRepository().Query() + .Include(x => x.StandardProduct) + .FirstOrDefaultAsync(x => x.Id == dto.Id); + + if (finishedProduct == null) + { + throw new ApiException("成品产品不存在或已删除!"); + } + //finishedProduct.ProductTypeId = dto.ProductTypeId; + finishedProduct.ProductCategoryId = dto.ProductCategoryId; + finishedProduct.ProductSeriesId = dto.ProductSeriesId; + finishedProduct.ProductServerType = dto.ProductServerType; + finishedProduct.AutoOpen = dto.AutoOpen; + finishedProduct.BuyOnline = dto.BuyOnline; + finishedProduct.Custom = dto.Custom; + finishedProduct.Give = dto.Give; + finishedProduct.Discount = dto.Discount; + finishedProduct.OpenCondition = dto.OpenCondition; + finishedProduct.OtherClassify = dto.OtherClassify; + finishedProduct.Remark = dto.Remark; + finishedProduct.Status = dto.Status; + finishedProduct.Upgrade = dto.Upgrade; + finishedProduct.CustomPrices = dto.CustomPrices; + finishedProduct.DiscounSections = dto.DiscounSections; + finishedProduct.GiveProducts = dto.GiveProducts; + + var productCode = !string.IsNullOrEmpty(finishedProduct.StandardProduct.ProductCode) ? + finishedProduct.StandardProduct.ProductCode : finishedProduct.StandardProduct.ProductPackageCode; + var addVirtualProduct = new AddVirtualProductDto + { + OutProductCode = productCode, + Day = finishedProduct.Day, + Price = finishedProduct.ProducPrice, + Num = finishedProduct.Coefficient, + ProductName = finishedProduct.ProductName, + BasicPorductCode = productCode, + ProductCode = finishedProduct.ProductCode + }; + if (!string.IsNullOrEmpty(finishedProduct.StandardProduct.ProductCode)) + { + var result = await _httpClient.PostAsync(_systemConfig.GetAddVirtualProduct(), addVirtualProduct); + if (result.Result) + { + finishedProduct.ProductCode = result.ProductCode; + } + else + { + throw new ApiException($"优品接口请求错误:{result.Retmsg}"); + } + } + else + { + var result = await _httpClient.PostAsync(_systemConfig.GetAddVirtualPackage(), addVirtualProduct); + if (result.Result) + { + finishedProduct.ProductCode = result.ProductCode; + } + else + { + throw new ApiException($"优品接口请求错误:{result.Retmsg}"); + } + } + await _zxdRepository.GetRepository().UpdateAsync(finishedProduct); + } + + /// + /// 创建成品产品 + /// + /// + /// + /// + public async Task CreateFinishedProduct(CreateFinishedProductDto dto) + { + if (!dto.FinishedProductDetails.Any()) + { + throw new ApiException("请正确填写产品信息!"); + } + var product = await _crmRepository.GetRepository().Query() + .Where(x => x.Id == dto.ProductCode) + .FirstOrDefaultAsync(); + var productPackage = await _zxdRepository.GetRepository().Query() + .Where(x => x.Code == dto.ProductCode) + .Include(x => x.BaseProductPackageRelations) + .FirstOrDefaultAsync(); + + using var transaction = await _zxdRepository.BeginTransactionAsync(); + try + { + foreach (var finishedProductDetail in dto.FinishedProductDetails) + { + var finishedProduct = new FinishedProduct + { + Deptid = finishedProductDetail.Deptid, + Day = finishedProductDetail.Day, + ProducPrice = finishedProductDetail.Price, + ProductName = finishedProductDetail.ProductName, + Coefficient = finishedProductDetail.Coefficient, + Discount = dto.Discount, + AutoOpen = dto.AutoOpen, + BuyOnline = dto.BuyOnline, + Custom = dto.Custom, + CustomPrices = dto.CustomPrices, + OtherClassify = dto.OtherClassify, + DiscounSections = dto.DiscounSections, + GiveProducts = dto.GiveProducts, + Give = dto.Give, + OpenCondition = dto.OpenCondition, + ProductServerType = (ProductServerType)dto.ProductServerType, + ProductCategoryId = dto.ProductCategoryId, + ProductSeriesId = dto.ProductSeriesId, + Remark = dto.Remark, + StandardProductId = dto.StandardProductId, + Status = (ProductStatus)dto.Status, + Upgrade = dto.Upgrade, + }; + finishedProduct.Module = product != null ? product.Moduleid + : productPackage != null ? string.Join(",", productPackage.BaseProductPackageRelations.Select(x => x.Moduleid).ToList()) + : null; + + var addVirtualProduct = new AddVirtualProductDto + { + OutProductCode = dto.ProductCode, + Day = finishedProduct.Day, + Price = finishedProduct.ProducPrice, + Num = finishedProduct.Coefficient, + ProductName = finishedProduct.ProductName, + BasicPorductCode = dto.ProductCode + }; + if (product != null) + { + var result = await _httpClient.PostAsync(_systemConfig.GetAddVirtualProduct(), addVirtualProduct); + if (result.Result) + { + finishedProduct.ProductCode = result.ProductCode; + } + else + { + throw new ApiException($"优品接口请求错误:{result.Retmsg}"); + } + } + else + { + var result = await _httpClient.PostAsync(_systemConfig.GetAddVirtualPackage(), addVirtualProduct); + if (result.Result) + { + finishedProduct.ProductCode = result.ProductCode; + } + else + { + throw new ApiException($"优品接口请求错误:{result.Retmsg}"); + } + } + + await _zxdRepository.GetRepository().InsertAsync(finishedProduct); + + + + } + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + Log.Error(ex, "批量添加成品产品错误!"); + throw; + } + } + + /// + /// 成品产品分页 + /// + /// + /// + public async Task> FinishedProductPage(SearchFinishedProductDto dto) + { + var query = _zxdRepository.GetRepository().Query() + .If(dto.Deptid != null, x => x.Where(x => x.Deptid == dto.Deptid)) + .If(!string.IsNullOrEmpty(dto.Name), x => x.Where(x => x.ProductName.Contains(dto.Name))) + .If(dto.Price != null, x => x.Where(x => x.ProducPrice == dto.Price)) + .If(!string.IsNullOrEmpty(dto.ProductCode), x => x.Where(x => x.ProductCode == dto.ProductCode)) + .If(dto.Day != null, x => x.Where(x => x.Day.Contains(dto.Day.Value.ToString()))) + .If(!string.IsNullOrEmpty(dto.Module), x => x.Where(x => x.Module.Contains(dto.Module))) + .If(dto.Status != null, x => x.Where(x => x.Status == dto.Status)) + .Include(x => x.StandardProduct); + + var total = await query.CountAsync(); + var deptments = await _deptmentDomain.GetDeptments(); + + var data = await query + .Select(x => new FinishedProductDto + { + Id = x.Id, + Deptid = x.Deptid, + ProducDay = x.Day, + AutoOpen = x.AutoOpen ? "是" : "否", + ProducPrice = x.ProducPrice, + ProductName = x.ProductName, + ProductServerType = x.ProductServerType.GetDescription(), + StandardProductId = x.StandardProductId, + ProductCategoryId = x.ProductCategoryId, + ProductSeriesId = x.ProductSeriesId, + Status = x.Status.GetDescription() + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + var productTypeList = await GetProductTypeList(); + var standardProductList = await _zxdRepository.GetRepository().Query() + .Where(x => data.Select(x => x.StandardProductId).Contains(x.Id)) + .ToListAsync(); + var productCodes = standardProductList.Where(x => !string.IsNullOrEmpty(x.ProductCode)).Select(x => x.ProductCode).ToList(); + var productPackageCodes = standardProductList.Where(x => !string.IsNullOrEmpty(x.ProductPackageCode)).Select(x => x.ProductPackageCode).ToList(); + var baseProductList = await _zxdRepository.GetRepository().Query() + .Where(x => productCodes.Contains(x.Code)).ToListAsync(); + var baseProductPackageList = await _zxdRepository.GetRepository().Query() + .Where(x => productPackageCodes.Contains(x.Code)).Include(x => x.BaseProductPackageRelations).ToListAsync(); + data.ForEach(x => + { + x.Department = deptments.First(y => y.Id == x.Deptid).Title; + x.ProductSeries = productTypeList.Where(y => y.ProductId == x.ProductSeriesId).Select(y => y.ProductName).FirstOrDefault(); + x.ProductCategory = productTypeList.Where(y => y.ProductId == x.ProductCategoryId).Select(y => y.ProductName).FirstOrDefault(); + var standardProduct = standardProductList.First(y => y.Id == x.StandardProductId); + if (!string.IsNullOrEmpty(standardProduct.ProductCode)) + { + var baseProduct = baseProductList.First(y => y.Code == standardProduct.ProductCode); + x.StandardProductModules = new List { $"{baseProduct.Name}【{baseProduct.Moduleid}】【{baseProduct.Day}】" }; + } + if (!string.IsNullOrEmpty(standardProduct.ProductPackageCode)) + { + var baseProductPackage = baseProductPackageList.First(y => y.Code == standardProduct.ProductCode); + x.StandardProductModules = baseProductPackage.BaseProductPackageRelations.Select(x => $"{x.ProductName}【{x.Moduleid}】【{x.Day}】").ToList(); + } + }); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + /// + /// 获取赠送产品设置 + /// + /// + /// + public async Task> GetActives(string? productCode) + { + var finishedProduct = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.ProductCode == productCode); + + if (finishedProduct == null) + { + throw new ApiException("成品产品不存在或已删除!"); + } + + var activeList = await _zxdRepository.GetRepository().Query() + .Where(x => x.ProductCode == finishedProduct.ProductCode) + .Where(x => x.Isdelete == 0) + .ToListAsync(); + + if (activeList == null || !activeList.Any()) return new List(); + + var activeids = activeList.Select(x => x.Id).ToList(); + var productGiftList = await _zxdRepository.GetRepository().Query() + .Where(x => x.SubProductId == finishedProduct.Id) + .Where(x => activeids.Contains(x.Activeid)) + .OrderByDescending(x => x.Id) + .Select(x => new SubProductGiftDto + { + GiftDays = x.GiftDays, + Activeid = x.Activeid, + GiftDaysName = x.GiftDaysName, + GiftName = x.GiftName, + Id = x.Id, + IsDefault = x.IsDefault, + Sort = x.Sort, + SubProductId = x.SubProductId, + SubProductName = x.SubProductName, + Type = x.Type + }).ToListAsync(); + + var data = activeList.Select(x => new ProductActiveDto + { + Id = x.Id, + ActiveCode = x.ActiveCode, + Name = x.Activename, + ActiveType = x.ActiveType, + GiftType = string.IsNullOrEmpty(x.Giftype) ? "" : x.Giftype.Replace("[Order]", "【下单时赠送】").Replace("[HandGif]", "【下单后赠送】"), + Giftype = x.Giftype, + Deptid = x.Deptid, + IsFollowOrder = x.IsFollowOrder, + GiftList = productGiftList.Where(y => y.Activeid == x.Id).ToList() + }).ToList(); + + return data; + } + + /// + /// 创建或修改成品产品的赠送产品 + /// + /// + /// + public async Task CreateOrEditActive(CreateOrEditActiveDto dto) + { + if (dto.Id != null && dto.Id > 0) + { + var active = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Id == dto.Id); + active.IsFollowOrder = dto.IsFollowOrder; + active.Giftype = dto.GifType; + await _zxdRepository.GetRepository().UpdateAsync(active); + return; + } + var finishedProduct = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.ProductCode == dto.ProductCode); + + if (finishedProduct == null) + { + throw new ApiException("成品产品不存在或已删除!"); + } + var giveProduct = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.ProductCode == dto.ActiveCode); + + if (giveProduct == null) + { + throw new ApiException("赠送的成品产品不存在或已删除!"); + } + var orderActive = new WxOrderActive + { + ProductName = finishedProduct.ProductName, + Activename = giveProduct.ProductName, + IsFollowOrder = dto.IsFollowOrder, + ProductCode = dto.ProductCode, + Deptid = dto.Deptid, + ActiveCode = dto.ActiveCode, + MinCount = 1, + ProductId = finishedProduct.Id, + Isdelete = 0, + Giftype = dto.GifType, + + }; + + await _zxdRepository.GetRepository().InsertAsync(orderActive); + } + + /// + /// 删除品产品的赠送产品 + /// + /// + /// + /// + public async Task DeleteActive(int? id) + { + if (id == null || id == 0) + { + throw new ApiException("id不能为空或者为0"); + } + var active = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Id == id); + active.Isdelete = 1; + await _zxdRepository.GetRepository().UpdateAsync(active); + } + + /// + /// 创建或修改赠送产品 + /// + /// + /// + /// + public async Task CreateOrEditProductGift(CreateOrEditProducGiftDto dto) + { + if (dto.Id != null && dto.Id > 0) + { + var productGift = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Id == dto.Id); + productGift.GiftDays = dto.GiftDays; + productGift.GiftDaysName = dto.GiftDays == 0 ? "不赠送" : $"赠送{dto.GiftDays}天"; + productGift.Sort = dto.Sort; + productGift.IsDefault = dto.IsDefault; + productGift.GiftName = dto.GiftName; + await _zxdRepository.GetRepository().UpdateAsync(productGift); + return; + } + var deptments = await _deptmentDomain.GetDeptments(); + var active = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Id == dto.Activeid); + var deptment = deptments.FirstOrDefault(x => x.Id == active.Deptid); + if (deptment == null || deptment.DeptmentCampains == null || !deptment.DeptmentCampains.Any()) + { + throw new ApiException($"找不到deptid:{active.Deptid} 的事业部"); + } + var finishedProduct = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.ProductCode == active.ProductCode); + + var subProductGift = new WxSzzySubProductGift + { + Sort = dto.Sort, + Deptid = active.Deptid, + GiftDays = dto.GiftDays, + SubProductId = finishedProduct.Id, + GiftDaysName = dto.GiftDays == 0 ? "不赠送" : $"赠送{dto.GiftDays}天", + IsDefault = dto.IsDefault, + Activeid = dto.Activeid, + Channel = deptment.DeptmentCampains.First().StartCampainId, + GiftName = dto.GiftName, + SubProductName = finishedProduct.ProductName, + Type = 1 + }; + + await _zxdRepository.GetRepository().InsertAsync(subProductGift); + } + + /// + /// 删除赠送产品 + /// + /// + /// + /// + public async Task DeleteProductGift(int? id) + { + if (id == null || id == 0) + { + throw new ApiException("id不能为空或者为0"); + } + var productGift = await _zxdRepository.GetRepository().FirstOrDefaultAsync(x => x.Id == id); + await _zxdRepository.GetRepository().DeleteAsync(productGift); + } + } +} + diff --git a/code/Zxd.Core.Domain/Impl/IActivityDomain.cs b/code/Zxd.Core.Domain/Impl/IActivityDomain.cs new file mode 100644 index 0000000..af5601c --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IActivityDomain.cs @@ -0,0 +1,14 @@ +using Zxd.Core.Domain.Dto.Activity; + +namespace Zxd.Core.Domain.Impl +{ + public interface IActivityDomain : IScopedDependency + { + /// + /// 获取活动名称 + /// + /// + /// + Task GetActivityNameAsync(GetActivityNameRequest request); + } +} diff --git a/code/Zxd.Core.Domain/Impl/ICacheDomain.cs b/code/Zxd.Core.Domain/Impl/ICacheDomain.cs new file mode 100644 index 0000000..debbe67 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/ICacheDomain.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Impl +{ + public interface ICacheDomain : IScopedDependency + { + Task GetValueParameter(string key); + + Task> GetTokens(); + + Task AddToken(SsoUserTokenInfo token); + + Task GetEarlyWarningValue(); + } +} diff --git a/code/Zxd.Core.Domain/Impl/ICustomerDomain.cs b/code/Zxd.Core.Domain/Impl/ICustomerDomain.cs new file mode 100644 index 0000000..0c8ff3a --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/ICustomerDomain.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Wework; + +namespace Zxd.Domain.Impl +{ + public interface ICustomerDomain : IScopedDependency + { + Task> GetUsernames(string? resid); + + Task> GetUsernamesByOrderid(string orderidList); + + public class userRet + { + public string orderid { set; get; } + public string softwarename { set; get; } + } + + Task CreateCustomer(string MOBILE, string ResId, string CustomerFrom); + + Task> GetSalesLeadList(string? resId); + + Task> GetFollow(List queryList); + + Task> GetWorkWXUserSelectAsync(string? resId, string? DeptCode); + + Task> ExtUserBandGetAsync(string? resId); + + Task> GetResidByExtuser(List extUser); + + Task> GetPhoneByUnionid(string unionid); + + /// + /// 添加标签数据 + /// + /// + /// + /// + /// + Task AddTag(string resid, string tag, int ceid); + /// + /// 删除标签 + /// + /// + /// + /// + Task DelTag(int id, int deleteeid); + + /// + /// 获取标签列表 + /// + /// + /// + Task> GetTag(string resid); + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Impl/IDeptmentDomain.cs b/code/Zxd.Core.Domain/Impl/IDeptmentDomain.cs new file mode 100644 index 0000000..3dd6161 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IDeptmentDomain.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Wework; + +namespace Zxd.Domain.Impl +{ + public interface IDeptmentDomain : IScopedDependency + { + Task> GetDeptments(bool? IsDept = null); + + Task GetDeptmentByChannel(int channel); + } +} diff --git a/code/Zxd.Core.Domain/Impl/IEarlyWarningDomain.cs b/code/Zxd.Core.Domain/Impl/IEarlyWarningDomain.cs new file mode 100644 index 0000000..1432e62 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IEarlyWarningDomain.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Impl +{ + public interface IEarlyWarningDomain : IScopedDependency + { + Task> GetEarlyWarningLogPage(SearchEarlyWarningLogDto dto, string? sgin); + + Task GetEarlyWarningDetail(int id); + + Task UpdateEarlyWarningStatus(UpdateEarlyWarningStatusDto dto); + + Task EarlyWarningSync(); + + Task> GetExternalUserTotal(SearchExternalUserTotalDto dto); + + Task WeworkSend(string? wxworkid, string? corpid, string? appid, string? message); + } +} diff --git a/code/Zxd.Core.Domain/Impl/IFinishedProductDomain.cs b/code/Zxd.Core.Domain/Impl/IFinishedProductDomain.cs new file mode 100644 index 0000000..68043bd --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IFinishedProductDomain.cs @@ -0,0 +1,31 @@ +using System; +namespace Zxd.Domain.Impl +{ + public interface IFinishedProductDomain : IScopedDependency + { + Task> GetProductSeriesSelect(); + + Task> GetProductCategorySelect(int? productSeriesId); + + Task GetStandardProduct(int productid); + + Task CreateFinishedProduct(CreateFinishedProductDto dto); + + Task EditFinishedProduct(EditFinishedProductDto dto); + + Task GetFinishedProductDetail(int productid); + + Task> FinishedProductPage(SearchFinishedProductDto dto); + + Task> GetActives(string? productCode); + + Task DeleteActive(int? id); + + Task CreateOrEditActive(CreateOrEditActiveDto dto); + + Task CreateOrEditProductGift(CreateOrEditProducGiftDto dto); + + Task DeleteProductGift(int? id); + } +} + diff --git a/code/Zxd.Core.Domain/Impl/IImportanceItemDomain.cs b/code/Zxd.Core.Domain/Impl/IImportanceItemDomain.cs new file mode 100644 index 0000000..d09cbc5 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IImportanceItemDomain.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Impl +{ + public interface IImportanceItemDomain : IScopedDependency + { + Task> GetCustomerBehaviorLog(SearchCustomerBehaviorLogDto dto); + + Task> GetCustomerBehaviorStatistics(SearchCustomerBehaviorLogDto dto); + } +} diff --git a/code/Zxd.Core.Domain/Impl/IInneruserDomain.cs b/code/Zxd.Core.Domain/Impl/IInneruserDomain.cs new file mode 100644 index 0000000..fb5c968 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IInneruserDomain.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto; + +namespace Zxd.Domain.Impl +{ + public interface IInneruserDomain : IScopedDependency + { + Task SyncSsoOrganization(); + + Task GetInneruser(int eid); + + Task> GetOrganization(); + } +} diff --git a/code/Zxd.Core.Domain/Impl/IMeetingDomain.cs b/code/Zxd.Core.Domain/Impl/IMeetingDomain.cs new file mode 100644 index 0000000..f2823fb --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IMeetingDomain.cs @@ -0,0 +1,15 @@ +using System; +namespace Zxd.Core.Domain.Impl +{ + public interface IMeetingDomain : IScopedDependency + { + Task> GetPage(SearchMeetingDto dto); + + Task> GetMeetingParticipants(int? meetingId); + + Task GetMeetingAccessory(int? meetingId); + + Task CreateOrEditMeeting(CreateOrEditMeetingDto dto, int eid); + } +} + diff --git a/code/Zxd.Core.Domain/Impl/IOrderDomain.cs b/code/Zxd.Core.Domain/Impl/IOrderDomain.cs new file mode 100644 index 0000000..e1335db --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IOrderDomain.cs @@ -0,0 +1,29 @@ +using Zxd.Core.Domain.Dto.Zxd.Callback; +using Zxd.Core.Domain.Dto.Zxd.Order; +using Zxd.Core.Domain.Dto.Zxd.QwWeiSide; + +namespace Zxd.Core.Domain.Impl +{ + public interface IOrderDomain : IScopedDependency + { + Task> GetBindListPageAsync(SearchBindListDto dto); + + Task GetBindDetailAsync(int? id); + + Task> GetUserSelectAsync(string unionId); + + Task GetUserItemAsync(string? resId); + + Task EditBindAsync(SearchBindListDto dto); + + Task BindAsync(BindOrderDto dto); + + Task OrderChange(OrderChangeDto dto); + + Task initResPassTime(ResPassTimeDto dto); + + Task> GetOrderListByEid(SearchSideOrderDto dto); + + Task> ImportHandGiftPreview(List dto); + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Impl/IProdcutDomain.cs b/code/Zxd.Core.Domain/Impl/IProdcutDomain.cs new file mode 100644 index 0000000..a14112b --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IProdcutDomain.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Contract; + +namespace Zxd.Domain.Impl +{ + public interface IProdcutDomain : IScopedDependency + { + Task> GetProductGroupSelect(); + + Task> GetModuleSelect(); + + Task> GetProductTeacherSelect(); + + Task> GetStandardTypeSelect(); + + Task> ProductPage(SearchProductDto dto); + + Task ProductEdit(ChangeProductStatusDto dto); + + Task EditProductPackage(ChangeProductStatusDto dto); + + Task InactiveProduct(string code); + + Task ActiveProduct(string code); + + Task DownProduct(string code); + + Task CreateProduct(CreateProductDto dto); + + Task> ImportPreview(List dto); + + Task ImportProduct(List dto); + + Task> ImportCombinationProductPreview(List dto); + + Task ImportCombinationProduct(List dto); + + Task> ProductPackagePage(SearchProductDto dto); + + Task InactiveProductPackage(string code); + + //下架 + Task DownProductPackage(string code); + + Task ActiveProductPackage(string code); + + Task CreateProductPackage(CreateProductPackageDto dto); + Task CreateSuperProductPackage(CreateSuperProductPackageDto dto); + + Task SyncProductPackage(); + + Task SyncProduct(); + + Task GetBaseProduct(string code); + + Task CreateStandardProduct(CreateStandardProductDto dto); + + Task> StandardProductPage(SearchStandardProductDto dto); + + #region 合同相关 + + Task GetContractByFreeOrderId(decimal ordeir); + + Task GetContractView(ContractQueryDto dto); + + #endregion 合同相关 + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Impl/IStandardProductDomain.cs b/code/Zxd.Core.Domain/Impl/IStandardProductDomain.cs new file mode 100644 index 0000000..10748a2 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IStandardProductDomain.cs @@ -0,0 +1,17 @@ +using System; +namespace Zxd.Core.Domain.Impl +{ + public interface IStandardProductDomain : IScopedDependency + { + Task> GetProductSelect(); + + Task GetBaseProduct(string code); + + Task> GetStandardWaySelect(); + + Task CreateStandardProduct(CreateStandardProductDto dto); + + Task> StandardProductPage(SearchStandardProductDto dto); + } +} + diff --git a/code/Zxd.Core.Domain/Impl/IStatisticsDomain.cs b/code/Zxd.Core.Domain/Impl/IStatisticsDomain.cs new file mode 100644 index 0000000..a31b18a --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IStatisticsDomain.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Dncmsbase; + +namespace Zxd.Core.Domain.Impl +{ + public interface IStatisticsDomain : IScopedDependency + { + Task GetMonthAttentionData(string year, string month); + } +} diff --git a/code/Zxd.Core.Domain/Impl/ITodoItemDomain.cs b/code/Zxd.Core.Domain/Impl/ITodoItemDomain.cs new file mode 100644 index 0000000..a0a14f6 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/ITodoItemDomain.cs @@ -0,0 +1,34 @@ +using Zxd.Core.Domain.Dto.TodoItem; + +namespace Zxd.Core.Domain.Impl +{ + public interface ITodoItemDomain : IScopedDependency + { + /// + /// 获取待办事项列表(新) + /// + /// + /// + Task> GetListNewAsync(GetListRequest dto); + + /// + /// 获取事件分类下拉选项 + /// + /// + /// + Task> GetEventTypeSelectAsync(GetEventTypeSelectRequest request); + + /// + /// 修改已读 + /// + /// + /// + Task EditReadAsync(EditReadRequest request); + + /// + /// 重要线索消息通知 + /// + /// + Task NoticeAsync(); + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Impl/IUserInfoDomain.cs b/code/Zxd.Core.Domain/Impl/IUserInfoDomain.cs new file mode 100644 index 0000000..b531279 --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IUserInfoDomain.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Dncmsbase; + +namespace Zxd.Core.Domain.Impl +{ + public interface IUserInfoDomain : IScopedDependency + { + /// + /// 根据条件获取用户信息 + /// + /// + /// + /// + /// + /// + /// + Task> GetUserInfos(int? cid, string? appid, string? appuserid, string? resid, string? unionid); + + /// + /// 获取业务线Id + /// + /// + /// + Task> GetLineIdAsync(string userids); + } +} diff --git a/code/Zxd.Core.Domain/Impl/IWxResourceDomain.cs b/code/Zxd.Core.Domain/Impl/IWxResourceDomain.cs new file mode 100644 index 0000000..53d407d --- /dev/null +++ b/code/Zxd.Core.Domain/Impl/IWxResourceDomain.cs @@ -0,0 +1,23 @@ +using Zxd.Core.Domain.Dto.WxResource; +using Zxd.Core.Domain.Dto.Zxd.Callback; +using Zxd.Core.Domain.Dto.Zxd.Order; + +namespace Zxd.Core.Domain.Impl +{ + public interface IWxResourceDomain : IScopedDependency + { + Task> GetUserGroupList(UserGroupQueryDto dto); + + Task> GetKfSourceCount(ResourceCountQueryDto dto); + + Task GetKfSourceCountByCrm(ResourceCountQueryDto dto); + + Task SubmitSourceTask(ResourceConfigCreateDto dto); + + Task> GetSourceTaskPage(SearchSourceTaskDto dto); + + Task> GetFromUserPage(SearchFromDto dto); + + Task GetToUserPage(SearchToDto dto); + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/ImportanceItemDomain.cs b/code/Zxd.Core.Domain/ImportanceItemDomain.cs new file mode 100644 index 0000000..bda4949 --- /dev/null +++ b/code/Zxd.Core.Domain/ImportanceItemDomain.cs @@ -0,0 +1,128 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.DirectoryServices; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.ImportanceItem; +using Zxd.Core.Domain.Response; +using Zxd.Domain.Sso; +using Zxd.Entity.Action; + +namespace Zxd.Core.Domain +{ + internal class ImportanceItemDomain : IImportanceItemDomain + { + private readonly IBaseRepository _hgActionRepository; + private readonly IDeptmentDomain _deptmentDomain; + private readonly IHttpClient _httpClient; + private readonly SystemConfig _systemConfig; + + public ImportanceItemDomain(IBaseRepository hgActionRepository, + IDeptmentDomain deptmentDomain, + IHttpClient httpClient, + IConfiguration configuration) + { + _hgActionRepository = hgActionRepository; + _deptmentDomain = deptmentDomain; + _httpClient = httpClient; + _systemConfig = configuration.GetSection("SystemConfig").Get(); + } + + public async Task> GetCustomerBehaviorLog(SearchCustomerBehaviorLogDto dto) + { + var deptments = await _deptmentDomain.GetDeptments(); + if (string.IsNullOrEmpty(dto.Resid) && !dto.Uid.HasValue && (string.IsNullOrEmpty(dto.Appid) || string.IsNullOrEmpty(dto.Appuserid))) + { + throw new ApiException("参数不能为空!"); + } + //var customerids = await _hgActionRepository.GetRepository().Query() + // .If(!string.IsNullOrEmpty(dto.Resid), x => x.Where(x => x.resid == dto.Resid)) + // .If(dto.Uid.HasValue, x => x.Where(x => x.uid == dto.Uid)) + // .If(!string.IsNullOrEmpty(dto.Appid) && !string.IsNullOrEmpty(dto.Appuserid), x => x.Where(x => x.appid == dto.Appid && x.appuserid == dto.Appuserid)) + // .Select(b => b.customerid).Where(x => x > 0).Distinct().ToListAsync(); + + //var uids = await _hgActionRepository.GetRepository().Query() + // .Where(a => customerids.Contains(a.customerid)).Select(a => a.uid) + // .Where(x => x > 0).Distinct().ToListAsync(); + var userlist = await GetUserList(dto.Appid, dto.Appuserid); + var uids = userlist.Select(x => x.Uid).ToList(); + var query = _hgActionRepository.GetRepository().Query() + .Where(x => uids.Contains(x.uid.Value)) + .If(dto.Eventid.HasValue, x => x.Where(x => x.neweventid == dto.Eventid)); + + var data = await query + .Select(x => new CustomerBehaviorLogDto + { + Id = x.id, + Deptid = x.deptid, + ActTime = x.act_time, + Eventid = x.neweventid.Value, + Eventname = x.neweventname, + Sceneidname = x.eventname, + Scenetypename = x.eventtypename, + Content = x.Content + }) + .OrderByDescending(x => x.Id) + .ToListAsync(); + + foreach (var item in data) + { + var deptment = deptments.FirstOrDefault(x => x.Id == item.Deptid); + if (deptment != null) + { + item.Deptname = deptment.Title; + } + } + + return data; + } + + public async Task> GetCustomerBehaviorStatistics(SearchCustomerBehaviorLogDto dto) + { + //var customerids = await _hgActionRepository.GetRepository().Query() + // .If(!string.IsNullOrEmpty(dto.Resid), x => x.Where(x => x.resid == dto.Resid)) + // .If(dto.Uid.HasValue, x => x.Where(x => x.uid == dto.Uid)) + // .If(!string.IsNullOrEmpty(dto.Appid) && !string.IsNullOrEmpty(dto.Appuserid), x => x.Where(x => x.appid == dto.Appid && x.appuserid == dto.Appuserid)) + // .Select(b => b.customerid).Where(x => x > 0).Distinct().ToListAsync(); + + //var uids = await _hgActionRepository.GetRepository().Query() + // .Where(a => customerids.Contains(a.customerid)).Select(a => a.uid) + // .Where(x => x > 0).Distinct().ToListAsync(); + var userlist = await GetUserList(dto.Appid, dto.Appuserid); + var uids = userlist.Select(x => x.Uid).ToList(); + var query = _hgActionRepository.GetRepository().Query() + .Where(x => uids.Contains(x.uid.Value)) + .GroupBy(x => new + { + x.neweventid, + x.eventtypename + }).Select(x => new CustomerBehaviorStatisticsDto + { + Eventid = x.Key.neweventid.Value, + EventName = x.Key.eventtypename, + Count = x.Count() + }); + + var data = await query.ToListAsync(); + + return data; + } + + private async Task> GetUserList(string? appid, string? appuserid) + { + var data = new + { + where = JsonHelper.ToJson(new { appid, appuserid }) + }; + var url = _systemConfig.GetUserList(); + var result = await _httpClient.PostAsync>(url, data); + if (result.Ret == 0) + { + return result.List; + } + return new List(); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/InneruserDomain.cs b/code/Zxd.Core.Domain/InneruserDomain.cs new file mode 100644 index 0000000..fb390b0 --- /dev/null +++ b/code/Zxd.Core.Domain/InneruserDomain.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto; + +namespace Zxd.Domain +{ + internal class InneruserDomain : IInneruserDomain + { + private readonly IConfiguration _configuration; + private readonly IHttpClient _httpClient; + private readonly IBaseRepository _repository; + + private SsoOrganization SsoOrganization { get; set; } + + public InneruserDomain(IConfiguration configuration, + IHttpClient httpClient, + IBaseRepository repository) + { + _configuration = configuration; + _httpClient = httpClient; + _repository = repository; + } + + public async Task SyncSsoOrganization() + { + try + { + return await OrganizationAnalyse(await GetSsoOrganization()); + } + catch (Exception ex) + { + Log.Error($"同步SSO报错", ex); + return false; + } + } + + private async Task GetSsoOrganization() + { + try + { + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var param = new Dictionary(); + param.Add("appid", systemConfig.Appid); + var response = await _httpClient.PostAsync>($"{systemConfig.SsoUrl}{systemConfig.SsoOrganizationUrl}", param, systemConfig.Appid, systemConfig.AppSecret); + if (response.Ret != 0) + { + Log.Error($"SSO 组织架构获取报错,ex: {response.Msg}"); + throw new Exception($"SSO 组织架构获取报错,ex: {response.Msg}"); + } + SsoOrganization = response.Data; + return SsoOrganization; + } + catch (Exception ex) + { + Log.Error($"SSO 组织架构获取报错!", ex); + throw; + } + } + + private async Task OrganizationAnalyse(SsoOrganization ssoOrganization) + { + var hasUpdate = false; + var employeeIds = new List(); + foreach (var employee in ssoOrganization.employees) + { + var employee_id = employee.employee_id; + var employee_departmentinfo = ssoOrganization.employee_departments.Where(m => m.employee_id == employee.id && m.is_deleted == 0); + //员工不在关系里面 + if (!employee_departmentinfo.Any()) + continue; + var departmentId = employee_departmentinfo.Select(n => n.department_id).ToList(); + //员工不在指定的部门里面 + if (ssoOrganization.profession_departments.FirstOrDefault(m => departmentId.Contains(m.id) && m.is_deleted == 0) == null) + continue; + employeeIds.Add(employee_id); + } + if (employeeIds != null && employeeIds.Any()) + { + var list = await _repository.GetRepository().Query().Where(x => employeeIds.Contains(x.EID)).ToListAsync();//在坐席中对应的关系 + using var transaction = await _repository.BeginTransactionAsync(); + try + { + foreach (var employeeId in employeeIds) + { + var info = list.FirstOrDefault(x => x.EID == employeeId); + var employee = ssoOrganization.employees.First(x => x.employee_id == employeeId); + if (info == null)//找不到数据,就新增 + { + await CreateInneruser(employeeId, employee, ssoOrganization); + hasUpdate = true; + } + else //有数据就修改 + { + if (info.UNAME != employee.employee_name || + info.DISMISSTIME != employee.leave_date || + info.ENTRYDATE != employee.entry_date || + info.ISHIDE != Convert.ToInt16(employee.is_deleted == 0 ? 0 : 1) || + info.ISDISMISS != Convert.ToInt16(employee.status == 2 ? 1 : 0) || + info.UNAME != employee.employee_name) + { + info.UNAME = employee.employee_name; + info.DISMISSTIME = employee.leave_date; + info.ENTRYDATE = employee.entry_date; + info.ISHIDE = Convert.ToInt16(employee.is_deleted == 0 ? 0 : 1); + info.ISDISMISS = Convert.ToInt16(employee.status == 2 ? 1 : 0);//是否离职,根据是否含有离职时间来 + info.UNAME = employee.employee_name; + hasUpdate = true; + await _repository.GetRepository().UpdateAsync(info); + } + } + } + + await transaction.CommitAsync(); + } + catch (Exception ex) + { + Log.Error("员工信息更新报错!", ex); + transaction.Rollback(); + transaction.Dispose(); + return false; + } + } + + if (hasUpdate) + { + await ClearCache(); + } + + return true; + } + + /// + /// 清理缓存 + /// + /// + private async Task ClearCache() + { + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + try + { + foreach (var clearCacheUrl in systemConfig.ClearCacheUrls) + { + var httpResponse = await _httpClient.GetAsync(clearCacheUrl); + } + } + catch (Exception ex) + { + Log.Error("清除缓存报错!", ex); + } + } + + /// + /// 新增员工数据 + /// + /// + /// + /// + /// + private async Task CreateInneruser(int employee_id, SsoEmployee employee, SsoOrganization ssoOrganization) + { + try + { + var bas_inneruser = new BAS_INNERUSER + { + CTIME = DateTime.Now, + DISMISSTIME = employee.leave_date, + ENTRYDATE = employee.entry_date, + EID = employee_id, + ISHIDE = Convert.ToInt16(employee.is_deleted == 0 ? 0 : 1), + ISDISMISS = Convert.ToInt16(employee.leave_date.HasValue ? 1 : 0),//是否离职,根据是否含有离职时间来 + UNAME = employee.employee_name + }; + string password = $"{employee_id}@123"; + string user_salt = Utility.CreateRandomSatl(8); + bas_inneruser.PASSWORD = Utility.Sha512(password + user_salt);//初始化密码 + var userSaltModel = new BAS_INNERUSERSALT + { + INNERUSERID = bas_inneruser.PKID, + EID = employee_id, + PWDSALT = user_salt, + CTIME = DateTime.Now + }; + + await _repository.GetRepository().InsertAsync(userSaltModel); + if (employee.sex.HasValue && employee.sex == 1) + { + bas_inneruser.GENDER = "m"; + } + else + { + bas_inneruser.GENDER = "f"; + } + await _repository.GetRepository().InsertAsync(bas_inneruser); + } + catch (Exception ex) + { + Log.Error($"员工信息{employee_id}新增报错!", ex); + } + } + + public async Task> GetOrganization() + { + var data = new List(); + var ssoOrganization = await GetSsoOrganization(); + if (ssoOrganization == null) + return data; + + foreach (var deparment in ssoOrganization.other_departments.Where(x => x.parent_id == null && x.is_deleted == 0)) + { + data.Add(new SsoOrganizationDto + { + Id = deparment.id, + DepartmentCode = deparment.department_code, + DepartmentName = deparment.department_name, + ParentId = deparment.parent_id, + Status = deparment.status, + Children = GetChildren(deparment.id, ssoOrganization), + SsoStaffs = GetSsoStaffs(deparment.id, ssoOrganization) + }); + } + return data; + } + + private static List GetChildren(int parentId, SsoOrganization ssoOrganization) + { + var data = new List(); + foreach (var deparment in ssoOrganization.other_departments.Where(x => x.parent_id == parentId && x.is_deleted == 0)) + { + data.Add(new SsoOrganizationDto + { + Id = deparment.id, + DepartmentCode = deparment.department_code, + DepartmentName = deparment.department_name, + ParentId = deparment.parent_id, + Status = deparment.status, + Children = GetChildren(deparment.id, ssoOrganization), + SsoStaffs = GetSsoStaffs(deparment.id, ssoOrganization) + }); + } + return data; + } + + private static List GetSsoStaffs(int departmentId, SsoOrganization ssoOrganization) + { + var data = new List(); + foreach (var employeeDepartments in ssoOrganization.employee_departments.Where(x => x.department_id == departmentId && x.is_deleted == 0)) + { + var employee = ssoOrganization.employees.FirstOrDefault(x => x.id == employeeDepartments.employee_id); + if (employee == null) continue; + data.Add(new SsoStaffDto + { + Eid = employee.employee_id, + Name = employee.employee_name, + }); + } + return data; + } + + public async Task GetInneruser(int eid) + { + var data = await _repository.GetRepository().Query() + .Where(x => x.EID == eid) + .Select(x => new InneruserDto + { + Eid = x.EID, + Inneruserid = x.PKID, + Username = x.UNAME + }) + .FirstOrDefaultAsync(); + + return data; + } + } +} diff --git a/code/Zxd.Core.Domain/MeetingDomain.cs b/code/Zxd.Core.Domain/MeetingDomain.cs new file mode 100644 index 0000000..a059be4 --- /dev/null +++ b/code/Zxd.Core.Domain/MeetingDomain.cs @@ -0,0 +1,232 @@ +using System; +using System.Linq; +using Zxd.Core.Domain.Impl; +using Zxd.Entity.Zxd; +using static Microsoft.EntityFrameworkCore.DbLoggerCategory; + +namespace Zxd.Core.Domain +{ + public class MeetingDomain : IMeetingDomain + { + private readonly IBaseRepository _zxdRepository; + private readonly IRedisManager _redisManager; + private readonly IConfiguration _configuration; + private readonly IDeptmentDomain _deptmentDomain; + private readonly IHttpClient _httpClient; + private readonly IMapper _mapper; + private readonly SystemConfig _systemConfig; + private readonly IInneruserDomain _inneruserDomain; + + public MeetingDomain(IBaseRepository zxdRepository, + IRedisManager redisManager, + IConfiguration configuration, + IDeptmentDomain deptmentDomain, + IMapper mapper, + IHttpClient httpClient, + IInneruserDomain inneruserDomain) + { + _zxdRepository = zxdRepository; + _redisManager = redisManager; + _deptmentDomain = deptmentDomain; + _mapper = mapper; + _httpClient = httpClient; + _configuration = configuration; + _inneruserDomain = inneruserDomain; + _systemConfig = _configuration.GetSection("SystemConfig").Get(); + } + + /// + /// 分页 + /// + /// + /// + public async Task> GetPage(SearchMeetingDto dto) + { + var query = _zxdRepository.GetRepository().Query() + .If(!string.IsNullOrEmpty(dto.MeetingName), x => x.Where(x => x.MeetingName.Contains(dto.MeetingName))) + .If(dto.MeetingType != null, x => x.Where(x => x.MeetingType == (MeetingType)dto.MeetingType)) + .If(!string.IsNullOrEmpty(dto.Compere), x => x.Where(x => x.Compere.Contains(dto.Compere))) + .If(!string.IsNullOrEmpty(dto.CreateUser), x => x.Where(x => x.CreateUser == dto.CreateUser)) + .If(!string.IsNullOrEmpty(dto.Paricipant), x => x.Where(x => x.MeetingParticipants.Any(y => y.Paricipant == dto.Paricipant))) + .If(dto.CreateTimeForm != null, x => x.Where(x => x.CreateTime >= dto.CreateTimeForm)) + .If(dto.CreateTimeTo != null, x => x.Where(x => x.CreateTime < dto.CreateTimeTo.Value.AddDays(1))) + .If(dto.MeetingDateForm != null, x => x.Where(x => x.BeginTime >= dto.MeetingDateForm)) + .If(dto.MeetingDateTo != null, x => x.Where(x => x.BeginTime < dto.MeetingDateTo.Value.AddDays(1))) + .Include(x => x.MeetingParticipants); + + var total = await query.CountAsync(); + var data = await query + .Select(x => new MeetingDto + { + Id = x.Id, + Compere = x.Compere, + CreateTime = x.CreateTime, + CreateUser = x.CreateUser, + MeetingName = x.MeetingName, + MeetingSite = x.Site, + MeetingTime = $"{x.BeginTime:yyyy.MM.dd}({x.BeginTime:HH:mm}-{x.BeginTime.AddHours(x.ContinueHour).AddMinutes(x.ContinueMinute):HH:mm})", + MeetingType = x.MeetingType.GetDescription(), + Remark = x.Remark, + UpdateTime = x.UpdateTime, + UpdateUser = x.UpdateUser + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + /// + /// 获取会议参与人 + /// + /// + /// + /// + public async Task> GetMeetingParticipants(int? meetingId) + { + if (meetingId == null) + { + throw new ApiException("会议ID不能为空!"); + } + var data = await _zxdRepository.GetRepository().Query() + .Where(x => x.MeetingId == meetingId) + .Select(x => new MeetingParticipantDto + { + Id = x.Id, + Participant = x.Paricipant ?? "" + }) + .ToListAsync(); + return data; + } + + /// + /// 获取会议附件 + /// + /// + /// + /// + public async Task GetMeetingAccessory(int? meetingId) + { + if (meetingId == null) + { + throw new ApiException("会议ID不能为空!"); + } + var meeting = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == meetingId) + .Where(x => !x.IsDelete) + .Include(x => x.MeetingAccessories) + .FirstOrDefaultAsync(); + + if (meeting == null) + { + throw new ApiException("会议不存或已删除!"); + } + + var data = new MeetingAccessoryDto + { + Id = meeting.Id, + Compere = meeting.Compere, + MeetingName = meeting.MeetingName, + MeetingType = meeting.MeetingType.GetDescription() + }; + foreach (var meetingAccessory in meeting.MeetingAccessories) + { + data.Accessories.Add(new AccessoryDto + { + FileName = meetingAccessory.FileName, + FileSize = meetingAccessory.FileSize, + FileUrl = meetingAccessory.FileUrl, + Uploader = meetingAccessory.Uploader, + UploadTime = meetingAccessory.UploadTime, + Id = meetingAccessory.Id + }); + } + + return data; + } + + /// + /// 创建或修改会议 + /// + /// + /// + /// + public async Task CreateOrEditMeeting(CreateOrEditMeetingDto dto, int eid) + { + var user = await _inneruserDomain.GetInneruser(eid); + var userName = user.Username; + if (dto.Id != null && dto.Id > 0) + { + var meeting = await _zxdRepository.GetRepository() + .FirstOrDefaultAsync(x => x.Id == dto.Id); + if (meeting == null) + { + throw new ApiException("会议不存或已删除!"); + } + meeting.BeginTime = dto.BigenTime; + meeting.Compere = dto.Compere; + meeting.ContinueHour = dto.ContinueHour; + meeting.ContinueMinute = dto.ContinueMinute; + meeting.MeetingName = dto.MeetingName; + meeting.MeetingType = (MeetingType)dto.MeetingType; + meeting.Remark = dto.Remark; + meeting.Site = dto.MeetingSite; + meeting.UpdateTime = DateTime.Now; + meeting.UpdateUser = userName; + + await _zxdRepository.GetRepository().UpdateAsync(meeting); + return; + } + + var meetingInfo = new Meeting + { + BeginTime = dto.BigenTime, + Compere = dto.Compere, + ContinueHour = dto.ContinueHour, + ContinueMinute = dto.ContinueMinute, + MeetingName = dto.MeetingName, + MeetingType = (MeetingType)dto.MeetingType, + Remark = dto.Remark, + Site = dto.MeetingSite, + CreateTime = DateTime.Now, + CreateUser = userName + }; + await _zxdRepository.GetRepository().InsertAsync(meetingInfo); + } + + public async Task DeleteMeeting(int? meetingId) + { + var meeting = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == meetingId) + .Where(x => !x.IsDelete) + .FirstOrDefaultAsync(); + + if (meeting == null) + { + throw new ApiException("会议不存或已删除!"); + } + + meeting.IsDelete = true; + await _zxdRepository.GetRepository().UpdateAsync(meeting); + } + + public async Task CreateMeetingAccessory(CreateMeetingAccessoryDto dto, int eid) + { + var user = await _inneruserDomain.GetInneruser(eid); + var meetingAccessory = new MeetingAccessory + { + FileName = dto.FileName, + FileSize = dto.FileSize, + FileUrl = dto.FileUrl, + MeetingId = dto.MeetingId, + UploadEid = eid, + UploadTime = DateTime.Now, + Uploader = user.Username + }; + + await _zxdRepository.GetRepository().InsertAsync(meetingAccessory); + } + } +} + diff --git a/code/Zxd.Core.Domain/OrderBindDomain.cs b/code/Zxd.Core.Domain/OrderBindDomain.cs new file mode 100644 index 0000000..b967989 --- /dev/null +++ b/code/Zxd.Core.Domain/OrderBindDomain.cs @@ -0,0 +1,443 @@ +using Dapper; +using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; +using System.Data; +using Zxd.Core.Domain.Dto.Zxd.Callback; +using Zxd.Core.Domain.Dto.Zxd.Order; +using Zxd.Core.Domain.Dto.Zxd.QwWeiSide; +using Zxd.Entity.UserCenter; +using Zxd.Entity.Zxd.Order; + +namespace Zxd.Core.Domain +{ + public class OrderBindDomain : IOrderDomain + { + private readonly IBaseRepository _zxdRepository; + private readonly IBaseRepository _cmsRepository; + + private readonly IBaseRepository _userCenterRepository; + + private readonly IRedisManager _redisManager; + + private readonly ICacheDomain _cacheDomain; + private readonly IMapper _mapper; + private readonly IHttpClient _httpClient; + + private readonly SystemConfig _systemConfig; + + private readonly IDbConnection _dbConnection; + + private readonly PayCallbackConfig _payCallbackConfig; + private readonly IUserInfoDomain _userInfoDomain; + + public OrderBindDomain( + IBaseRepository zxdRepository, + IBaseRepository cmsRepository, + IBaseRepository userCenterRepository, + IRedisManager redisManager, + ICacheDomain cacheDomain, + IHttpClient httpClient, + IConfiguration configuration, + IUserInfoDomain userInfoDomain, + IDbConnection dbConnection, IMapper mapper) + { + _zxdRepository = zxdRepository; + _cmsRepository = cmsRepository; + _userCenterRepository = userCenterRepository; + _redisManager = redisManager; + _cacheDomain = cacheDomain; + _httpClient = httpClient; + _userInfoDomain = userInfoDomain; + _mapper = mapper; + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _dbConnection = dbConnection; + _payCallbackConfig = configuration.GetSection("PayCallbackConfig").Get(); + } + + public async Task> GetBindListPageAsync(SearchBindListDto dto) + { + var channel = new List(); + if (!string.IsNullOrEmpty(dto.Channel)) + { + var parts = dto.Channel.Split(','); + foreach (var part in parts) + { + if (int.TryParse(part, out var ch)) + { + channel.Add(ch); + } + } + } + if (channel.Count == 0) + { + return new PageResult(dto.PageIndex, dto.PageSize, 0, new List()); + } + if (!string.IsNullOrEmpty(dto.ResId)) + { + dto.ResId = await _zxdRepository.GetRepository().Query().Where(x => x.UMID == dto.ResId) + .Select(x => x.RESID).FirstOrDefaultAsync(); + } + + var query = _zxdRepository.GetRepository().Query() + .Where(x => channel.Contains(x.Channel)) + .If(dto.BindType.HasValue, x => x.Where(x => x.BindType == dto.BindType)) + .If(dto.EId.HasValue, x => x.Where(x => x.EId == dto.EId)) + .If(!string.IsNullOrEmpty(dto.txt_userId), x => x.Where(x => x.EId.GetValueOrDefault().ToString() == dto.txt_userId)) + .If(!string.IsNullOrEmpty(dto.PayType), x => x.Where(x => x.PayType == dto.PayType)) + .If(!string.IsNullOrEmpty(dto.ResId), x => x.Where(x => x.ResId == dto.ResId)) + .If(!string.IsNullOrEmpty(dto.UnionId), x => x.Where(x => x.UnionId == dto.UnionId)) + .If(!string.IsNullOrEmpty(dto.PayNo), x => x.Where(x => x.TradeNo == dto.PayNo)); + + var total = await query.CountAsync(); + var data = await query + .OrderByDescending(x => x.CreateTime) + .Select(x => new BindListDto + { + Id = x.Id, + BindType = x.BindType, + PayType = x.PayType, + UnionId = x.UnionId, + PayNo = x.TradeNo, + Amount = x.TotalAmount, + ResId = x.ResId, + Remark = x.Remark, + EId = x.EId, + PayTime = x.CreateTime + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + + var resids = data.Select(x => x.ResId).ToList(); + + var customers = await _zxdRepository.GetRepository().Query().Where(x => resids.Contains(x.RESID)).ToListAsync(); + + foreach (var item in data) + { + item.ResId = customers.FirstOrDefault(x => x.RESID == item.ResId)?.UMID ?? ""; + } + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + public async Task GetBindDetailAsync(int? id) + { + var query = _zxdRepository.GetRepository().Query() + .Where(w => w.Id == id); + var data = await query + .Select(x => new BindListDto + { + BindType = x.BindType, + PayType = x.PayType, + UnionId = x.UnionId, + PayNo = x.TradeNo, + Amount = x.TotalAmount, + ResId = x.ResId, + Remark = x.Remark, + EId = x.EId, + PayTime = x.CreateTime + }).ToListAsync(); + return data.FirstOrDefault(); + } + + public async Task EditBindAsync(SearchBindListDto dto) + { + var one = await _zxdRepository.GetRepository().Query() + .Where(w => w.Id == dto.Id) + .FirstOrDefaultAsync(); + if (one == null) + { + throw new ApiException("无效的id:" + dto.Id, 1); + } + + //if (!string.IsNullOrEmpty(one.ResId)) + //{ + // throw new ApiException("已绑定过,不能再次绑定", 1); + //} + var orderCount = await _zxdRepository.GetRepository().Query() + .Where(w => w.tradeno == one.TradeNo && w.auditstatus == 1 && w.isdelete == 0) + .CountAsync(); + if (orderCount > 0) + { + throw new ApiException("已绑定过,不能再次绑定", 1); + } + + one.ResId = dto.ResId; + one.Remark = dto.Remark; + one.BindType = 2; + await _zxdRepository.GetRepository().UpdateAsync(one); + await SyncOrderAsync(one, dto.ResId); + return "修改成功"; + } + + public async Task BindAsync(BindOrderDto dto) + { + var channel = default(int?); + if (int.TryParse(dto.channel, out var channelTemp)) + { + channel = channelTemp; + } + + var payTime = default(DateTime?); + if (!string.IsNullOrEmpty(dto.payTime) && DateTime.TryParse(dto.payTime, out var payTimeTemp)) + { + payTime = payTimeTemp; + } + + var one = await _zxdRepository.GetRepository().Query() + .Where(w => w.TradeNo == dto.tradeNo) + .FirstOrDefaultAsync(); + if (one != null) + { + //重复推送的只修改订单状态 + one.TradeStatus = dto.tradeStatus; + await _zxdRepository.GetRepository().UpdateAsync(one); + } + else + { + //只处理交易成功的 + if (dto.tradeStatus == 1 && payTime.HasValue) + { + var bindType = 0; + var resId = default(string); + var users = await GetUserSelectAsync(dto.unionId); + if (users.Count == 1) + { + bindType = 1; + resId = users.FirstOrDefault(); + } + + one = new WX_SZZYORDER_BIND(); + one.PayType = dto.payType; + one.TradeNo = dto.tradeNo; + one.OutTradeNo = dto.outTradeNo; + one.UserTradeNo = dto.userTradeNo; + one.TotalAmount = 0.01m * dto.totalAmount.GetValueOrDefault(); + one.TradeStatus = dto.tradeStatus; + one.UnionId = dto.unionId; + one.EId = dto.eId; + one.BindType = bindType; + one.ResId = resId ?? ""; + one.CreateTime = payTime; + one.Channel = channel; + one.Remark = ""; + one.IdentityKey = dto.identityKey; + await _zxdRepository.GetRepository().InsertAsync(one); + + if (!string.IsNullOrEmpty(resId)) + { + await SyncOrderAsync(one, resId); + } + } + } + return "绑定成功"; + } + + private async Task SyncOrderAsync(WX_SZZYORDER_BIND dto, string resId) + { + var url = await _cacheDomain.GetValueParameter("Core_ZxdService_OrderDeposit"); + if (string.IsNullOrEmpty(url)) + { + url = _payCallbackConfig.PushUrl; + } + var clientid = "UPWEBSITE"; + + var paytypename = ""; + var paytype = 0; + switch (dto.PayType) + { + case "alipay": + { + paytypename = "支付宝"; + paytype = 1; + break; + } + case "wechat": + { + paytypename = "微信支付"; + paytype = 5; + break; + } + } + var param = new OrderDepositDto + { + source = "zxd", + channel = dto.Channel, + companycode = null, + creator = null, + creatorname = null, + deptcode = null, + id = 0, + isuse = 0, + orderid = null, + paydate = dto.CreateTime, + payname = "在线支付", + payno = dto.TradeNo, + payprice = dto.TotalAmount.GetValueOrDefault(), + paytype = paytype, + paytypename = paytypename, + remark = $"{dto.PayType},付款流水号:{dto.TradeNo}", + resid = resId, + tradeno = dto.TradeNo, + identityKey = dto.IdentityKey + }; + var response = await _httpClient.PostSecurityAsync(url, param, new { }, clientid, _systemConfig.GetAccessKey(clientid)); + if (!response.result) + { + throw new ApiException(JsonSerializer.Serialize(response), 3); + } + } + + public async Task> GetUserSelectAsync(string unionId) + { + var data = new List(); + if (string.IsNullOrEmpty(unionId)) + { + return data; + } + + var sql = "select Customerid from userinfo where unionId=@unionId limit 1"; + var customerid = await _dbConnection.ExecuteScalarAsync(sql, new { unionId }); + if (customerid.HasValue) + { + sql = "select Distinct(Resid) from userinfo where Customerid=@customerid"; + var resIds = await _dbConnection.QueryAsync(sql, new { customerid }); + if (resIds != null && resIds.Any()) + { + data.AddRange(resIds.Where(w => !string.IsNullOrEmpty(w))); + } + } + + return data; + } + + public async Task GetUserItemAsync(string? resId) + { + if (string.IsNullOrEmpty(resId)) + { + throw new ApiException("resId必填", 1); + } + + var sql = "select count(1) from userinfo where Resid=@resId"; + var count = await _dbConnection.ExecuteScalarAsync(sql, new { resId }); + if (count.GetValueOrDefault() == 0) + { + throw new ApiException("无效的resId:" + resId, 1); + } + return "获取成功"; + } + + public async Task OrderChange(OrderChangeDto dto) + { + try + { + Log.Information($"接收【OrderChange】到数据{dto.ToJson()}"); + var orderLog = _mapper.Map(dto); + await _cmsRepository.GetRepository().InsertAsync(orderLog); + var obj = new ResPassTimeDto + { + ResId = dto.RESID + }; + return await initResPassTime(obj); + } + catch (Exception ex) + { + Log.Error($"插入【OrderChange】日志失败{ex.Message}"); + return false; + } + } + + public async Task initResPassTime(ResPassTimeDto dto) + { + var consumers = KafkaClient.GetConsumers(); + Log.Information($"consumers: {consumers.ToJson()}"); + var obj = new ResPassTimeDto + { + ResId = dto.ResId + }; + await KafkaClient.SendMessage(consumers.FirstOrDefault(n => n.Topic == "ResPassTime"), obj); + return true; + } + + public async Task> GetOrderListByEid(SearchSideOrderDto dto) + { + var userInfoList = await _userInfoDomain.GetUserInfos(null, dto.AppId, dto.AppUserId, "", ""); + var resids = userInfoList.Where(n => !string.IsNullOrWhiteSpace(n.Resid)).Select(n => n.Resid).Distinct().ToList(); + var dataList = await _zxdRepository.GetRepository().Query().Where(n => resids.Contains(n.RESID) && n.eid == dto.Eid).OrderByDescending(n => n.CTIME).ToListAsync(); + List res = new List(); + foreach (var item in dataList) + { + SideOrderModel side = new SideOrderModel + { + OrderId = item.ORDERID, + SzzyOrderId = item.SZZYORDERID.ToString(), + ProductName = item.SUBPRODUCTNAME, + ProductCode = item.PRODUCTCODE, + Opendays = item.OPENDAYS, + Giftdays = item.giftdays.HasValue ? item.giftdays.Value : item.giftdays2.HasValue ? (item.giftdays.Value + item.giftdays2.Value) : 0, + Ctime = item.CTIME, + Otime = item.OTIME, + OrderStatus = item.ORDERSTATUS, + OrderStatusName = item.ORDERSTATUSNAME, + }; + res.Add(side); + } + return res; + } + + /// + /// 导入赠送订单预览 + /// + /// + /// + public async Task> ImportHandGiftPreview(List dto) + { + List res = new List(); + var orderids = dto.Select(n => Convert.ToDecimal(n.OrderId)).ToList(); + var dataList = await _zxdRepository.GetRepository().Query().Where(n => orderids.Contains(n.ORDERID)).ToListAsync(); + var productCode = dto.Select(n => n.ProductCode).Distinct().ToList(); + var proList = await _zxdRepository.GetRepository().Query().Where(n => productCode.Contains(n.productcode)).ToListAsync(); + foreach (var item in dto) + { + ImportGiftOrderViewModel model = new ImportGiftOrderViewModel + { + OrderId = item.OrderId, + Day = Convert.ToInt32(item.Day), + ProductCode = item.ProductCode + }; + var orderid = Convert.ToDecimal(item.OrderId); + var order = dataList.FirstOrDefault(n => n.ORDERID == orderid); + if (order == null) + { + model.Msg += "找不到订单;"; + } + else + { + model.Channel = order.CHANNEL; + model.Umid = order.UMID; + model.Name = order.CNAME; + model.UserName = order.SOFTUSERNAME; + } + if (model.Day <= 0) + { + model.Msg += "赠送天数不能小于0;"; + } + var product = proList.FirstOrDefault(n => n.productcode == model.ProductCode); + if (product == null) + { + model.Msg += "找不到对应的产品;"; + } + else + { + model.ProductName = product.subproductname; + } + if (!model.ProductCode.Contains("_MFTY")) + { + model.Msg += "只能赠送免费产品;"; + } + res.Add(model); + } + + return res; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/OrderDomain.cs b/code/Zxd.Core.Domain/OrderDomain.cs new file mode 100644 index 0000000..9f15859 --- /dev/null +++ b/code/Zxd.Core.Domain/OrderDomain.cs @@ -0,0 +1,50 @@ +using System; + +namespace Zxd.Domain +{ + public class OrderDomain + { + private readonly IBaseRepository _zxdRepository; + private readonly IDeptmentDomain _deptmentDomain; + + public OrderDomain(IBaseRepository zxdRepository, + IDeptmentDomain deptmentDomain) + { + _zxdRepository = zxdRepository; + _deptmentDomain = deptmentDomain; + } + + /*public async Task> GetOrderPage(SearchOrderDto dto) + { + var query = _zxdRepository.GetRepository().Query() + .If(dto.Orderid != null, x => x.Where(x => x.SzzyOrderid == dto.Orderid)) + .If(dto.OrderStatus != null, x => x.Where(x => x.OrderStatus == dto.OrderStatus)) + .If(dto.RiskctrlStatus != null, x => x.Where(x => x.RiskctrlStatus == dto.RiskctrlStatus)) + .If(dto.Deptid != null, x => x.Where(x => x.Deptid == dto.Deptid)) + .If(dto.ProductSeriesId != null, x => x.Where(x => x.FinishedProduct.ProductSeriesId == dto.ProductSeriesId)) + .If(dto.ProductTypeId != null, x => x.Where(x => x.FinishedProduct.ProductTypeId == dto.ProductTypeId)) + .If(dto.Activity != null, x => x.Where(x => x.FinishedProductId == dto.Activity)) + .If(!string.IsNullOrEmpty(dto.ProductName), x => x.Where(x => x.FinishedProduct.ProductName.Contains(dto.ProductName))) + .If(!string.IsNullOrEmpty(dto.ProductCode), x => x.Where(x => x.FinishedProduct.ProductCode == dto.ProductCode)) + .If(dto.SzzyOrderid != null, x => x.Where(x => x.SzzyOrderid == dto.SzzyOrderid)) + .If(dto.OrderAmountMax != null, x => x.Where(x => x.NeedPay > dto.OrderAmountMax)) + .If(dto.OrderTimeFrom != null, x => x.Where(x => x.Ctime >= dto.OrderTimeFrom)) + .If(dto.OpenDateTo != null, x => x.Where(x => x.Ctime < dto.OrderTimeFrom.Value.AddDays(1))) + .If(dto.AccountingDateFrom != null, x => x.Where(x => x.Arrivaltime >= dto.AccountingDateFrom)) + .If(dto.AccountingDateTo != null, x => x.Where(x => x.Arrivaltime < dto.AccountingDateFrom.Value.AddDays(1))) + .If(!dto.IncludeNotOpen, x => x.Where(x => x.Otime != null)) + .Include(x => x.FinishedProduct); + + var total = await query.CountAsync(); + var data = await query + .Select(x => new OrderDto + { + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + }*/ + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/ProductDomain.cs b/code/Zxd.Core.Domain/ProductDomain.cs new file mode 100644 index 0000000..812a97c --- /dev/null +++ b/code/Zxd.Core.Domain/ProductDomain.cs @@ -0,0 +1,2012 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Web; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Newtonsoft.Json; +using Zxd.Core.Domain.Dto.Contract; +using Zxd.Core.Domain.Dto.Crm; +using Zxd.Entity.Crm; +using Zxd.Entity.Dncms; +using Zxd.Entity.Zxd; +using Zxd.Entity.Zxd.Order; + +namespace Zxd.Domain +{ + public class ProductDomain : IProdcutDomain + { + private readonly IBaseRepository _crmRepository; + private readonly IBaseRepository _zxdRepository; + private readonly IBaseRepository _repository; + private readonly IRedisManager _redisManager; + private readonly IDeptmentDomain _deptmentDomain; + private readonly IMapper _mapper; + private readonly IHttpClient _httpClient; + private readonly SystemConfig _systemConfig; + private readonly IConfiguration _configuration; + + public ProductDomain(IBaseRepository crmRepository, + IBaseRepository zxdRepository, + IBaseRepository repository, + IRedisManager redisManager, + IDeptmentDomain deptmentDomain, + IConfiguration configuration, + IHttpClient httpClient, + IMapper mapper) + { + _crmRepository = crmRepository; + _zxdRepository = zxdRepository; + _redisManager = redisManager; + _deptmentDomain = deptmentDomain; + _httpClient = httpClient; + _repository = repository; + _configuration = configuration; + _mapper = mapper; + _systemConfig = _configuration.GetSection("SystemConfig").Get(); + } + + #region 下拉列表 + + public async Task> GetProductGroupSelect() + { + var data = new List(); + /* var key = CacheKeys.ProductGroupList; + if (!await _redisManager.ExistsAsync(key)) + { + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id, item.Name ?? "")); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromHours(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + }*/ + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id, item.Name ?? "")); + } + return data; + } + + public async Task> GetModuleSelect() + { + var data = new List(); + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id ?? "", $"{item.Name}/{item.Id}")); + } + return data; + /* var key = CacheKeys.ProductModuleList; + if (!await _redisManager.ExistsAsync(key)) + { + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id ?? "", $"{item.Name}/{item.Id}")); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromHours(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + } + + return data;*/ + } + + public async Task> GetProductTeacherSelect() + { + var data = new List(); + /*var key = CacheKeys.ProductTeacherList; + if (!await _redisManager.ExistsAsync(key)) + { + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Code ?? "", $"{item.Name}({item.Code})")); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromHours(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + }*/ + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Code ?? "", $"{item.Name}({item.Code})")); + } + return data; + } + + public async Task> GetProductSelect() + { + var data = new List(); + /* var key = CacheKeys.ProductList; + if (!await _redisManager.ExistsAsync(key)) + { + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id ?? "", $"{item.Name}/{item.Moduleid}/{item.Day}/{item.Price}")); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromHours(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + }*/ + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id ?? "", $"{item.Name}/{item.Moduleid}/{item.Day}/{item.Price}")); + } + return data; + } + + public async Task> GetStandardTypeSelect() + { + var key = CacheKeys.StandardType; + var data = new List(); + if (!await _redisManager.ExistsAsync(key)) + { + foreach (StandardType item in Enum.GetValues(typeof(StandardType))) + { + data.Add(new SelectItem(item, item.GetDescription())); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromDays(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + } + + return data; + } + + #endregion 下拉列表 + + #region 基础产品 + + public async Task> ProductPage(SearchProductDto dto) + { + var query = _crmRepository.GetRepository().Query() + .If(!string.IsNullOrEmpty(dto.ProductCode), x => x.Where(y => y.Id == dto.ProductCode)) + .If(!string.IsNullOrEmpty(dto.ProductName), x => x.Where(y => y.Name.Contains(dto.ProductName))) + .If(!string.IsNullOrEmpty(dto.ProductModule), x => x.Where(y => y.Moduleid == dto.ProductModule)) + .If(dto.Active.HasValue, x => x.Where(y => y.Active == dto.Active)) + .Include(x => x.ProductGroup) + .Include(x => x.Module); + + var total = await query.CountAsync(); + var data = await query + .OrderByDescending(x => x.Id) + .Select(x => new ProductDto + { + Id = x.Pk, + ProdcutCode = x.Id, + Price = $"{x.Price:0.00}元", + ProdcutName = x.Name, + ProdcutType = x.ProductGroup.Name, + ProductModule = $"{x.Module.Name}【{x.Moduleid}】【{x.Day}】", + Day = $"{x.Day}天", + Status = x.Active == 1 ? "已上线" : x.Active == 2 ? "已下架" : "未上线", + Ctime = x.Ctime.ToString("yyyy-MM-dd HH:mm:ss"), + EffectiveImmediately = x.EffectiveImmediately.Value ? "是" : "否" + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + /// + /// 基础产品编辑 + /// + /// + /// + /// + public async Task ProductEdit(ChangeProductStatusDto dto) + { + ProductEdit res = new ProductEdit(); + //枚举值 + + //产品下拉框 处理 + res.Group = await GetProductGroupSelect(); + res.Module = await GetModuleSelect(); + res.Teacher = await GetProductTeacherSelect(); + res.Dept = await _deptmentDomain.GetDeptments(); + + if (string.IsNullOrWhiteSpace(dto.ProductCode)) + { + return res; + } + + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == dto.ProductCode); + if (product == null) + { + throw new ApiException("产品不存在或已删除!"); + } + res.ProductModule = product.Moduleid; + res.ProductCode = product.Id; + res.ProductName = product.Name; + res.Free = product.Id.IndexOf("_MFTY") > 0 ? true : false; + res.Price = product.Price; + res.EffectiveImmediately = product.EffectiveImmediately; + res.ProductType = product.Groupid; + res.Day = product.Day; + res.Status = product.Active; + var teacherList = await _crmRepository.GetRepository().Query() + .Include(x => x.Teacher) + .Where(n => n.ProductId == product.Id).ToListAsync(); + var deptGroup = teacherList.Select(n => n.Deptid).Distinct().ToList(); + var deptments = await _repository.GetRepository().Query().Where(n => deptGroup.Contains(n.Id)).ToListAsync(); + List proTeacherInfos = new List(); + foreach (var deptid in deptGroup) + { + var teachers = teacherList.Where(n => n.Deptid == deptid).ToList(); + ProTeacherInfo teaInfo = new ProTeacherInfo + { + dept_val = deptid, + dept_txt = deptments.FirstOrDefault(n => n.Id == deptid)?.Title + }; + List tealist = new List(); + foreach (var tea in teachers) + { + tealist.Add(new teacherInfo + { + code = tea.Teacher.Code, + name = tea.Teacher.Name + }); + } + teaInfo.teacherInfos = tealist; + proTeacherInfos.Add(teaInfo); + } + res.ProTeacherInfo = proTeacherInfos; + return res; + } + + public async Task InactiveProduct(string code) + { + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == code); + if (product != null) + { + product.Active = 0; + await _crmRepository.GetRepository().UpdateAsync(product); + return; + } + throw new ApiException("产品不存在或已删除!"); + } + + public async Task ActiveProduct(string code) + { + var product = await _crmRepository.GetRepository().Query() + .Include(x => x.Module) + .FirstOrDefaultAsync(x => x.Id == code); + if (product == null) + { + throw new ApiException("产品不存在或已删除!"); + } + var url = $"{_systemConfig.GetActiveProduct()}?flag=mod&online=up&active=1&productpk={product.Pk}&productid={product.Id}&productname={product.Name}&modulename={product.Module?.Name}&moduleid={product.Moduleid}&price={product.Price}&day={product.Day}"; + var result = await _httpClient.GetAsync(url); + if (result != null && result.result) + { + return; + } + throw new Exception("请求优品接口出错"); + } + + public async Task DownProduct(string code) + { + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == code); + if (product != null) + { + product.Active = 2; + await _crmRepository.GetRepository().UpdateAsync(product); + return; + } + throw new ApiException("产品不存在或已删除!"); + } + + public async Task CreateProduct(CreateProductDto dto) + { + var time = DateTime.Now.ToString("yyyyMMddhhmm"); + var count = 0; + string key = "UPCFJC_" + time; + if (!await _redisManager.ExistsAsync(key))//不存在 + { + count++; + await _redisManager.SetAsync(key, count, TimeSpan.FromMinutes(5)); + } + else + { + count = await _redisManager.GetAsync(key); + count++; + await _redisManager.SetAsync(key, count, TimeSpan.FromMinutes(5)); + } + var code = $"UPCFJC_{time}{(count < 10 ? ("0" + count) : count.ToString())}" + (dto.Free ? "_MFTY" : ""); + + //if (!string.IsNullOrWhiteSpace(dto.ProductCode)) + //{ + // List orderStatus = new List + // { + // "220","205","80","90" + // }; + // var existModel = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.PRODUCTCODE == dto.ProductCode && orderStatus.Contains(n.ORDERSTATUS)); + // if (existModel != null) + // { + // throw new ApiException("已开通订单的产品不让编辑!"); + // } + //} + var oldCode = dto.ProductCode; + var productCode = string.Empty; + if (!string.IsNullOrWhiteSpace(dto.ProductCode) && (!dto.Free && dto.ProductCode.Contains("_MFTY") || dto.Free && !dto.ProductCode.Contains("_MFTY"))) + { + dto.ProductCode = ""; + } + if (string.IsNullOrWhiteSpace(dto.ProductCode)) + { + productCode = code; + var product = new Product + { + Id = code, + Name = dto.ProductName, + Moduleid = dto.ProductModule.ToString(), + Price = dto.Price, + Groupid = dto.ProductType, + Ctime = DateTime.Now, + UpdateTime = DateTime.Now, + EffectiveImmediately = dto.AutoOpen, + BusinessType = 1, + Day = dto.Day, + Active = 2, + Old = false, + Compliance = true + }; + var baseProduct = new BaseProduct + { + Code = code, + Name = dto.ProductName, + Moduleid = dto.ProductModule.ToString(), + Price = dto.Price, + Groupid = dto.ProductType, + Ctime = DateTime.Now, + UpdateTime = DateTime.Now, + EffectiveImmediately = dto.AutoOpen, + Day = dto.Day, + Active = 2, + }; + // 新增优品信息 + using var transaction = await _crmRepository.BeginTransactionAsync(); + try + { + //删除产品后再新加 + if (!string.IsNullOrEmpty(oldCode)) + { + var oldproduct = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == oldCode); + await _crmRepository.GetRepository().DeleteAsync(oldproduct); + var oldTeacher = await _crmRepository.GetRepository().Query().Where(n => n.ProductId == oldproduct.Id).ToListAsync(); + await _crmRepository.GetRepository().BatchDeleteAsync(oldTeacher); + var oldbaseProduct = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Code == oldproduct.Id); + // 删除千托信息 + await _zxdRepository.GetRepository().DeleteAsync(oldbaseProduct); + } + if (dto.Teachers != null && dto.Teachers.Any()) + { + foreach (var productTeacher in dto.Teachers) + { + if (productTeacher.TeacherCodes == null) continue; + foreach (var teacher in productTeacher.TeacherCodes) + { + await _crmRepository.GetRepository().InsertAsync(new ProductTeacher + { + Deptid = productTeacher.Deptid, + CreateTime = DateTime.Now, + UpdateTime = DateTime.Now, + IsPacks = false, + ProductId = code, + TeacherCode = teacher + }); + } + } + } + await _crmRepository.GetRepository().InsertAsync(product); + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + Log.Error(ex, "添加基础产品错误!"); + throw; + } + // 新增千托信息 + await _zxdRepository.GetRepository().InsertAsync(baseProduct); + } + else + { + productCode = dto.ProductCode; + //更新优品信息 + using var transaction = await _crmRepository.BeginTransactionAsync(); + var product = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == dto.ProductCode); + if (product == null) + { + throw new ApiException("产品不存在或已删除!"); + } + product.Name = dto.ProductName; + product.Moduleid = dto.ProductModule.ToString(); + product.Price = dto.Price; + product.Groupid = dto.ProductType; + product.Ctime = DateTime.Now; + product.UpdateTime = DateTime.Now; + product.EffectiveImmediately = dto.AutoOpen; + product.Day = dto.Day; + code = product.Id; + product.Active = 2; + try + { + //老师处理 + var oldTeacher = await _crmRepository.GetRepository().Query().Where(n => n.ProductId == product.Id).ToListAsync(); + if (dto.Teachers != null && dto.Teachers.Any()) + { + foreach (var productTeacher in dto.Teachers) + { + if (productTeacher.TeacherCodes == null) continue; + foreach (var teacher in productTeacher.TeacherCodes) + { + await _crmRepository.GetRepository().InsertAsync(new ProductTeacher + { + Deptid = productTeacher.Deptid, + CreateTime = DateTime.Now, + UpdateTime = DateTime.Now, + IsPacks = false, + ProductId = code, + TeacherCode = teacher + }); + } + } + } + await _crmRepository.GetRepository().BatchDeleteAsync(oldTeacher); + await _crmRepository.GetRepository().UpdateAsync(product); + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + Log.Error(ex, "修改基础产品错误!"); + throw; + } + //更新千托信息 + var baseProduct = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Code == dto.ProductCode); + if (baseProduct != null) + { + baseProduct.Code = code; + baseProduct.Name = dto.ProductName; + baseProduct.Moduleid = dto.ProductModule.ToString(); + baseProduct.Price = dto.Price; + baseProduct.Groupid = dto.ProductType; + baseProduct.UpdateTime = DateTime.Now; + baseProduct.EffectiveImmediately = dto.AutoOpen; + baseProduct.Day = dto.Day; + baseProduct.Active = 2; + // 新增千托信息 + await _zxdRepository.GetRepository().UpdateAsync(baseProduct); + } + } + return productCode; + } + + /// + /// 批量导入产品 + /// + /// + /// + public async Task> ImportPreview(List dto) + { + List res = new List(); + //权限 + var moduleList = await _crmRepository.GetRepository().Query().Where(n => dto.Select(x => x.ProductModule).Contains(n.Id)).ToListAsync(); + //类型 + var productGroupList = await _crmRepository.GetRepository().Query().Where(n => dto.Select(x => x.ProductType).Contains(n.Name)).ToListAsync(); + var deptList = await _deptmentDomain.GetDeptments(); + var teacherList = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in dto) + { + ImportBasicsProductViewModel newModel = new ImportBasicsProductViewModel + { + ProductName = item.ProductName, + Free = item.Free == "否" ? false : true, + }; + res.Add(newModel); + if (string.IsNullOrWhiteSpace(item.ProductName)) + { + newModel.Msg = "产品名称不能为空"; + continue; + } + if (string.IsNullOrWhiteSpace(item.Price)) + { + newModel.Msg = "价格不能为空"; + continue; + } + if (string.IsNullOrWhiteSpace(item.Day)) + { + newModel.Msg = "时长不能为空"; + continue; + } + try + { + //校验 + var productType = productGroupList.FirstOrDefault(n => n.Name == item.ProductType); + if (productType == null) + { + newModel.Msg = "找不到对应的产品类型"; + continue; + } + newModel.ProductType = productType.Id; + newModel.ProductTypeName = productType.Name; + var module = moduleList.FirstOrDefault(n => n.Id == item.ProductModule); + if (module == null) + { + newModel.Msg = "找不到对应的权限Id"; + continue; + } + newModel.ProductModule = module.Id; + newModel.ProductModuleName = module.Name; + + newModel.Price = Convert.ToDouble(item.Price); + newModel.Day = Convert.ToInt32(item.Day); + newModel.AutoOpen = false; + if (!string.IsNullOrWhiteSpace(item.Teachers)) + { + List teaList = new List(); + var deptSpilt = item.Teachers.Split(";"); + foreach (var deptstr in deptSpilt) + { + ImportProductTeacherDto teacherDto = new ImportProductTeacherDto(); + Regex reg1 = new Regex(".*?(?=\\()"); + var deptId = reg1.Match(deptstr); + if (deptId != null) + { + var deptItem = deptList.FirstOrDefault(n => n.Title == deptId.Value); + if (deptItem == null) + { + newModel.Msg = $"找不到对应的事业部"; + continue; + } + else + { + teacherDto.Deptid = deptItem.Id; + teacherDto.DeptName = deptItem?.Title; + } + } + Regex reg2 = new Regex("(?<=\\()(\\S+)(?=\\))"); + var teacherStr = reg2.Match(deptstr); + if (teacherStr != null) + { + var teacherItem = teacherStr.Value.Split(",").ToList(); + foreach (var tea in teacherItem) + { + var teacher = teacherList.FirstOrDefault(n => n.Code == tea || tea == n.Name); + if (teacher != null) + { + TeacherInfo teacherInfo = new TeacherInfo() + { + Code = teacher.Code, + Name = teacher.Name + }; + teacherDto.TeacherCodes.Add(teacherInfo); + } + else + { + newModel.Msg = $"找不到对应的老师{tea}"; + } + } + teaList.Add(teacherDto); + } + } + newModel.Teachers = teaList; + } + } + catch (Exception ex) + { + newModel.Msg = $"数据不合法{ex.Message}"; + } + } + return res; + } + + /// + /// 导入 + /// + /// + /// + public async Task ImportProduct(List dto) + { + foreach (var item in dto) + { + await CreateProduct(item); + Thread.Sleep(1000); + } + } + + public async Task> ImportCombinationProductPreview(List dto) + { + List res = new List(); + //类型 + var productGroupList = await _crmRepository.GetRepository().Query().Where(n => dto.Select(x => x.ProductType).Contains(n.Name)).ToListAsync(); + var deptList = await _deptmentDomain.GetDeptments(); + var teacherList = await _crmRepository.GetRepository().QueryListAsync(); + List productCodeList = new List(); + foreach (var item in dto) + { + productCodeList.AddRange(item.ProductCodes.Split(",").Where(n => !string.IsNullOrWhiteSpace(n)).ToList()); + } + var productList = await _crmRepository.GetRepository().Query().Where(n => productCodeList.Contains(n.Id)).ToListAsync(); + foreach (var item in dto) + { + ImportCombinationViewModel newModel = new ImportCombinationViewModel + { + ProductName = item.ProductName, + Free = item.Free == "否" ? false : true, + }; + res.Add(newModel); + if (string.IsNullOrWhiteSpace(item.ProductName)) + { + newModel.Msg = "产品名称不能为空"; + continue; + } + if (string.IsNullOrWhiteSpace(item.Price)) + { + newModel.Msg = "价格不能为空"; + continue; + } + if (string.IsNullOrWhiteSpace(item.ProductCodes)) + { + newModel.Msg = "子产品不能为空"; + continue; + } + try + { + //校验 + var productType = productGroupList.FirstOrDefault(n => n.Name == item.ProductType); + if (productType == null) + { + newModel.Msg = "找不到对应的产品类型"; + continue; + } + newModel.ProductType = productType.Id; + newModel.ProductTypeName = productType.Name; + var proCodes = item.ProductCodes.Split(",").ToList(); + List productInfos = new List(); + foreach (var code in proCodes) + { + var pro = productList.FirstOrDefault(n => n.Id == code); + if (pro == null) + { + newModel.Msg = $"找不到对应的子产品【{code}】"; + } + else + { + if (item.Free.ToLower() == "是" && pro.Price > 0) + { + newModel.Msg = "组合产品生产免费产品时,子产品必须都是免费产品!"; + } + productInfos.Add(new ProductInfo + { + Code = code, + Name = pro.Name, + Price = pro.Price + }); + } + } + newModel.ProductCodes = productInfos; + newModel.Price = Convert.ToDouble(item.Price); + newModel.AutoOpen = false; + if (!string.IsNullOrWhiteSpace(item.Teachers)) + { + List teaList = new List(); + var deptSpilt = item.Teachers.Split(";"); + foreach (var deptstr in deptSpilt) + { + ImportProductTeacherDto teacherDto = new ImportProductTeacherDto(); + Regex reg1 = new Regex(".*?(?=\\()"); + var deptId = reg1.Match(deptstr); + if (deptId != null) + { + var deptItem = deptList.FirstOrDefault(n => n.Title == deptId.Value); + if (deptItem == null) + { + newModel.Msg = $"找不到对应的事业部"; + continue; + } + else + { + teacherDto.Deptid = deptItem.Id; + teacherDto.DeptName = deptItem?.Title; + } + } + Regex reg2 = new Regex("(?<=\\()(\\S+)(?=\\))"); + var teacherStr = reg2.Match(deptstr); + if (teacherStr != null) + { + var teacherItem = teacherStr.Value.Split(",").ToList(); + foreach (var tea in teacherItem) + { + var teacher = teacherList.FirstOrDefault(n => n.Code == tea || tea == n.Name); + if (teacher != null) + { + TeacherInfo teacherInfo = new TeacherInfo() + { + Code = teacher.Code, + Name = teacher.Name + }; + teacherDto.TeacherCodes.Add(teacherInfo); + } + else + { + newModel.Msg = $"找不到对应的老师{tea}"; + } + } + teaList.Add(teacherDto); + } + } + newModel.Teachers = teaList; + } + } + catch (Exception ex) + { + newModel.Msg = $"数据不合法{ex.Message}"; + } + } + return res; + } + + public async Task SyncProduct() + { + var productList = await _crmRepository.GetRepository().QueryListAsync(); + var baseProductList = await _zxdRepository.GetRepository().QueryListAsync(); + foreach (var product in productList) + { + var baseProduct = baseProductList.FirstOrDefault(x => x.Code == product.Id); + if (baseProduct == null) + { + baseProduct = new BaseProduct + { + Code = product.Id, + Name = product.Name, + Price = product.Price, + Groupid = product.Groupid, + Ctime = product.Ctime, + EffectiveImmediately = product.EffectiveImmediately, + Moduleid = product.Moduleid, + AppImgUrl = product.AppImgUrl, + Day = product.Day, + Appextinfo = product.Appextinfo, + Appext = product.Appext, + Active = product.Active, + Compliance = product.Compliance, + Ext = product.Ext, + Extinfo = product.Extinfo, + Old = product.Old, + Remark = product.Remark, + UpdateTime = product.UpdateTime, + WebImgUrl = product.WebImgUrl + }; + + await _zxdRepository.GetRepository().InsertAsync(baseProduct); + continue; + } + if (baseProduct.Name != product.Name + || baseProduct.Price != product.Price + || baseProduct.Groupid != product.Groupid + || baseProduct.Ctime != product.Ctime + || baseProduct.EffectiveImmediately != product.EffectiveImmediately + || baseProduct.Active != product.Active + || baseProduct.Remark != product.Remark + || baseProduct.Appext != product.Appext + || baseProduct.Appextinfo != product.Appextinfo + || baseProduct.AppImgUrl != product.AppImgUrl + || baseProduct.Extinfo != product.Extinfo + || baseProduct.Old != product.Old + || baseProduct.WebImgUrl != product.WebImgUrl + || baseProduct.UpdateTime != product.UpdateTime) + { + baseProduct.Name = product.Name; + baseProduct.Price = product.Price; + baseProduct.Groupid = product.Groupid; + baseProduct.Ctime = product.Ctime; + baseProduct.EffectiveImmediately = product.EffectiveImmediately; + baseProduct.Active = product.Active; + baseProduct.Remark = product.Remark; + baseProduct.Appext = product.Appext; + baseProduct.Appextinfo = product.Appextinfo; + baseProduct.AppImgUrl = product.AppImgUrl; + baseProduct.Extinfo = product.Extinfo; + baseProduct.Old = product.Old; + baseProduct.WebImgUrl = product.WebImgUrl; + baseProduct.UpdateTime = product.UpdateTime; + await _zxdRepository.GetRepository().UpdateAsync(baseProduct); + } + } + } + + #endregion 基础产品 + + #region 组合产品 + + public async Task> ProductPackagePage(SearchProductDto dto) + { + var productCodes = new List(); + if (!string.IsNullOrEmpty(dto.ProductModule)) + { + productCodes = await _zxdRepository.GetRepository().Query() + .Where(x => x.Moduleid == dto.ProductModule) + .Select(x => x.PackageCode ?? "") + .Distinct() + .ToListAsync(); + } + var query = _crmRepository.GetRepository().Query() + .If(!string.IsNullOrEmpty(dto.ProductCode), x => x.Where(x => x.Id == dto.ProductCode)) + .If(!string.IsNullOrEmpty(dto.ProductName), x => x.Where(x => x.Name.Contains(dto.ProductName))) + .If(dto.Active.HasValue, x => x.Where(y => y.Active == dto.Active)) + .If(productCodes != null && productCodes.Any(), x => x.Where(x => productCodes.Contains(x.Id))) + .Include(x => x.ProductGroup); + + var total = await query.CountAsync(); + var data = await query + .OrderByDescending(x => x.Id) + .Select(x => new ProductPackageDto + { + Id = x.Pk, + ProdcutCode = x.Id, + Price = $"{x.Price:0.00}元", + ProdcutName = x.Name, + ProdcutType = x.ProductGroup.Name, + Status = x.Active == 1 ? "已上线" : x.Active == 2 ? "已下架" : "未上线", + Ctime = x.Ctime.ToString("yyyy-MM-dd HH:mm:ss"), + EffectiveImmediately = x.EffectiveImmediately.Value ? "是" : "否", + SubProductsInfo = x.SubProductsInfo + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + var codes = new List(); + data.ForEach(x => codes.AddRange(x.ProductCodes)); + codes = codes.Distinct().ToList(); + var products = await _crmRepository.GetRepository().Query() + .Include(x => x.Module) + .Include(x => x.ProductGroup) + .Where(x => codes.Contains(x.Id)) + .Select(x => new ProductDto + { + Id = x.Pk, + ProdcutCode = x.Id, + ProdcutName = x.Name, + ProdcutType = x.ProductGroup.Name, + ProductModule = $"{x.Module.Name}【{x.Moduleid}】【{x.Day}】" + }) + .ToListAsync(); + data.ForEach(x => + { + List modules = new List(); + foreach (var code in x.ProductCodes) + { + var pro = products.Where(y => code == y.ProdcutCode).FirstOrDefault(); + if (pro != null) + { + modules.Add(pro.ProductModule); + } + } + x.ProductModule = modules; + }); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + public async Task InactiveProductPackage(string code) + { + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == code); + if (product != null) + { + product.Active = 0; + await _crmRepository.GetRepository().UpdateAsync(product); + return; + } + throw new ApiException("产品不存在或已删除!"); + } + + public async Task DownProductPackage(string code) + { + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == code); + if (product != null) + { + product.Active = 2; + await _crmRepository.GetRepository().UpdateAsync(product); + return; + } + throw new ApiException("产品不存在或已删除!"); + } + + public async Task ActiveProductPackage(string code) + { + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == code); + if (product == null) + { + throw new ApiException("产品不存在或已删除!"); + } + var basProCodes = product.SubProducts.Split("|").ToList(); + var basproducts = await _crmRepository.GetRepository().Query().Where(n => basProCodes.Contains(n.Id)).ToListAsync(); + List moduleids = new List(); + foreach (var bascode in basProCodes) + { + var pro = basproducts.FirstOrDefault(n => n.Id == bascode); + if (pro != null) + { + moduleids.Add($"{pro.Moduleid}【{pro.Day}】"); + } + } + var url = $"{_systemConfig.GetActivePackage()}?flag=mod&online=up&active=1&productpk={product.Pk}&productid={product.Id}&productname={product.Name}&moduleids={string.Join(",", moduleids)}&price={product.Price}"; + var result = await _httpClient.GetAsync(url); + if (result != null && result.result) + { + return; + } + if (product != null) + { + product.Active = 1; + await _crmRepository.GetRepository().UpdateAsync(product); + return; + } + } + /// + /// 查找存在重复的产品 + /// + /// + /// + /// + /// + private string IsHasDayPackge(int days, string[] modules, int price) + { + var relations = _zxdRepository.GetRepository().Query().Where(m => modules.Contains(m.Moduleid) && m.Day == days).ToList().GroupBy(m => m.PackageCode); + foreach (var item in relations) + { + var packProduct = _zxdRepository.GetRepository().Query().Where(m => m.PackageCode == item.Key).ToList(); + if (modules.Where(m => !packProduct.Select(m => m.Moduleid).Contains(m)).Any())//如果不是完全匹配,那么表示产品不存在,可以创建 + continue; + if (packProduct.Where(m => !modules.Contains(m.Moduleid)).Any())//如果不是完全匹配,那么表示产品不存在,可以创建 + continue; + var pack = _zxdRepository.GetRepository().Query().FirstOrDefault(m => m.Code == item.Key); + if (pack != null && pack.Price == price) + { + return pack.Code; + } + + } + return ""; + + } + /// + /// 一键创建组合产品 + /// + /// + /// + /// + public async Task CreateSuperProductPackage(CreateSuperProductPackageDto dto) + { + //进行产品重复校验 + for (int i = 0; i < dto.prices.Length; i++) + { + string moduleId = dto.productModule[i]; + int day = Convert.ToInt32(dto.days[i]); + decimal price = Convert.ToDecimal(dto.prices[i]); + if (price == 0 && day > 1) + { + throw new Exception("金额为零的产品,必须只能是1天"); + } + var hasCode = IsHasDayPackge(Convert.ToInt32(dto.days[i]), dto.productModule, Convert.ToInt32(dto.prices[i])); + if (!string.IsNullOrEmpty(hasCode)) + { + throw new Exception("已有重复天数:" + dto.days[i] + "、金额:" + dto.prices[i] + ",产品ID:" + hasCode); + } + } + List packList = new List();//需要创建的组合产品 + //循环创建基础产品 + for (int i = 0; i < dto.prices.Length; i++) + { + + int day = Convert.ToInt32(dto.days[i]); + decimal price = Convert.ToDecimal(dto.prices[i]); + var pageckDto = new CreateProductPackageDto() + { + AutoOpen = dto.AutoOpen, + Day = day, + Free = dto.Free, + Price = price, + ProductCode = String.Empty, + ProductCodes = new List(), + ProductName = dto.ProductName, + ProductType = dto.ProductType, + Teachers = dto.Teachers + }; + foreach (var moduleId in dto.productModule)//循环创建子产品 + { + string productCode = string.Empty;// 产品编码 + BaseProduct baseProduct = null; + if (price > 0) + { + baseProduct = await _zxdRepository.GetRepository().Query().OrderByDescending(m => m.Active % 2).ThenByDescending(m => m.Id).FirstOrDefaultAsync(n => n.Moduleid == moduleId && n.Day == day && n.Price > 0); + } + else + { + baseProduct = await _zxdRepository.GetRepository().Query().OrderByDescending(m => m.Active % 2).ThenByDescending(m => m.Id).FirstOrDefaultAsync(n => n.Moduleid == moduleId && n.Day == day && n.Price == 0); + } + if (baseProduct == null)//找不到相关产品,那么就进行创建基础产品 + { + var module = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(m => m.Id == moduleId); + if (module == null) + throw new Exception(moduleId + "权限ID不存在"); + productCode = await CreateProduct(new CreateProductDto + { + AutoOpen = dto.AutoOpen, + Day = day, + Free = dto.Free, + Price = price, + ProductModule = Convert.ToInt32(moduleId), + ProductModules = new List() { moduleId }, + ProductName = module.Name + day + "天", + ProductCode = String.Empty, + ProductType = dto.ProductType, + Teachers = dto.Teachers + }); + + } + else + productCode = baseProduct.Code; + + pageckDto.ProductCodes.Add(new CreateProductCodeDto + { + Price = baseProduct != null ? baseProduct.Price : price, + ProductCode = productCode, + }); + await ActiveProduct(productCode);//上线产品 + } + packList.Add(pageckDto); + } + //循环创建组合产品 + foreach (var item in packList) + { + string packcode = await CreateProductPackage(item); + await ActiveProductPackage(packcode);//上线产品 + } + } + public async Task CreateProductPackage(CreateProductPackageDto dto) + { + var productPackCode = string.Empty; + var time = DateTime.Now.ToString("yyyyMMddhhmm"); + var count = 0; + string key = "UPCFZH_" + time; + if (!await _redisManager.ExistsAsync(key))//不存在 + { + count++; + await _redisManager.SetAsync(key, count, TimeSpan.FromMinutes(5)); + } + else + { + count = await _redisManager.GetAsync(key); + count++; + await _redisManager.SetAsync(key, count, TimeSpan.FromMinutes(5)); + } + var code = $"UPCFZH_{time}{(count < 10 ? ("0" + count) : count.ToString())}" + (dto.Free ? "_MFTY" : ""); + //if (!string.IsNullOrWhiteSpace(dto.ProductCode)) + //{ + // List orderStatus = new List + // { + // "220","205","80","90" + // }; + // var existModel = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.PRODUCTCODE == dto.ProductCode && orderStatus.Contains(n.ORDERSTATUS)); + // if (existModel != null) + // { + // throw new ApiException("已开通订单的产品不让编辑!"); + // } + //} + if (dto.ProductCodes == null || !dto.ProductCodes.Any()) + { + throw new ApiException("请选择产品权限!"); + } + var subProductsInfo = dto.ProductCodes.Select(x => + new SubProductJson + { + SubPrice = $"{x.Price:0.00}", + SubProductId = x.ProductCode + }).ToList().ToJson(); + if (dto.Free) + { + var productCodes = dto.ProductCodes.Select(x => x.ProductCode).ToList(); + if (await _zxdRepository.GetRepository().Query().Where(x => productCodes.Contains(x.Code)).AnyAsync(x => x.Price > 0)) + { + throw new ApiException("组合产品生产免费产品时,子产品必须都是免费产品!"); + } + } + var oldCode = dto.ProductCode; + if (!string.IsNullOrWhiteSpace(dto.ProductCode) && !dto.Free && dto.ProductCode.Contains("_MFTY") || dto.Free && !dto.ProductCode.Contains("_MFTY")) + { + dto.ProductCode = ""; + } + if (string.IsNullOrWhiteSpace(dto.ProductCode)) + { + productPackCode = code; + + var productPackage = new ProductPackage + { + Id = code, + Name = dto.ProductName, + Price = dto.Price, + Groupid = dto.ProductType, + Ctime = DateTime.Now, + UpdateTime = DateTime.Now, + EffectiveImmediately = dto.AutoOpen, + Old = false, + BusinessType = 1, + Active = 2, + SubProducts = string.Join("|", dto.ProductCodes.Select(x => x.ProductCode).ToList()), + SubProductsInfo = subProductsInfo + }; + var baseProductPackage = new BaseProductPackage + { + Code = code, + Name = dto.ProductName, + Price = dto.Price, + Groupid = dto.ProductType, + Ctime = DateTime.Now, + UpdateTime = DateTime.Now, + EffectiveImmediately = dto.AutoOpen, + Active = 2, + }; + using var transactionCrm = await _crmRepository.BeginTransactionAsync(); + using var transactionZxd = await _zxdRepository.BeginTransactionAsync(); + try + { + if (!string.IsNullOrWhiteSpace(oldCode)) + { + var oldproductPackage = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == oldCode); + await _crmRepository.GetRepository().DeleteAsync(oldproductPackage); + var oldTeacher = await _crmRepository.GetRepository().Query().Where(n => n.ProductId == oldCode).ToListAsync(); + await _crmRepository.GetRepository().BatchDeleteAsync(oldTeacher); + var oldbaseProductPackage = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Code == oldCode); + await _zxdRepository.GetRepository().DeleteAsync(oldbaseProductPackage); + var oldRelationList = await _zxdRepository.GetRepository().Query().Where(n => n.PackageCode == oldCode).ToListAsync(); + await _zxdRepository.GetRepository().BatchDeleteAsync(oldRelationList); + } + // 新增优品信息 + if (dto.Teachers != null && dto.Teachers.Any()) + { + foreach (var productTeacher in dto.Teachers) + { + if (productTeacher.TeacherCodes == null || !productTeacher.TeacherCodes.Any()) continue; + foreach (var teacher in productTeacher.TeacherCodes) + { + await _crmRepository.GetRepository().InsertAsync(new ProductTeacher + { + Deptid = productTeacher.Deptid, + CreateTime = DateTime.Now, + UpdateTime = DateTime.Now, + IsPacks = false, + ProductId = code, + TeacherCode = teacher + }); + } + } + } + await _crmRepository.GetRepository().InsertAsync(productPackage); + await transactionCrm.CommitAsync(); + + // 新增千托信息 + if (dto.ProductCodes != null && dto.ProductCodes.Any()) + { + foreach (var productCode in dto.ProductCodes) + { + var baseproduct = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(m => m.Id == productCode.ProductCode); + await _zxdRepository.GetRepository().InsertAsync(new BaseProductPackageRelation + { + PackageCode = code, + ProductCode = productCode.ProductCode, + Price = productCode.Price, + Day = baseproduct.Day, + Moduleid = baseproduct.Moduleid, + ProductName = baseproduct.Name + }); + } + } + await _zxdRepository.GetRepository().InsertAsync(baseProductPackage); + await transactionZxd.CommitAsync(); + } + catch (Exception ex) + { + await transactionCrm.RollbackAsync(); + await transactionCrm.DisposeAsync(); + await transactionZxd.RollbackAsync(); + await transactionZxd.DisposeAsync(); + Log.Error(ex, "添加组合产品错误!"); + throw; + } + } + else + { + productPackCode = dto.ProductCode; + var productPackage = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == dto.ProductCode); + + code = productPackage.Id; + productPackage.Name = dto.ProductName; + productPackage.Price = dto.Price; + productPackage.Groupid = dto.ProductType; + productPackage.UpdateTime = DateTime.Now; + productPackage.EffectiveImmediately = dto.AutoOpen; + productPackage.Active = 2; + + productPackage.SubProducts = string.Join("|", dto.ProductCodes.Select(x => x.ProductCode).ToList()); + + productPackage.SubProductsInfo = subProductsInfo; + using var transactionCrm = await _crmRepository.BeginTransactionAsync(); + using var transactionZxd = await _zxdRepository.BeginTransactionAsync(); + + try + { + var oldTeacher = await _crmRepository.GetRepository().Query().Where(n => n.ProductId == code).ToListAsync(); + // 新增优品信息 + if (dto.Teachers != null && dto.Teachers.Any()) + { + foreach (var productTeacher in dto.Teachers) + { + if (productTeacher.TeacherCodes == null || !productTeacher.TeacherCodes.Any()) continue; + foreach (var teacher in productTeacher.TeacherCodes) + { + await _crmRepository.GetRepository().InsertAsync(new ProductTeacher + { + Deptid = productTeacher.Deptid, + CreateTime = DateTime.Now, + UpdateTime = DateTime.Now, + IsPacks = false, + ProductId = code, + TeacherCode = teacher + }); + } + } + } + await _crmRepository.GetRepository().BatchDeleteAsync(oldTeacher); + await _crmRepository.GetRepository().UpdateAsync(productPackage); + await transactionCrm.CommitAsync(); + + // 新增千托信息 + var baseProductPackage = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Code == dto.ProductCode); + if (baseProductPackage != null) + { + baseProductPackage.Code = code; + baseProductPackage.Name = dto.ProductName; + baseProductPackage.Price = dto.Price; + baseProductPackage.Groupid = dto.ProductType; + baseProductPackage.UpdateTime = DateTime.Now; + baseProductPackage.EffectiveImmediately = dto.AutoOpen; + baseProductPackage.Active = 2; + await _zxdRepository.GetRepository().UpdateAsync(baseProductPackage); + } + else + { + baseProductPackage = new BaseProductPackage + { + Code = code, + Name = dto.ProductName, + Price = dto.Price, + Groupid = dto.ProductType, + Ctime = DateTime.Now, + UpdateTime = DateTime.Now, + EffectiveImmediately = dto.AutoOpen, + Active = 2, + }; + await _zxdRepository.GetRepository().InsertAsync(baseProductPackage); + } + var oldRelationList = await _zxdRepository.GetRepository().Query().Where(n => n.PackageCode == dto.ProductCode).ToListAsync(); + if (dto.ProductCodes != null && dto.ProductCodes.Any()) + { + foreach (var productCode in dto.ProductCodes) + { + var baseproduct = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(m => m.Id == productCode.ProductCode); + await _zxdRepository.GetRepository().InsertAsync(new BaseProductPackageRelation + { + PackageCode = code, + ProductCode = productCode.ProductCode, + Price = productCode.Price, + Day = baseproduct.Day, + Moduleid = baseproduct.Moduleid, + ProductName = baseproduct.Name + }); + } + } + await _zxdRepository.GetRepository().BatchDeleteAsync(oldRelationList); + await transactionZxd.CommitAsync(); + } + catch (Exception ex) + { + await transactionCrm.RollbackAsync(); + await transactionCrm.DisposeAsync(); + await transactionZxd.RollbackAsync(); + await transactionZxd.DisposeAsync(); + Log.Error(ex, "更新组合产品错误!"); + throw; + } + } + return productPackCode; + } + + /// + /// 组合产品编辑 + /// + /// + /// + public async Task EditProductPackage(ChangeProductStatusDto dto) + { + EditProductPackageDto res = new EditProductPackageDto(); + //产品下拉框 处理 + res.Group = await GetProductGroupSelect(); + res.Module = await GetModuleSelect(); + res.Teacher = await GetProductTeacherSelect(); + res.Dept = await _deptmentDomain.GetDeptments(); + res.ProductList = await _crmRepository.GetRepository().Query().OrderByDescending(x => x.Id) + .Select(x => new ProductDto + { + Id = x.Pk, + ProdcutCode = x.Id, + Price = $"{x.Price:0.00}元", + ProdcutName = x.Name, + ProdcutType = x.ProductGroup.Name, + ProductModule = $"{x.Module.Name}【{x.Moduleid}】【{x.Day}】", + Day = $"{x.Day}天", + Status = x.Active == 1 ? "已上线" : "未上线", + Ctime = x.Ctime.ToString("yyyy-MM-dd HH:mm:ss"), + EffectiveImmediately = x.EffectiveImmediately.Value ? "是" : "否" + }).ToListAsync(); + if (string.IsNullOrWhiteSpace(dto.ProductCode)) + { + return res; + } + var product = await _crmRepository.GetRepository().Query() + .FirstOrDefaultAsync(x => x.Id == dto.ProductCode); + if (product == null) + { + throw new ApiException("产品不存在或已删除!"); + } + var subCodes = product.SubProductCodes; + var subProductList = await _crmRepository.GetRepository().Query().Where(n => subCodes.Contains(n.Id)).ToListAsync(); + List subProCodes = new List(); + foreach (var subpro in subProductList) + { + subProCodes.Add(new CreateProductCodeDto + { + Price = (decimal)subpro.Price, + ProductCode = subpro.Id + }); + } + res.ProductCode = product.Id; + res.ProductCodes = subProCodes; + res.ProductName = product.Name; + res.Free = product.Id.IndexOf("_MFTY") > 0 ? true : false; + res.Price = product.Price; + res.EffectiveImmediately = product.EffectiveImmediately; + res.ProductType = product.Groupid; + res.Status = product.Active; + var teacherList = await _crmRepository.GetRepository().Query() + .Include(x => x.Teacher) + .Where(n => n.ProductId == product.Id).ToListAsync(); + var deptGroup = teacherList.Select(n => n.Deptid).Distinct().ToList(); + var deptments = await _repository.GetRepository().Query().Where(n => deptGroup.Contains(n.Id)).ToListAsync(); + List proTeacherInfos = new List(); + foreach (var deptid in deptGroup) + { + var teachers = teacherList.Where(n => n.Deptid == deptid).ToList(); + ProTeacherInfo teaInfo = new ProTeacherInfo + { + dept_val = deptid, + dept_txt = deptments.FirstOrDefault(n => n.Id == deptid)?.Title + }; + List tealist = new List(); + foreach (var tea in teachers) + { + tealist.Add(new teacherInfo + { + code = tea.Teacher.Code, + name = tea.Teacher.Name + }); + } + teaInfo.teacherInfos = tealist; + proTeacherInfos.Add(teaInfo); + } + res.ProTeacherInfo = proTeacherInfos; + return res; + } + + public async Task SyncProductPackage() + { + var productPackageList = await _crmRepository.GetRepository().QueryListAsync(); + var baseProductPackageList = await _zxdRepository.GetRepository().QueryListAsync(); + foreach (var productPackage in productPackageList) + { + var baseProductPackage = baseProductPackageList.FirstOrDefault(x => x.Code == productPackage.Id); + if (baseProductPackage == null) + { + baseProductPackage = new BaseProductPackage + { + Code = productPackage.Id, + Name = productPackage.Name, + Price = productPackage.Price, + Groupid = productPackage.Groupid, + Ctime = productPackage.Ctime, + EffectiveImmediately = productPackage.EffectiveImmediately, + Remark = productPackage.Remark, + Appext = productPackage.Appext, + Appextinfo = productPackage.Appextinfo, + AppImgUrl = productPackage.AppImgUrl, + Extinfo = productPackage.Extinfo, + Old = productPackage.Old, + WebImgUrl = productPackage.WebImgUrl, + UpdateTime = productPackage.UpdateTime, + Active = productPackage.Active, + }; + + if (productPackage.SubProducts != null && productPackage.SubProductsInfos != null) + { + var productCodes = productPackage.SubProducts.Split('|'); + foreach (var subProduct in productPackage.SubProductsInfos) + { + var product = await _crmRepository.GetRepository().Query() + .Where(x => x.Id == subProduct.SubProductId) + .FirstOrDefaultAsync(); + await _zxdRepository.GetRepository().InsertAsync(new BaseProductPackageRelation + { + PackageCode = productPackage.Id, + Price = !string.IsNullOrEmpty(subProduct.SubPrice) && decimal.TryParse(subProduct.SubPrice, out decimal price) ? price : 0, + ProductCode = subProduct.SubProductId, + Moduleid = product?.Moduleid, + Day = product?.Day, + ProductName = product?.Name + }); + } + } + await _zxdRepository.GetRepository().InsertAsync(baseProductPackage); + continue; + } + if (baseProductPackage.Name != productPackage.Name + || baseProductPackage.Price != productPackage.Price + || baseProductPackage.Groupid != productPackage.Groupid + || baseProductPackage.Ctime != productPackage.Ctime + || baseProductPackage.EffectiveImmediately != productPackage.EffectiveImmediately + || baseProductPackage.Active != productPackage.Active + || baseProductPackage.Remark != productPackage.Remark + || baseProductPackage.Appext != productPackage.Appext + || baseProductPackage.Appextinfo != productPackage.Appextinfo + || baseProductPackage.AppImgUrl != productPackage.AppImgUrl + || baseProductPackage.Extinfo != productPackage.Extinfo + || baseProductPackage.Old != productPackage.Old + || baseProductPackage.WebImgUrl != productPackage.WebImgUrl + || baseProductPackage.UpdateTime != productPackage.UpdateTime) + { + baseProductPackage.Name = productPackage.Name; + baseProductPackage.Price = productPackage.Price; + baseProductPackage.Groupid = productPackage.Groupid; + baseProductPackage.Ctime = productPackage.Ctime; + baseProductPackage.EffectiveImmediately = productPackage.EffectiveImmediately; + baseProductPackage.Active = productPackage.Active; + baseProductPackage.Remark = productPackage.Remark; + baseProductPackage.Appext = productPackage.Appext; + baseProductPackage.Appextinfo = productPackage.Appextinfo; + baseProductPackage.AppImgUrl = productPackage.AppImgUrl; + baseProductPackage.Extinfo = productPackage.Extinfo; + baseProductPackage.Old = productPackage.Old; + baseProductPackage.WebImgUrl = productPackage.WebImgUrl; + baseProductPackage.UpdateTime = productPackage.UpdateTime; + await _zxdRepository.GetRepository().UpdateAsync(baseProductPackage); + } + } + } + + #endregion 组合产品 + + #region 基准产品 + + public async Task GetBaseProduct(string code) + { + if (string.IsNullOrEmpty(code)) + { + throw new ApiException("产品编码不能为空!"); + } + + var product = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .Include(x => x.Module) + .FirstOrDefaultAsync(x => x.Id == code); + var productPackage = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .FirstOrDefaultAsync(x => x.Id == code); + if (product == null && productPackage == null) + { + throw new ApiException("产品不存在或已删除!"); + } + + if (product != null) + { + return new BaseProductInfoDto + { + Code = product.Id, + Day = product.Day ?? 0, + Price = (decimal)product.Price, + ProductName = product.Name ?? "", + ProductProperty = "基础产品", + ProductType = product.ProductGroup?.Name ?? "", + Status = product.Active == 1 ? "已上线" : "未上线", + ProductModules = new List() { product.Moduleid ?? "" } + }; + } + + if (productPackage != null) + { + var productCodes = string.IsNullOrEmpty(productPackage.SubProducts) ? new List() + : productPackage.SubProducts.Split('|').ToList(); + var data = new BaseProductInfoDto + { + Code = productPackage.Id, + Price = (decimal)productPackage.Price, + ProductName = productPackage.Name ?? "", + ProductProperty = "组合产品", + ProductType = productPackage.ProductGroup?.Name ?? "", + Status = productPackage.Active == 1 ? "已上线" : "未上线" + }; + if (productCodes.Any()) + { + var productList = await _crmRepository.GetRepository().Query() + .Where(x => productCodes.Contains(x.Id)) + .ToListAsync(); + data.Day = productList.Sum(x => x.Day ?? 0); + data.ProductModules = productList.Select(x => x.Moduleid ?? "").ToList(); + } + return data; + } + + return new BaseProductInfoDto(); + } + + public async Task CreateStandardProduct(CreateStandardProductDto dto) + { + if (string.IsNullOrEmpty(dto.ProductCode)) + { + throw new ApiException("产品编码不能为空!"); + } + var code = dto.ProductCode; + var product = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .Include(x => x.Module) + .FirstOrDefaultAsync(x => x.Id == code); + var productPackage = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .FirstOrDefaultAsync(x => x.Id == code); + if (product == null && productPackage == null) + { + throw new ApiException("产品不存在或已删除!"); + } + var standardProduct = new StandardProduct + { + ProductCode = product != null ? dto.ProductCode : null, + ProductPackageCode = productPackage != null ? dto.ProductCode : null, + StandardType = (StandardType)dto.StandardType, + Way = dto.StandardWay, + CreateTime = DateTime.Now + }; + + await _zxdRepository.GetRepository().InsertAsync(standardProduct); + } + + public async Task> StandardProductPage(SearchStandardProductDto dto) + { + var productCodes = new List(); + var productPackageCodes = new List(); + if (!string.IsNullOrEmpty(dto.ProductName)) + { + productCodes = await _crmRepository.GetRepository().Query() + .Where(x => x.Name.Contains(dto.ProductName)) + .Select(x => x.Id) + .ToListAsync(); + + productPackageCodes = await _crmRepository.GetRepository().Query() + .Where(x => x.Name.Contains(dto.ProductName)) + .Select(x => x.Id) + .ToListAsync(); + } + var query = _zxdRepository.GetRepository().Query() + .If(dto.Id != null, x => x.Where(x => x.Id == dto.Id)) + .If(dto.StandardType != null, x => x.Where(x => x.StandardType == (StandardType)dto.StandardType)) + .If(productCodes.Any(), x => x.Where(x => productCodes.Contains(x.ProductCode))) + .If(productPackageCodes.Any(), x => x.Where(x => productPackageCodes.Contains(x.ProductPackageCode))) + .Include(x => x.FinishedProducts); + + var total = await query.CountAsync(); + var data = await query + .Select(x => new StandardProductDto + { + Id = x.Id, + CreateTime = x.CreateTime, + StandardProductType = ((StandardType)x.StandardType).GetDescription(), + ProductCode = string.IsNullOrEmpty(x.ProductCode) ? x.ProductPackageCode : x.ProductCode, + ProductProperty = string.IsNullOrEmpty(x.ProductCode) ? "组合产品" : "基础产品", + FinishedProductCount = x.FinishedProducts == null ? 0 : x.FinishedProducts.Count + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + + var productList = new List(); + var productPackageList = new List(); + var productPackageProductList = new List(); + if (data.Any()) + { + productList = await _crmRepository.GetRepository().Query() + .Where(x => data.Select(y => y.ProductCode).Contains(x.Id)) + .Include(x => x.Module) + .Include(x => x.ProductGroup) + .ToListAsync(); + productPackageList = await _crmRepository.GetRepository().Query() + .Where(x => data.Select(y => y.ProductCode).Contains(x.Id)) + .Include(x => x.ProductGroup) + .ToListAsync(); + if (productPackageList.Any()) + { + var productPackageProductCodes = new List(); + productPackageList.ForEach(x => + { + if (x.SubProductCodes != null && x.SubProductCodes.Any()) + { + productPackageCodes.AddRange(x.SubProductCodes); + } + }); + productPackageProductList = await _crmRepository.GetRepository().Query() + .Where(x => productPackageProductCodes.Contains(x.Id)) + .Include(x => x.Module) + .Include(x => x.ProductGroup) + .ToListAsync(); + } + } + data.ForEach(x => + { + var product = productList.FirstOrDefault(y => y.Id == x.ProductCode); + var productPackage = productPackageList.FirstOrDefault(y => y.Id == x.ProductCode); + if (product != null) + { + x.Day = product.Day.ToString(); + x.Price = $"{product.Price:0:00}元"; + x.StandardProductName = product.Name; + x.Status = product.Active == 1 ? "已上线" : "未上线"; + x.StandardProductModule = new List { $"{product.Module.Name}【{product.Moduleid}】【{product.Day}】" }; + } + if (productPackage != null) + { + var productPackageProducts = productPackageProductList + .Where(y => productPackage.SubProductCodes.Contains(y.Id)).ToList(); + x.Day = string.Join("/", productPackageProducts.Select(x => x.Day).ToList()); + x.Price = $"{productPackage.Price:0:00}元"; + x.StandardProductName = productPackage.Name; + x.Status = productPackage.Active == 1 ? "已上线" : "未上线"; + x.StandardProductModule = productPackageProducts.Select(y => $"{y.Module.Name}【{y.Moduleid}】【{y.Day}】").ToList(); + } + }); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + public async Task ImportCombinationProduct(List dto) + { + foreach (var product in dto) + { + await CreateProductPackage(product); + Thread.Sleep(1000); + } + } + + #endregion 基准产品 + + #region 合同相关 + + /// + /// 获取合同地址 免费活动订单需传自定义的产品名 + /// + /// + /// + /// + /// + public async Task GetContractByFreeOrderId(decimal ordeid) + { + var orderInfo = await GetContractOrderInfo(ordeid); + + var product = await GetProductInfo(orderInfo.productcode);// _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.productcode == freeOrder.subproductcode);//合同地址 + if (product == null) + { + throw new Exception("找不到对应的产品"); + } + var urlKey = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.PARAKEY == "UserCenter_RiaService_ContractSignThree");//合同地址 + var threeUrl = urlKey?.PARAVALUE; + var clientidKey = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.PARAKEY == "Sys_OrderClientIdKey"); + var clientid = clientidKey?.PARAVALUE; + + if (string.IsNullOrWhiteSpace(clientid)) + { + clientid = "UPWEBSITE"; + } + var json = new + { + productName = orderInfo.productname, + period = string.Format("{0}天", orderInfo.day), + price = string.Format("{0}元", 0.ToString("#0.00")), + userId = orderInfo.username, + productLevel = product.productlevel, + productInvestTime = product.productinvesttime, + productInvestType = product.productinvesttype, + issupplement = 1, + orderId = orderInfo.szzyorderid.ToString(), + htid = string.Format("DN{0}", orderInfo.szzyorderid.ToString()) + }; + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var key = systemConfig.GetAccessKey(clientid); + var content = SecurityHelper.EncyptData(json.ToJson(), key); + string sign = SecurityHelper.SignData(content, key); + var threehtUrl = threeUrl + string.Format("?content={0}&sign={1}&clientId={2}&protocolType=", HttpUtility.UrlEncode(content), HttpUtility.UrlEncode(sign), clientid); + + return threehtUrl; + } + + /// + /// 获取订单所需要的合同信息 免费产品需传坐席的名称 + /// + /// + /// + /// + /// + public async Task GetContractOrderInfo(decimal orderid) + { + var result = new ContractOrderInfo(); + var order = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.ORDERID == orderid); + if (order != null) + { + result.productcode = order.PRODUCTCODE; + result.szzyorderid = order.SZZYORDERID.ToString(); + result.productname = order.SUBPRODUCTNAME; + result.day = order.OPENDAYS; + result.username = order.SOFTUSERNAME; + result.ContractCode = order.CONTRACTCODE; + result.ContractStatus = order.contractstatus; + return result; + } + var freeOrder = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.orderid == orderid); + if (freeOrder != null) + { + result.productcode = freeOrder.productcode; + result.szzyorderid = freeOrder.szzyorderid.ToString(); + result.productname = freeOrder.subproductname; + result.day = freeOrder.giftdays; + result.username = freeOrder.softusername; + result.ContractCode = freeOrder.CONTRACTCODE; + result.ContractStatus = freeOrder.contractstatus; + } + else + { + var orderstr = orderid.ToString(); + var l2Order = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.WEBORDERID == orderstr); + if (l2Order != null) + { + result.productcode = l2Order.PRODUCTCODE; + result.szzyorderid = l2Order.WEBORDERID; + result.productname = l2Order.productname; + result.day = l2Order.DAYS; + result.username = l2Order.USERNAME; + result.ContractCode = l2Order.CONTRACTCODE; + result.ContractStatus = l2Order.contractstatus; + } + } + if (result == null || result.szzyorderid == null) + { + throw new Exception("找不到对应的订单"); + } + return result; + } + + public async Task GetProductInfo(string code) + { + var basProduct = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == code); + if (basProduct == null) + { + var productPackage = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == code); + if (productPackage != null) + { + var idArr = new List(productPackage.SubProducts.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries)); + + basProduct = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == idArr[0]); + } + } + if (basProduct == null) + { + throw new Exception("找不到对应的产品"); + } + var module = await _crmRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == basProduct.Moduleid); + return new ProductModuleInfo + { + productinvesttime = module?.InvestTime, + productinvesttype = module?.InvestType, + productlevel = module?.RiskLevel + }; + } + + /// + /// 查看投顾协议 风险协议 风测 等数据 + /// + /// + /// + public async Task GetContractView(ContractQueryDto dto) + { + var orderInfo = await GetContractOrderInfo(dto.orderid); + if (orderInfo == null) + { + throw new Exception("找不到对应的订单"); + } + var res = new ContractResultView() + { + CONTRACTCODE = orderInfo.ContractCode, + CONTRACTSTATUS = orderInfo.ContractStatus + }; + var productInfo = await GetProductInfo(orderInfo.productcode); + if (productInfo == null) + { + throw new Exception("找不到对应的产品"); + } + var threeUrl = await GetBasParameterValue("UserCenter_RiaService_ContractSignThree"); + var clientidKey = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.PARAKEY == "Sys_OrderClientIdKey"); + var clientid = clientidKey?.PARAVALUE; + + if (string.IsNullOrWhiteSpace(clientid)) + { + clientid = "UPWEBSITE"; + } + var json = new + { + productName = orderInfo.productname, + period = string.Format("{0}天", orderInfo.day), + price = string.Format("{0}元", 0.ToString("#0.00")), + userId = orderInfo.username, + productLevel = productInfo.productlevel, + productInvestTime = productInfo.productinvesttime, + productInvestType = productInfo.productinvesttype, + issupplement = 1, + orderId = orderInfo.szzyorderid.ToString(), + htid = string.Format("DN{0}", orderInfo.szzyorderid.ToString()) + }; + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var key = systemConfig.GetAccessKey(clientid); + var content = SecurityHelper.EncyptData(json.ToJson(), key); + string sign = SecurityHelper.SignData(content, key); + var threehtUrl = threeUrl + string.Format("?content={0}&sign={1}&clientId={2}&protocolType=", HttpUtility.UrlEncode(content), HttpUtility.UrlEncode(sign), clientid); + res.htUrl = threehtUrl; + //===================合同Url测试=============== + //合同生成URL测试 + var url = await GetBasParameterValue(Parameter.UserCenter_RiaService_SignPdf.ToString()); + //风险揭示书 + content = SecurityHelper.EncyptData("R_DN" + orderInfo.szzyorderid.ToString(), key); + sign = SecurityHelper.SignData(content, key); + string fxjssUrl = string.Format("{0}/{4}-风险揭示书.pdf?content={1}&sign={2}&clientId={3}&employeeId={5}&employeeName={6}&viewSource={7}&pageSource={8}" + , url, HttpUtility.UrlEncode(content), HttpUtility.UrlEncode(sign), clientid, orderInfo.productname, + dto.Eid, + dto.UserName, + dto.ViewSource, + dto.PageSource); + res.fxjssUrl = fxjssUrl; + + //投顾服务协议 + content = SecurityHelper.EncyptData("A_DN" + orderInfo.szzyorderid.ToString(), key); + sign = SecurityHelper.SignData(content, key); + string tgfwxyUrl = string.Format("{0}/{4}-投顾服务协议.pdf?content={1}&sign={2}&clientId={3}&employeeId={5}&employeeName={6}&viewSource={7}&pageSource={8}", + url, HttpUtility.UrlEncode(content), HttpUtility.UrlEncode(sign), clientid, orderInfo.productname, + dto.Eid, + dto.UserName, + dto.ViewSource, + dto.PageSource); + res.tgfwxyUrl = tgfwxyUrl; + if (!string.IsNullOrEmpty(orderInfo.ContractCode)) + { + var riskinfoUrl = await GetBasParameterValue("riskinfo"); + var htflagUrl = await GetBasParameterValue("htflag"); + if (string.IsNullOrEmpty(riskinfoUrl)) + { + riskinfoUrl = "https://r2.soft.dn8188.com/contract_sign_crm/get_riskinfo"; + } + if (string.IsNullOrEmpty(htflagUrl)) + { + htflagUrl = "https://r2.soft.dn8188.com/contract_sign_crm/get_htflag"; + } + var bf = "{\"uid\": \"" + orderInfo.username + "\",\"htid\":\"DN" + orderInfo.szzyorderid.ToString() + "\"}"; + var hqr = BlowFish.Encode(bf); + var para = new { hqr }; + var ret1 = await _httpClient.PostAsync(riskinfoUrl, para); + //var ret1 = JsonConvert.DeserializeObject(riskData); + //LogHelper.Info(ret1.ToJson()); + if (ret1.ret == 0) + { + //风险评测页面 + var riskcontent = SecurityHelper.EncyptData(ret1.ToJson(), key); + string risksign = SecurityHelper.SignData(riskcontent, key); + var hgUrl = await GetBasParameterValue("HgSoftWebUrl"); + var a = HttpUtility.UrlEncode(riskcontent); + var b = HttpUtility.UrlEncode(risksign); + string fxpcUrl = string.Format("{0}/Compliance/NewRisk?content={1}&sign={2}&clientId={3}&decode=false", + hgUrl, a, b, clientid); + res.fxpcUrl = fxpcUrl; + + res.businesstype = ret1.businesstype; + + if (ret1.businesstype != "smallAmount") + { + var ret = await _httpClient.GetAsync($"{htflagUrl}?htid={orderInfo.ContractCode}"); + var retObj = JsonConvert.DeserializeAnonymousType(ret, new { ret = -1, msg = string.Empty }); + if (retObj.ret != -1) + { + if (retObj.ret == 0) + { + //产品或服务不适当警示确认书 + content = SecurityHelper.EncyptData("I_DN" + orderInfo.szzyorderid.ToString(), key); + sign = SecurityHelper.SignData(content, key); + string cphfwUrl = string.Format("{0}/{4}-产品或服务不适当警示及投资者确认书.pdf ?content={1}&sign={2}&clientId={3}&employeeId={5}&employeeName={6}&viewSource={7}&pageSource={8}", + url, HttpUtility.UrlEncode(content), HttpUtility.UrlEncode(sign), clientid, orderInfo.productname, + dto.Eid, + dto.UserName, + dto.ViewSource, + dto.PageSource); + res.cphfwUrl = cphfwUrl; + } + else if (retObj.ret == 1) + { + //适当性评估结果确认书 + content = SecurityHelper.EncyptData("S_DN" + orderInfo.szzyorderid.ToString(), key); //sHelper.encyptData(clientid, "S_DN" + order.SZZYORDERID.ToString()); + sign = SecurityHelper.SignData(content, key); + string sdxpgUrl = string.Format("{0}/{4}-适当性评估结果确认书.pdf ?content={1}&sign={2}&clientId={3}&employeeId={5}&employeeName={6}&viewSource={7}&pageSource={8}", + url, HttpUtility.UrlEncode(content), HttpUtility.UrlEncode(sign), clientid, orderInfo.productname, + dto.Eid, + dto.UserName, + dto.ViewSource, + dto.PageSource); + res.sdxpgUrl = sdxpgUrl; + } + } + } + } + } + return res; + } + + private async Task GetBasParameterValue(string key) + { + var urlKey = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.PARAKEY == key);//合同地址 + return urlKey?.PARAVALUE; + } + + #endregion 合同相关 + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Response/AddVirtualProductResult.cs b/code/Zxd.Core.Domain/Response/AddVirtualProductResult.cs new file mode 100644 index 0000000..79ddafb --- /dev/null +++ b/code/Zxd.Core.Domain/Response/AddVirtualProductResult.cs @@ -0,0 +1,20 @@ +using System; +namespace Zxd.Core.Domain.Response +{ + public class AddVirtualProductResult + { + public AddVirtualProductResult() + { + } + + public bool Result { get; set; } + + public int Retcode { get; set; } + + public string? Retmsg { get; set; } + + [JsonPropertyName("productcode")] + public string? ProductCode { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/Response/SaleClusResult.cs b/code/Zxd.Core.Domain/Response/SaleClusResult.cs new file mode 100644 index 0000000..d92871f --- /dev/null +++ b/code/Zxd.Core.Domain/Response/SaleClusResult.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Response +{ + public class SaleClusResult + { + [JsonPropertyName("list")] + public List? List { get; set; } + + [JsonPropertyName("ret")] + public int Ret { get; set; } + + [JsonPropertyName("msg")] + public string? Msg { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Response/SaleRelation.cs b/code/Zxd.Core.Domain/Response/SaleRelation.cs new file mode 100644 index 0000000..4e2be52 --- /dev/null +++ b/code/Zxd.Core.Domain/Response/SaleRelation.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Response +{ + public class SaleRelation + { + [JsonPropertyName("appid")] + public string? Appid { get; set; } + + [JsonPropertyName("appuserid")] + public string? Appuserid { get; set; } + + [JsonPropertyName("uid")] + public int? Uid { get; set; } + + [JsonPropertyName("mobile")] + public string? Mobile { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Response/UsercenterResponse.cs b/code/Zxd.Core.Domain/Response/UsercenterResponse.cs new file mode 100644 index 0000000..82ff38e --- /dev/null +++ b/code/Zxd.Core.Domain/Response/UsercenterResponse.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Domain.Response +{ + public class UsercenterResponse + { + public int Ret { get; set; } + + public string RetMsg { get; set; } + + public List List { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Sso/SsoDepartment.cs b/code/Zxd.Core.Domain/Sso/SsoDepartment.cs new file mode 100644 index 0000000..64f3ff6 --- /dev/null +++ b/code/Zxd.Core.Domain/Sso/SsoDepartment.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoDepartment + { + public int id { get; set; } + public string remark { get; set; } + public int status { get; set; } + public int? parent_id { get; set; } + public string department_name { get; set; } + public int department_sort { get; set; } + public int department_type { get; set; } + public string department_code { get; set; } + public int is_deleted { get; set; } + public string create_time { get; set; } + public string update_time { get; set; } + public bool is_checked { get; set; } + } + + public class SsoDepartmentExtend : SsoDepartment + { + public decimal? IS_PROFESSION { get; set; } = 0; + } +} diff --git a/code/Zxd.Core.Domain/Sso/SsoEmployee.cs b/code/Zxd.Core.Domain/Sso/SsoEmployee.cs new file mode 100644 index 0000000..a87c55e --- /dev/null +++ b/code/Zxd.Core.Domain/Sso/SsoEmployee.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoEmployee + { + public int id { get; set; } + public int status { get; set; } + public int? sex { get; set; } + public string phone { get; set; } + public int employee_id { get; set; } + public string employee_name { get; set; } + public string employee_position { get; set; } + public DateTime? entry_date { get; set; } + public DateTime? leave_date { get; set; } + public int is_change_password { get; set; } + public int is_deleted { get; set; } + public DateTime? create_time { get; set; } + public DateTime? update_time { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Sso/SsoEmployeeDepartment.cs b/code/Zxd.Core.Domain/Sso/SsoEmployeeDepartment.cs new file mode 100644 index 0000000..c7bf95e --- /dev/null +++ b/code/Zxd.Core.Domain/Sso/SsoEmployeeDepartment.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoEmployeeDepartment + { + public int id { get; set; } + public int employee_id { get; set; } + public int department_id { get; set; } + public int is_deleted { get; set; } + public DateTime? create_time { get; set; } + public DateTime? update_time { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Sso/SsoOrganization.cs b/code/Zxd.Core.Domain/Sso/SsoOrganization.cs new file mode 100644 index 0000000..4c44c27 --- /dev/null +++ b/code/Zxd.Core.Domain/Sso/SsoOrganization.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoOrganization + { + public SsoOrganization(List profession_departments, List other_departments, List employees, List employee_departments) + { + this.profession_departments = profession_departments; + this.other_departments = other_departments; + this.employees = employees; + this.employee_departments = employee_departments; + } + + /// + /// 业务部门 + /// + public List profession_departments { get; set; } + /// + /// 其他部门 + /// + public List other_departments { get; set; } + /// + /// 员工信息 + /// + public List employees { get; set; } + /// + /// 员工部门关系 + /// + public List employee_departments { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Sso/SsoResult.cs b/code/Zxd.Core.Domain/Sso/SsoResult.cs new file mode 100644 index 0000000..371921f --- /dev/null +++ b/code/Zxd.Core.Domain/Sso/SsoResult.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + internal class SsoResult + { + /// + /// -1 未知异常 + /// -1001 签名不合法 + /// -1002 签名验证失败 + /// -1003 请求内容不合法 + /// -1004 AppID不合法 + // -1005 签名已过期 + /// + [JsonPropertyName("ret")] + public int Ret { get; set; } + + [JsonPropertyName("data")] + public T Data { get; set; } + + [JsonPropertyName("msg")] + public string? Msg { get; set; } + } +} diff --git a/code/Zxd.Core.Domain/Sso/SsoUserTokenInfo.cs b/code/Zxd.Core.Domain/Sso/SsoUserTokenInfo.cs new file mode 100644 index 0000000..ca46b0e --- /dev/null +++ b/code/Zxd.Core.Domain/Sso/SsoUserTokenInfo.cs @@ -0,0 +1,18 @@ +using System; +namespace Zxd.Domain.Sso +{ + public class SsoUserTokenInfo + { + public SsoUserTokenInfo() + { + + } + + public decimal Eid { get; set; } + + public DateTime ExpirationTime { get; set; } + + public string? Token { get; set; } + } +} + diff --git a/code/Zxd.Core.Domain/StandardProductDomain.cs b/code/Zxd.Core.Domain/StandardProductDomain.cs new file mode 100644 index 0000000..abaac2c --- /dev/null +++ b/code/Zxd.Core.Domain/StandardProductDomain.cs @@ -0,0 +1,265 @@ +using System; +using Zxd.Core.Domain.Impl; + +namespace Zxd.Core.Domain +{ + public class StandardProductDomain : IStandardProductDomain + { + private readonly IBaseRepository _crmRepository; + private readonly IBaseRepository _zxdRepository; + private readonly IRedisManager _redisManager; + private readonly IDeptmentDomain _deptmentDomain; + private readonly IMapper _mapper; + + public StandardProductDomain(IBaseRepository crmRepository, + IBaseRepository zxdRepository, + IRedisManager redisManager, + IDeptmentDomain deptmentDomain, + IMapper mapper) + { + _crmRepository = crmRepository; + _zxdRepository = zxdRepository; + _redisManager = redisManager; + _deptmentDomain = deptmentDomain; + _mapper = mapper; + } + + public async Task> GetProductSelect() + { + var key = CacheKeys.ProductList; + var data = new List(); + if (!await _redisManager.ExistsAsync(key)) + { + var list = await _crmRepository.GetRepository().QueryListAsync(); + foreach (var item in list) + { + data.Add(new SelectItem(item.Id ?? "", $"{item.Name}/{item.Moduleid}/{item.Day}/{item.Price}")); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromHours(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + } + + return data; + } + + public async Task> GetStandardWaySelect() + { + var key = CacheKeys.StandardWay; + var data = new List(); + if (!await _redisManager.ExistsAsync(key)) + { + foreach (StandardWay item in Enum.GetValues(typeof(StandardWay))) + { + data.Add(new SelectItem(item, item.GetDescription())); + } + await _redisManager.SetAsync(key, data, TimeSpan.FromDays(1)); + } + else + { + data = await _redisManager.GetListAsync(key); + } + + return data; + } + + public async Task GetBaseProduct(string code) + { + if (string.IsNullOrEmpty(code)) + { + throw new ApiException("产品编码不能为空!"); + } + + var product = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .Include(x => x.Module) + .FirstOrDefaultAsync(x => x.Id == code); + var productPackage = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .FirstOrDefaultAsync(x => x.Id == code); + if (product == null && productPackage == null) + { + throw new ApiException("产品不存在或已删除!"); + } + + if (product != null) + { + return new BaseProductInfoDto + { + Code = product.Id, + Day = product.Day ?? 0, + Price = (decimal)product.Price, + ProductName = product.Name ?? "", + ProductProperty = "基础产品", + ProductType = product.ProductGroup?.Name ?? "", + Status = product.Active == 1 ? "已上线" : "未上线", + ProductModules = new List() { product.Moduleid ?? "" } + }; + } + + if (productPackage != null) + { + var productCodes = string.IsNullOrEmpty(productPackage.SubProducts) ? new List() + : productPackage.SubProducts.Split('|').ToList(); + var data = new BaseProductInfoDto + { + Code = productPackage.Id, + Price = (decimal)productPackage.Price, + ProductName = productPackage.Name ?? "", + ProductProperty = "组合产品", + ProductType = productPackage.ProductGroup?.Name ?? "", + Status = productPackage.Active == 1 ? "已上线" : "未上线" + }; + if (productCodes.Any()) + { + var productList = await _crmRepository.GetRepository().Query() + .Where(x => productCodes.Contains(x.Id)) + .ToListAsync(); + data.Day = productList.Sum(x => x.Day ?? 0); + data.ProductModules = productList.Select(x => x.Moduleid ?? "").ToList(); + } + return data; + } + + return new BaseProductInfoDto(); + } + + public async Task CreateStandardProduct(CreateStandardProductDto dto) + { + if (string.IsNullOrEmpty(dto.ProductCode)) + { + throw new ApiException("产品编码不能为空!"); + } + var code = dto.ProductCode; + var product = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .Include(x => x.Module) + .FirstOrDefaultAsync(x => x.Id == code); + var productPackage = await _crmRepository.GetRepository().Query() + .Include(x => x.ProductGroup) + .FirstOrDefaultAsync(x => x.Id == code); + if (product == null && productPackage == null) + { + throw new ApiException("产品不存在或已删除!"); + } + var standardProduct = new StandardProduct + { + ProductCode = product != null ? dto.ProductCode : null, + ProductPackageCode = productPackage != null ? dto.ProductCode : null, + StandardType = (StandardType)dto.StandardType, + Way = dto.StandardWay, + CreateTime = DateTime.Now + }; + + if (product != null) + { + // todo 调用优品接口 + } + else + { + // todo 调用优品接口 + } + + await _zxdRepository.GetRepository().InsertAsync(standardProduct); + } + + public async Task> StandardProductPage(SearchStandardProductDto dto) + { + var productCodes = new List(); + var productPackageCodes = new List(); + if (!string.IsNullOrEmpty(dto.ProductName)) + { + productCodes = await _crmRepository.GetRepository().Query() + .Where(x => x.Name.Contains(dto.ProductName)) + .Select(x => x.Id) + .ToListAsync(); + + productPackageCodes = await _crmRepository.GetRepository().Query() + .Where(x => x.Name.Contains(dto.ProductName)) + .Select(x => x.Id) + .ToListAsync(); + } + var query = _zxdRepository.GetRepository().Query() + .If(dto.Id != null, x => x.Where(x => x.Id == dto.Id)) + .If(dto.StandardType != null, x => x.Where(x => x.StandardType == (StandardType)dto.StandardType)) + .If(productCodes.Any(), x => x.Where(x => productCodes.Contains(x.ProductCode))) + .If(productPackageCodes.Any(), x => x.Where(x => productPackageCodes.Contains(x.ProductPackageCode))) + .Include(x => x.FinishedProducts); + + var total = await query.CountAsync(); + var data = await query + .Select(x => new StandardProductDto + { + Id = x.Id, + CreateTime = x.CreateTime, + StandardProductType = ((StandardType)x.StandardType).GetDescription(), + ProductCode = string.IsNullOrEmpty(x.ProductCode) ? x.ProductPackageCode : x.ProductCode, + ProductProperty = string.IsNullOrEmpty(x.ProductCode) ? "组合产品" : "基础产品", + FinishedProductCount = x.FinishedProducts == null ? 0 : x.FinishedProducts.Count + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + + var productList = new List(); + var productPackageList = new List(); + var productPackageProductList = new List(); + if (data.Any()) + { + productList = await _crmRepository.GetRepository().Query() + .Where(x => data.Select(y => y.ProductCode).Contains(x.Id)) + .Include(x => x.Module) + .Include(x => x.ProductGroup) + .ToListAsync(); + productPackageList = await _crmRepository.GetRepository().Query() + .Where(x => data.Select(y => y.ProductCode).Contains(x.Id)) + .Include(x => x.ProductGroup) + .ToListAsync(); + if (productPackageList.Any()) + { + var productPackageProductCodes = new List(); + productPackageList.ForEach(x => + { + if (x.SubProductCodes != null && x.SubProductCodes.Any()) + { + productPackageCodes.AddRange(x.SubProductCodes); + } + }); + productPackageProductList = await _crmRepository.GetRepository().Query() + .Where(x => productPackageProductCodes.Contains(x.Id)) + .Include(x => x.Module) + .Include(x => x.ProductGroup) + .ToListAsync(); + } + } + data.ForEach(x => + { + var product = productList.FirstOrDefault(y => y.Id == x.ProductCode); + var productPackage = productPackageList.FirstOrDefault(y => y.Id == x.ProductCode); + if (product != null) + { + x.Day = product.Day.ToString(); + x.Price = $"{product.Price:0:00}元"; + x.StandardProductName = product.Name; + x.Status = product.Active == 1 ? "已上线" : "未上线"; + x.StandardProductModule = new List { $"{product.Module.Name}【{product.Moduleid}】【{product.Day}】" }; + } + if (productPackage != null) + { + var productPackageProducts = productPackageProductList + .Where(y => productPackage.SubProductCodes.Contains(y.Id)).ToList(); + x.Day = string.Join("/", productPackageProducts.Select(x => x.Day).ToList()); + x.Price = $"{productPackage.Price:0:00}元"; + x.StandardProductName = productPackage.Name; + x.Status = productPackage.Active == 1 ? "已上线" : "未上线"; + x.StandardProductModule = productPackageProducts.Select(y => $"{y.Module.Name}【{y.Moduleid}】【{y.Day}】").ToList(); + } + }); + + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + } +} + diff --git a/code/Zxd.Core.Domain/StatisticsDomain.cs b/code/Zxd.Core.Domain/StatisticsDomain.cs new file mode 100644 index 0000000..10c429c --- /dev/null +++ b/code/Zxd.Core.Domain/StatisticsDomain.cs @@ -0,0 +1,103 @@ +using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.Dncmsbase; +using Zxd.Domain.Config; + +namespace Zxd.Core.Domain +{ + internal class StatisticsDomain : IStatisticsDomain + { + private readonly IConfiguration _configuration; + private readonly ICacheDomain _cacheDomain; + private readonly IBaseRepository _dncmsbaseRepository; + private readonly IBaseRepository _zxdRepository; + private readonly IServiceProvider _serviceProvider; + + public StatisticsDomain(IConfiguration configuration, + ICacheDomain cacheDomain, + IBaseRepository dncmsbaseRepository, + IBaseRepository zxdRepository, + IServiceProvider serviceProvider) + { + _configuration = configuration; + _cacheDomain = cacheDomain; + _dncmsbaseRepository = dncmsbaseRepository; + _zxdRepository = zxdRepository; + _serviceProvider = serviceProvider; + } + + public async Task GetMonthAttentionData(string year, string month) + { + var date = $"{year}-{month}"; + var result = new MonthAttentionDto + { + Date = date, + }; + var starDate = DateTime.Parse(date).ToString("yyyy-MM-dd"); + var endDate = DateTime.Parse(date).AddMonths(1).ToString("yyyy-MM-dd"); + var param = new MySqlParameter[] { + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=starDate,ParameterName="starDate"}, + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=endDate,ParameterName="endDate"} + }; + using (var scope = _serviceProvider.CreateAsyncScope()) + { + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var deptSql = @"SELECT dt.title, t2.毛量 as only, t3.去重总数 as total, t1.去重新增量 as increment FROM + (SELECT ta.deptid, ta.total as 去重新增量 FROM + (SELECT a.deptid, + COUNT(DISTINCT a.unionid) AS total + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 + AND a.repeattype <= 150 + GROUP BY a.deptid) AS ta) t1 LEFT JOIN + (SELECT ta.deptid, ta.total as 毛量 FROM + (SELECT a.deptid, + COUNT(*) AS total + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 + GROUP BY a.deptid) AS ta) t2 ON t1.deptid = t2.deptid LEFT JOIN + (SELECT ta.deptid, ta.total as 去重总数 FROM + (SELECT a.deptid, + COUNT(DISTINCT a.unionid) AS total + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 + GROUP BY a.deptid) AS ta) t3 ON t1.deptid = t3.deptid + LEFT JOIN dncmsbase.deptment dt + on t1.deptid = dt.id + ORDER BY + dt.title;"; + + result.DeptData = await dncmsbaseRepository.ExecuteSqlToListAsync(deptSql, param); + } + using (var scope = _serviceProvider.CreateAsyncScope()) + { + var dncmsbaseRepository = scope.ServiceProvider.GetRequiredService>(); + var conterSql = @" + SELECT '懂牛软件业务中心' as title, COUNT(*) AS total, + COUNT(DISTINCT a.unionid) AS increment + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 AND a.repeattype<=100 + AND deptid in (16,29,23,2,5,41) + union + SELECT '六合智投业务中心' as title, COUNT(*) AS total, + COUNT(DISTINCT a.unionid) AS increment + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 AND a.repeattype<=100 + AND deptid in (27,33,32,40,43) + union + SELECT '东方股票业务中心' as title, COUNT(*) AS total, + COUNT(DISTINCT a.unionid) AS increment + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 AND a.repeattype<=100 + AND deptid in (38,37,19,15,8) + union + SELECT '好股来投教中心' as title, COUNT(*) AS total, + COUNT(DISTINCT a.unionid) AS increment + FROM dncms.weworkexternalusersubscribe AS a WHERE a.regdate >= @starDate AND a.regdate < @endDate AND a.add_way<>202 AND a.repeattype<=100 + AND deptid in (35,36,30,31);"; + + result.ConterData = await dncmsbaseRepository.ExecuteSqlToListAsync(conterSql, param); + } + return result; + } + } +} diff --git a/code/Zxd.Core.Domain/TodoItemDomain.cs b/code/Zxd.Core.Domain/TodoItemDomain.cs new file mode 100644 index 0000000..29ddc28 --- /dev/null +++ b/code/Zxd.Core.Domain/TodoItemDomain.cs @@ -0,0 +1,439 @@ +using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; +using Newtonsoft.Json; +using System.Reflection; +using Zxd.Core.Domain.Dto.TodoItem; +using Zxd.Entity.Action; + +namespace Zxd.Core.Domain +{ + public class TodoItemDomain : ITodoItemDomain + { + private readonly IServiceProvider _serviceProvider; + + private readonly IBaseRepository _hgActionRepository; + + private readonly IBaseRepository _zxdRepository; + + private readonly IConfiguration _configuration; + + private readonly IDeptmentDomain _deptDomain; + + private readonly IBaseRepository _dncmsBaseRepository; + + private readonly SystemConfig _systemConfig; + + private readonly IEarlyWarningDomain _earlyWarningDomain; + + private readonly ICacheDomain _cacheDomain; + + public TodoItemDomain( + IServiceProvider serviceProvider, + IBaseRepository hgActionRepository, + IBaseRepository zxdRepository, + IConfiguration configuration, + IDeptmentDomain deptDomain, + IEarlyWarningDomain earlyWarningDomain, + IBaseRepository dncmsBaseRepository, + ICacheDomain cacheDomain) + { + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _serviceProvider = serviceProvider; + _hgActionRepository = hgActionRepository; + _zxdRepository = zxdRepository; + _configuration = configuration; + _deptDomain = deptDomain; + _earlyWarningDomain = earlyWarningDomain; + _dncmsBaseRepository = dncmsBaseRepository; + _cacheDomain = cacheDomain; + } + + public async Task> GetListNewAsync(GetListRequest request) + { + var depts = await _deptDomain.GetDeptments(); + var tableFilter = ""; + var filter = new List(); + var ps = new List(); + + var setting = await _cacheDomain.GetValueParameter("ToDoItemSetting"); + var sets = new List(); + if (!string.IsNullOrWhiteSpace(setting)) + { + sets = JsonHelper.FromJson(setting).setting; + } + + if (!string.IsNullOrEmpty(request.lineid)) + { + var lineids = GetIds(request.lineid); + if (lineids.Count > 0) + { + filter.Add($"t1.deptid in ({string.Join(",", lineids)})"); + } + } + + if (request.eid.HasValue) + { + filter.Add($"t1.eid = @eid"); + ps.Add(new MySqlParameter("eid", request.eid)); + } + else + { + if (request.deptid.HasValue) + { + tableFilter = $"{Environment.NewLine}JOIN employee_department_detail t3 on t3.eid = t1.eid"; + filter.Add($"t3.department_id = @deptid"); + filter.Add($"t3.is_deleted = 0"); + ps.Add(new MySqlParameter("deptid", request.deptid)); + } + } + + if (!string.IsNullOrEmpty(request.resid)) + { + filter.Add($"(t1.resid = @resid or t1.umid = @resid)"); + ps.Add(new MySqlParameter("resid", request.resid)); + } + + if (request.customerid.HasValue) + { + filter.Add($"t1.customerid = @customerid"); + ps.Add(new MySqlParameter("customerid", request.customerid)); + } + + if (!string.IsNullOrEmpty(request.cname)) + { + filter.Add($"t1.Nickname like @cname"); + ps.Add(new MySqlParameter("cname", $"%{request.cname}%")); + } + + if (!string.IsNullOrEmpty(request.eventtypename)) + { + var eventids = GetIds(request.eventtypename); + if (eventids.Count > 0) + { + filter.Add($"t1.neweventid in ({string.Join(",", eventids)})"); + } + } + else + { + if (!string.IsNullOrEmpty(request.eventid)) + { + var eventids = GetIds(request.eventid); + if (eventids.Count > 0) + { + filter.Add($"t1.neweventid in ({string.Join(",", eventids)})"); + } + } + } + + if (!string.IsNullOrEmpty(request.eventmemo)) + { + filter.Add($"t1.Content like @eventmemo"); + ps.Add(new MySqlParameter("eventmemo", $"%{request.eventmemo}%")); + } + + if (request.noticetimeBegin.HasValue) + { + var dt = request.noticetimeBegin.GetValueOrDefault().Date; + filter.Add($"t1.act_date >= @noticetimeBegin"); + ps.Add(new MySqlParameter("noticetimeBegin", dt)); + } + + if (request.noticetimeEnd.HasValue) + { + var dt = request.noticetimeEnd.GetValueOrDefault().Date.AddDays(1); + filter.Add($"t1.act_date < @noticetimeEnd"); + ps.Add(new MySqlParameter("noticetimeEnd", dt)); + } + + if (request.isread.HasValue) + { + filter.Add($"t1.isread = {request.isread}"); + } + + if (request.readtimeBegin.HasValue) + { + var dt = request.readtimeBegin.GetValueOrDefault().Date; + filter.Add($"t1.readtime >= @readtimeBegin"); + ps.Add(new MySqlParameter("readtimeBegin", dt)); + } + + if (request.readtimeEnd.HasValue) + { + var dt = request.readtimeEnd.GetValueOrDefault().Date.AddDays(1); + filter.Add($"t1.readtime < @readtimeEnd"); + ps.Add(new MySqlParameter("readtimeEnd", dt)); + } + + var where = ""; + if (filter.Count > 0) + { + where = $"{Environment.NewLine}where {string.Join(" and ", filter)}"; + } + + var tables = $@" + ac_employee_todoitem t1{tableFilter}"; + + var fields = $@" + t1.id, + t1.deptid, + t1.eid, + t1.ename, + t1.resid, + t1.umid, + t1.customerid, + t1.Nickname cname, + t1.eventid, + t1.neweventid, + t1.neweventname eventname, + t1.Content eventmemo, + t1.ctime noticetime, + t1.eventtypename, + t1.isread, + t1.readtime, + t1.appid, + t1.appuserid, + t1.sceneid"; + var skip = (request.PageIndex - 1) * request.PageSize; + var take = request.PageSize; + using (var scope = _serviceProvider.CreateAsyncScope()) + { + var repository = scope.ServiceProvider.GetRequiredService>(); + var sql = $"select count(1) from {tables}{where}"; + var total = await repository.ExecuteSqlToCountLongAsync(sql, ps.ToArray()); + sql = $"select {fields} from {tables}{where} order by t1.id desc limit {skip},{take}"; + if (!string.IsNullOrEmpty(request.eventmemo))// 如果包含了模糊查找,那么就需要进行子查询,会快一点 + { + sql = $"select {fields} from ac_employee_todoitem t1 where t1.id in( select t1.id from {tables}{where} ) order by t1.id desc limit {skip},{take}"; + } + var items = await repository.ExecuteSqlToListAsync(sql, ps.ToArray()); + foreach (var item in items) + { + //这里要关联Id而不是DepartmentId + var dept = depts.Where(w => w.Id == item.deptid).FirstOrDefault(); + if (dept != null) + { + item.deptname = dept.Title; + } + + var set = sets.FirstOrDefault(x => x.neweventid == item.neweventid); + if (set != null && !string.IsNullOrWhiteSpace(set.linkUrl)) + { + item.linkurl = GetContent(item, set.linkUrl); + } + } + return new PageResult(request.PageIndex, request.PageSize, Convert.ToInt32(total), items); + } + } + + private string GetContent(TodoItemDto item, string linkUrl) + { + var content = linkUrl; + Type type = typeof(TodoItemDto); + PropertyInfo[] propertyInfo = type.GetProperties(); + foreach (var property in propertyInfo) + { + var value = property.GetValue(item); + var setValue = value == null ? "" : value.ToString(); + var name = "{" + property.Name + "}"; + if (name == "{act_date}" && content.Contains(name)) + { + content = content.Replace(name, Convert.ToDateTime(setValue).ToString("yyyy-MM-dd")); + continue; + } + if (content.Contains(name)) + { + content = content.Replace(name, setValue); + } + } + content = content.Replace("----", "-").Replace("---", "-").Replace("--", "-").Trim('-'); + return content; + } + + private List GetIds(string input) + { + var ids = new List(); + var parts = input.Split(','); + var t = typeof(T); + if (t == typeof(int)) + { + foreach (var part in parts) + { + if (!int.TryParse(part, out int temp)) + { + throw new Exception("无效的输入"); + } + + ids.Add((T)(object)temp); + } + } + else + { + throw new Exception("无效的类型T"); + } + + return ids; + } + + public async Task> GetEventTypeSelectAsync(GetEventTypeSelectRequest request) + { + var items = new List(); + var setting = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "ToDoItemSetting"); + if (setting != null && !string.IsNullOrWhiteSpace(setting.PARAVALUE)) + { + var config = JsonConvert.DeserializeObject(setting.PARAVALUE); + if (config != null && config.setting != null && config.setting.Count > 0) + { + if (!string.IsNullOrEmpty(request.eventid)) + { + var ids = GetIds(request.eventid); + items.AddRange(config.setting.Where(w => ids.Contains(w.neweventid.GetValueOrDefault())).Select(o => new SelectItem(o.memo, o.neweventid))); + } + else + { + var groups = config.setting.GroupBy(g => new { g.remark, g.Sort }); + groups = groups.OrderBy(n => n.Key.Sort); + foreach (var group in groups) + { + items.Add(new SelectItem(group.Key.remark, string.Join(",", group.Select(o => o.neweventid.GetValueOrDefault())))); + } + } + } + } + return items; + } + + /// + /// 修改已读 + /// + /// + /// + public async Task EditReadAsync(EditReadRequest request) + { + var model = await _hgActionRepository.GetRepository().FirstOrDefaultAsync(f => f.id == request.Id); + if (model != null && model.isread != 1 && model.readtime.HasValue == false) + { + model.isread = 1; + model.readtime = DateTime.Now; + await _hgActionRepository.GetRepository().UpdateAsync(model); + } + return "修改成功"; + } + + /// + /// 重要线索消息通知 + /// + /// + public async Task NoticeAsync() + { + try + { + var now = DateTime.Now; + if (now.DayOfWeek == DayOfWeek.Saturday || now.DayOfWeek == DayOfWeek.Sunday) + return; + + //获取参数配置中的消息可通知时间段 + var todoItemNotice = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "ToDoItemNotice"); + if (todoItemNotice != null && !string.IsNullOrWhiteSpace(todoItemNotice.PARAVALUE)) + { + var noticeDto = JsonConvert.DeserializeObject(todoItemNotice.PARAVALUE); + + if (!noticeDto.IsNotice) + return; + + DateTime.TryParse($"{now.Date.ToString("yyyy-MM-dd")} {noticeDto.StartTime}", out DateTime startTime); + DateTime.TryParse($"{now.Date.ToString("yyyy-MM-dd")} {noticeDto.EndTime}", out DateTime endTime); + + if (now >= startTime && now <= endTime) + { + //获取重要线索 + var todoItems = await _hgActionRepository.GetRepository().Query() + .Where(x => x.ctime >= now.Date && x.isread == 0) + .GroupBy(x => new { x.eid, x.deptid }) + .Select(x => new + { + Eid = x.Key.eid, + DeptId = x.Key.deptid, + Items = x.Select(y => y.eventtypename), + Count = x.Count() + }) + .ToListAsync(); + + //企微应用的ID + var weworkAgents = await _dncmsBaseRepository.GetRepository().Query().Where(x => x.name == "客服达量通知").ToListAsync(); + //获取员工的信息 + var weworks = await _dncmsBaseRepository.GetRepository().Query().ToListAsync(); + foreach (var todoItem in todoItems) + { + var weworkUsers = weworks.Where(x => x.eid == todoItem.Eid && x.deptid == todoItem.DeptId); + if (!weworkUsers.Any()) + continue; + + //重要线索列表页路径 + var app = _systemConfig.Apps.Where(x => x.Deptids.Contains(weworkUsers.FirstOrDefault().deptid.Value)).FirstOrDefault(); + var toDoItemListUrl = $"{app?.CrmUrl}Csvr/ToDoItem/ImportantNew?urlTitle=我的重要线索客户"; + + var message = $"有{todoItem.Count}条重要线索未读 {now},【点击更多】"; + + var items = todoItem.Items.GroupBy(x => x).Select(x => new { Name = x.Key, Count = x.Count() }); + foreach (var item in items) + { + message += $"\n{item.Name}:{item.Count}条"; + } + + foreach (var weworkUser in weworkUsers) + { + var weworkAgent = weworkAgents.FirstOrDefault(x => x.appid == weworkUser.appid); + if (weworkAgent == null) + continue; + + await _earlyWarningDomain.WeworkSend(weworkUser.userid, weworkUser.appid, weworkAgent.agentid.ToString(), message); + //await _earlyWarningDomain.WeworkSend("chenshidong", "ww89347c2378b6e050", "1000028", message); + } + } + } + } + } + catch (Exception ex) + { + Log.Error($"重要线索消息通知报错", ex); + } + } + } + + public class ToDoItemSetting + { + public int delaytime { get; set; } + + public List setting { get; set; } + } + + public class ToDoItemSettingItem + { + public int? eventid { get; set; } + + public string remark { get; set; } + + public string memo { get; set; } + + public string template { get; set; } + + public bool? allNotice { get; set; } + + public bool? firstCtime { get; set; } + + public bool? is_wework { get; set; } + + public bool? is_mobile { get; set; } + + public bool? is_belong { get; set; } + + public List scenetype { get; set; } + + public List sceneid { get; set; } + + public List deptids { get; set; } + public int? neweventid { get; set; } + public int? Sort { get; set; } + public string? linkUrl { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/UserInfoDomain.cs b/code/Zxd.Core.Domain/UserInfoDomain.cs new file mode 100644 index 0000000..1b14f8e --- /dev/null +++ b/code/Zxd.Core.Domain/UserInfoDomain.cs @@ -0,0 +1,240 @@ +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto; +using Zxd.Core.Domain.Dto.Dncmsbase; +using Zxd.Domain.Config; + +namespace Zxd.Core.Domain +{ + internal class UserInfoDomain : IUserInfoDomain + { + private readonly IServiceProvider _serviceProvider; + private readonly IRedisManager _redisManager; + private readonly IBaseRepository _cmsBaseRepository; + + public UserInfoDomain( + IRedisManager redisManager, + IServiceProvider serviceProvider, + IBaseRepository cmsBaseRepository) + { + _redisManager = redisManager; + _serviceProvider = serviceProvider; + _cmsBaseRepository = cmsBaseRepository; + } + + /// + /// 根据条件获取用户信息 + /// + /// + /// + /// + /// + /// + /// + public async Task> GetUserInfos(int? cid, string? appid, string? appuserid, string? resid, string? unionid) + { + var userInfos = new List(); + var paramList = new Dictionary(); + if (cid != null && cid > 0) + { + paramList.Add("customerid", cid); + userInfos = await GetUserInfoByCid(cid); + userInfos ??= await GetUserInfoBySqlCondition(paramList); + } + else if (!string.IsNullOrEmpty(appid) && !string.IsNullOrEmpty(appuserid)) + { + // 从缓存中获取用户信息 + var uid = await _redisManager.ExistsAsync($"{appid}_1_{appuserid}", "UserCenter") ? await _redisManager.GetAsync($"{appid}_1_{appuserid}", "UserCenter") : 0; + + //Log.Information($"在缓存key:【{appid}_1_{appuserid}】中获取 uid:{uid}"); + if (uid == 0) + { + uid = await _redisManager.ExistsAsync($"{appid}_{appuserid}", "UserCenter") ? await _redisManager.GetAsync($"{appid}_{appuserid}", "UserCenter") : 0; + //Log.Information($"在缓存key:【{appid}_{appuserid}】中获取 uid:{uid}"); + } + if (uid > 0 && await _redisManager.ExistsAsync($"user_{uid}", "UserCenter")) + { + Log.Information($"useruid:user_{uid}"); + var userInfoDto = await _redisManager.GetHashAsync($"user_{uid}", "UserCenter"); + cid = !string.IsNullOrEmpty(userInfoDto.Customerid) ? int.Parse(userInfoDto.Customerid) : 0; + Log.Information($"cid:{userInfoDto.ToJson()} {cid}"); + } + if (cid != null && cid > 0) + { + paramList.Add("customerid", cid); + userInfos = await GetUserInfoByCid(cid); + userInfos ??= await GetUserInfoBySqlCondition(paramList); + } + if (userInfos == null || !userInfos.Any()) + { + paramList = new Dictionary + { + { "appid", appid }, + { "appuserid", appuserid } + }; + userInfos = await GetUserInfoBySqlCondition(paramList); + if (userInfos.Any()) + { + cid = !string.IsNullOrEmpty(userInfos.First().Customerid) ? int.Parse(userInfos.First().Customerid) : 0; + userInfos = await GetUserInfoByCid(cid); + paramList = new Dictionary + { + { "customerid", cid } + }; + userInfos ??= await GetUserInfoBySqlCondition(paramList); + } + } + } + else if (!string.IsNullOrEmpty(resid)) + { + // 从缓存中获取用户信息 + cid = await _redisManager.ExistsAsync(resid, "UserCenter") ? await _redisManager.GetAsync(resid, "UserCenter") : 0; + if (cid != null && cid > 0) + { + paramList.Add("Resid", resid); + userInfos = await GetUserInfoByCid(cid); + userInfos ??= await GetUserInfoBySqlCondition(paramList); + if (userInfos.Any()) + { + cid = !string.IsNullOrEmpty(userInfos.First().Customerid) ? int.Parse(userInfos.First().Customerid) : 0; + userInfos = await GetUserInfoByCid(cid); + paramList = new Dictionary + { + { "customerid", cid } + }; + userInfos ??= await GetUserInfoBySqlCondition(paramList); + } + } + } + else if (!string.IsNullOrEmpty(unionid)) + { + paramList.Add("Unionid", unionid); + // 如果缓存中没有用户信息,则从数据库中获取 + userInfos ??= await GetUserInfoBySqlCondition(paramList); + if (userInfos.Any()) + { + cid = !string.IsNullOrEmpty(userInfos.First().Customerid) ? int.Parse(userInfos.First().Customerid) : 0; + userInfos = await GetUserInfoByCid(cid); + paramList = new Dictionary + { + { "customerid", cid } + }; + userInfos ??= await GetUserInfoBySqlCondition(paramList); + } + } + return userInfos; + } + + /// + /// 根据客户id获取客户信息 + /// + /// + /// + private async Task?> GetUserInfoByCid(int? cid) + { + var userInfos = new List(); + var userInfo = await _redisManager.GetHashAsync($"user_{cid}", "UserCenter"); + if (userInfo != null) + { + var result = await _redisManager.GetDatabase("UserCenter").SetMembersAsync($"cid_{cid}"); + + #region 反序列化处理 + + foreach (var item in result) + { + if (!item.HasValue) continue; + try + { + var data = JsonSerializer.Deserialize(item, new JsonSerializerOptions + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + if (data == null) continue; + var uid = data.Uid; + userInfo = await _redisManager.GetHashAsync($"user_{uid}", "UserCenter"); + userInfos.Add(userInfo); + continue; + } + catch (Exception e) + { + Log.Error($"反序列化失败:{e.Message}"); + } + try + { + var data = JsonSerializer.Deserialize(item, new JsonSerializerOptions + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); + if (data == null) continue; + var uid = data.Uid; + userInfo = await _redisManager.GetHashAsync($"user_{uid}", "UserCenter"); + userInfos.Add(userInfo); + } + catch (Exception e) + { + Log.Error($"反序列化失败:{e.Message}"); + } + } + + #endregion 反序列化处理 + + Log.Information($"cid_cache:{userInfos.ToJson()} "); + return userInfos; + } + return null; + } + + /// + /// 根据sql和条件获取客户信息 + /// + /// + /// + private async Task> GetUserInfoBySqlCondition(Dictionary paramList) + { + Log.Information($"lookdb:{paramList.ToJson()}"); + var sql = @"SELECT Uid, Appid, Appuserid, Customerid, Resid, Unionid FROM UserInfo WHERE 1=1"; + if (!paramList.Any()) return new List(); + using (var scope = _serviceProvider.CreateAsyncScope()) + { + var userCenterRepository = scope.ServiceProvider.GetRequiredService>(); + + var paramter = new List() { }; + var values = new List(); + foreach (var param in paramList) + { + sql += $" AND {param.Key} = @{param.Key}"; + paramter.Add(new MySqlParameter() { ParameterName = param.Key, MySqlDbType = MySqlDbType.VarChar, Value = param.Value }); + values.Add(param.Value); + } + + //Log.Information($"sql: {sql}, param: {string.Join(',', values)}"); + var userInfos = await userCenterRepository.ExecuteSqlToListAsync(sql, paramter.ToArray()); + return userInfos; + } + } + + /// + /// 获取业务线Id + /// + /// + /// + public async Task> GetLineIdAsync(string userids) + { + var ids = userids.Split(','); + var items = await _cmsBaseRepository.GetRepository().Query().Where(f => ids.Contains(f.userid)).Select(o => new WeWorkUser2EidDto + { + userid = o.userid, + eid = o.eid, + deptid = o.deptid + }).ToListAsync(); + return items; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/WeworkUserDomain.cs b/code/Zxd.Core.Domain/WeworkUserDomain.cs new file mode 100644 index 0000000..b0548a2 --- /dev/null +++ b/code/Zxd.Core.Domain/WeworkUserDomain.cs @@ -0,0 +1,22 @@ +using Zxd.Core.Domain.Dto; + +namespace Zxd.Core.Domain +{ + /// + /// + /// + public class WeworkUserDomain + { + /// + /// + /// + /// + /// + public async Task SyncBinding(WeworkWorkerDto dto) + { + var consumers = KafkaClient.GetConsumers(); + Log.Information($"consumers: {consumers.ToJson()}"); + await KafkaClient.SendMessage(consumers.FirstOrDefault(n => n.Topic == "crm-topic"), dto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/WxResourceDomain.cs b/code/Zxd.Core.Domain/WxResourceDomain.cs new file mode 100644 index 0000000..23ac126 --- /dev/null +++ b/code/Zxd.Core.Domain/WxResourceDomain.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Domain.Dto.WxResource; + +namespace Zxd.Core.Domain +{ + public class WxResourceDomain : IWxResourceDomain + { + private readonly IConfiguration _configuration; + private readonly ICacheDomain _cacheDomain; + private readonly SystemConfig _systemConfig; + private readonly IHttpClient _httpClient; + private readonly IBaseRepository _cmsRepository; + private readonly IMapper _mapper; + + public WxResourceDomain( + IConfiguration configuration, + IHttpClient httpClient, + ICacheDomain cacheDomain, + IBaseRepository cmsRepository, + IMapper mapper) + { + _httpClient = httpClient; + _configuration = configuration; + _cacheDomain = cacheDomain; + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _cmsRepository = cmsRepository; + _mapper = mapper; + } + + public async Task> GetUserGroupList(UserGroupQueryDto dto) + { + var url = $"{_systemConfig.GetUserGroupList()}?deptIds={dto.deptid}&page=1&limit=100000"; + if (dto.cateKey.HasValue) + { + url += $"&cateKey={dto.cateKey}"; + } + var response = await _httpClient.GetAsync>>(url); + if (response.Ret == 0) + { + return response.Data.TableData; + } + else + { + Log.Error($"获取分群列表接口报错:{response.Message}"); + throw new ApiException($"获取分群列表接口报错:{response.Message}"); + } + } + + public async Task GetKfSourceCountByCrm(ResourceCountQueryDto dto) + { + ResourceCountPage res = new ResourceCountPage(); + var url = $"{_systemConfig.GetKFSourceCount()}?appid={dto.appid}&userids={dto.userids}&fields=_appuserid,_appid,_headimgurl,_nickname¤tPage={dto.page}&pageSize={dto.limit}&status={dto.status}&subscribe={dto.subscribe}&group_ids={dto.groupids}"; + var response = await _httpClient.GetAsync>>(url); + if (response.Ret == 0) + { + res.Total = response.Data.TableData.Count(); + res.Data = response.Data.TableData.ToList(); + var userids = dto.userids.Split(",").ToList(); + List resRelationModels = new List(); + var groupid = 0; + Int32.TryParse(dto.groupids, out groupid); + var oldLogs = new List(); + var allOldFromLog = await _cmsRepository.GetRepository().Query().Where(x => x.Appid == dto.appid && userids.Contains(x.FromUserid) && x.Status != ResourceFlowStatus.转移成功).ToListAsync(); + if (groupid > 0) + { + oldLogs = allOldFromLog.Where(x => x.GroupId == groupid).ToList(); + } + //最近一天的 不让重新分配 + var notPassFromLog = allOldFromLog.Where(n => n.FlowTime >= DateTime.Now.AddDays(-1)).ToList(); + oldLogs.AddRange(notPassFromLog); + foreach (var userid in userids) + { + url = $"{_systemConfig.GetKFSourceCount()}?appid={dto.appid}&userids={userid}&fields=_appuserid,_appid,_headimgurl,_nickname¤tPage={dto.page}&pageSize={dto.limit}&status={dto.status}&subscribe={dto.subscribe}&group_ids={dto.groupids}"; + response = await _httpClient.GetAsync>>(url); + if (response.Ret == 0) + { + var relation = response.Data.TableData; + foreach (var entity in relation) + { + ResRelationModel model = new ResRelationModel + { + _appid = entity._appid, + _appuserid = entity._appuserid, + _headimgurl = entity._headimgurl, + _nickname = entity._nickname, + _fromuserid = userid + }; + var log = oldLogs.FirstOrDefault(n => n.Appuserid == model._appuserid && n.FromUserid == userid); + if (log != null) + { + model._done = true; + } + resRelationModels.Add(model); + } + } + } + resRelationModels = resRelationModels.ToList(); + res.ResRelationModel = resRelationModels; + res.DoneModel = resRelationModels.Where(n => n._done).ToList(); + res.RelationCount = resRelationModels.Count(); + //去重 + var distinctData = new List(); + List containStr = new List(); + foreach (var entity in res.Data) + { + var key = $"{entity._appid}_{entity._appuserid}"; + if (containStr.Contains(key)) + { + continue; + } + containStr.Add(key); + distinctData.Add(entity); + } + res.Total = distinctData.Count(); + res.Data = distinctData.ToList(); + res.UseCount = distinctData.Where(n => resRelationModels.Where(n => !n._done).Select(n => n._appuserid).Contains(n._appuserid)).Count(); + res.UseData = distinctData.Where(n => resRelationModels.Where(n => !n._done).Select(n => n._appuserid).Contains(n._appuserid)).ToList(); + res.DoneCount = resRelationModels.Where(n => n._done).Count(); + return res; + } + else + { + Log.Error($"获取分群列表接口报错:{response.Message}"); + throw new ApiException($"获取分群列表接口报错:{response.Message}"); + } + } + + public async Task> GetKfSourceCount(ResourceCountQueryDto dto) + { + var url = $"{_systemConfig.GetKFSourceCount()}?appid={dto.appid}&userids={dto.userids}&fields=_appuserid,_appid,_headimgurl,_nickname¤tPage={dto.page}&pageSize={dto.limit}&status={dto.status}&subscribe={dto.subscribe}"; + if (!string.IsNullOrWhiteSpace(dto.groupids)) + { + url += $"&group_ids={dto.groupids}"; + } + var response = await _httpClient.GetAsync>>(url); + if (response.Ret == 0) + { + return response.Data; + } + else + { + Log.Error($"获取分群列表接口报错:{response.Message}"); + throw new ApiException($"获取分群列表接口报错:{response.Message}"); + } + } + + public async Task SubmitSourceTask(ResourceConfigCreateDto dto) + { + //校验 + if (dto.ToUser.Count == 0) + { + throw new Exception("接替者不能为空"); + } + if (dto.FromUser.Count == 0) + { + throw new Exception("转移成员不能为空"); + } + try + { + ResourceFlowConfig config = new ResourceFlowConfig + { + GroupId = dto.groupid, + Appid = dto.appid, + Eid = dto.eid, + Ename = dto.ename, + GroupName = dto.gname, + FlowCount = dto.flowCount, + Ctime = DateTime.Now, + Deptid = dto.deptId, + Status = ResourceConfigStatus.待执行 + }; + await _cmsRepository.GetRepository().InsertAsync(config); + List fromList = new List(); + foreach (var item in dto.FromUser) + { + fromList.Add(new ResourceFlowConfigFrom + { + ConfigId = config.Id, + Eid = item.eid, + Ename = item.ename, + Userid = item.userid, + Ctime = DateTime.Now, + GroupId = dto.groupid, + }); + } + List toList = new List(); + foreach (var item in dto.ToUser) + { + toList.Add(new ResourceFlowConfigTo + { + ConfigId = config.Id, + Eid = item.eid, + Ename = item.ename, + FlowCount = item.flowCount, + Userid = item.userid, + Ctime = DateTime.Now, + GroupId = dto.groupid + }); + } + await _cmsRepository.GetRepository().BatchInsertAsync(fromList); + await _cmsRepository.GetRepository().BatchInsertAsync(toList); + } + catch (Exception ex) + { + Log.Error($"提交企微流转任务失败{ex.Message}"); + throw ex; + } + } + + public async Task> GetSourceTaskPage(SearchSourceTaskDto dto) + { + //PageResult res = new PageResult(); + var deptids = new List(); + if (!string.IsNullOrWhiteSpace(dto.deptids)) + { + deptids = dto.deptids.Split(",").Select(n => Convert.ToInt32(n)).ToList(); + } + var query = _cmsRepository.GetRepository().Query(); + if (deptids.Any()) + { + query = query.Where(n => deptids.Contains(n.Deptid)); + } + var data = await query + .OrderByDescending(x => x.Id) + .Select(x => new SourceTaskModel + { + Id = x.Id, + GroupId = x.GroupId, + GroupName = x.GroupName, + Appid = x.Appid, + Eid = x.Eid, + Ename = x.Ename, + Date = x.Ctime.ToString("yyyy-MM-dd"), + FlowCount = x.FlowCount, + Deptid = x.Deptid, + SuccessCount = x.ResourceFlowLog.Where(n => n.Status == ResourceFlowStatus.转移成功).Count(), + }) + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + var total = await query.CountAsync(); + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + public async Task> GetFromUserPage(SearchFromDto dto) + { + return await _cmsRepository.GetRepository().Query().Where(n => n.ConfigId == dto.Id).ToListAsync(); + } + + public async Task GetToUserPage(SearchToDto dto) + { + ToUserTotalModel result = new ToUserTotalModel(); + + List res = new List(); + var toUserList = await _cmsRepository.GetRepository().Query().Where(n => n.ConfigId == dto.Id).ToListAsync(); + var logList = await _cmsRepository.GetRepository().Query().Where(n => n.ConfigId == dto.Id).ToListAsync(); + foreach (var toUser in toUserList) + { + ToUserModel model = new ToUserModel + { + Eid = toUser.Eid, + Ename = toUser.Ename, + FlowCount = logList.Where(n => n.ToUserid == toUser.Userid).Select(n => n.Appuserid).Distinct().Count(), + Userid = toUser.Userid, + SuccessCount = logList.Where(n => n.ToUserid == toUser.Userid && n.Status == ResourceFlowStatus.转移成功).Select(n => n.Appuserid).Distinct().Count(), + NoneCount = logList.Where(n => n.ToUserid == toUser.Userid && n.Status == ResourceFlowStatus.无好友关系).Select(n => n.Appuserid).Distinct().Count(), + ForbidCount = logList.Where(n => n.ToUserid == toUser.Userid && n.Status == ResourceFlowStatus.成员禁用).Select(n => n.Appuserid).Distinct().Count(), + RefundCount = logList.Where(n => n.ToUserid == toUser.Userid && n.Status == ResourceFlowStatus.用户拒绝).Select(n => n.Appuserid).Distinct().Count(), + OtherCount = logList.Where(n => n.ToUserid == toUser.Userid && n.Status == ResourceFlowStatus.转移失败).Select(n => n.Appuserid).Distinct().Count(), + }; + res.Add(model); + } + result.ToUserModel = res; + result.FailCount = res.Sum(n => n.RefundCount) + res.Sum(n => n.ForbidCount) + res.Sum(n => n.RefundCount) + res.Sum(n => n.OtherCount); + return result; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Domain/Zxd.Core.Domain.csproj b/code/Zxd.Core.Domain/Zxd.Core.Domain.csproj new file mode 100644 index 0000000..720881d --- /dev/null +++ b/code/Zxd.Core.Domain/Zxd.Core.Domain.csproj @@ -0,0 +1,76 @@ + + + + net6.0 + enable + enable + True + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/Zxd.Core.Shared/CommonApiResult.cs b/code/Zxd.Core.Shared/CommonApiResult.cs new file mode 100644 index 0000000..ceaf79c --- /dev/null +++ b/code/Zxd.Core.Shared/CommonApiResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Shared +{ + public class CommonApiResult where T : class + { + public int code { get; set; } + public string? message { get; set; } + public T data { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Shared/Dto/DeptmentDto.cs b/code/Zxd.Core.Shared/Dto/DeptmentDto.cs new file mode 100644 index 0000000..7f2c082 --- /dev/null +++ b/code/Zxd.Core.Shared/Dto/DeptmentDto.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Shared.Dto +{ + public class DeptmentDto + { + public int Id { get; set; } + public int? GroupId { get; set; } + public string? Title { get; set; } + + public string? Code { get; set; } + + public string? Appid { get; set; } + + public int DepartmentId { get; set; } + + public bool? IsDept { get; set; } + + public string? CompanyCode { get; set; } + + public int? SortNo { get; set; } + + public List? DeptmentCampains { get; set; } + } + + public class DeptmentCampainDto + { + public int StartCampainId { get; set; } + + public int EndCampainId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Shared/Dto/WeWorkTagDto.cs b/code/Zxd.Core.Shared/Dto/WeWorkTagDto.cs new file mode 100644 index 0000000..d6cf736 --- /dev/null +++ b/code/Zxd.Core.Shared/Dto/WeWorkTagDto.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Shared.Dto +{ + /// + /// 企业微信打标签 + /// + public class WeWorkTagDto + { + /// + /// 账号类型 + /// + public string appId { get; set; } + /// + /// 账号 + /// + public string appUserid { get; set; } + /// + /// + /// + public string tagName { get; set; } + + /// + /// 指定企业微信,如果指定了,那么只能按照指定的企业微信进行打标签,不会去查找所有关联的企微进行标签 + /// + public string targAppId { get; set; } + } +} diff --git a/code/Zxd.Core.Shared/Dto/WeworkWorkerDto.cs b/code/Zxd.Core.Shared/Dto/WeworkWorkerDto.cs new file mode 100644 index 0000000..04c1afa --- /dev/null +++ b/code/Zxd.Core.Shared/Dto/WeworkWorkerDto.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Core.Shared.Dto +{ + public class WeworkWorkerDto + { + public string? type { get; set; } + public string? cid { get; set; } + public string? appid { get; set; } + public string? appuserid { get; set; } + public string? userid { get; set; } + public int? deptid { get; set; } + public int? olddeptid { get; set; } + public string? resid { get; set; } + public DateTime? regdate { get; set; } + public int? ch { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Shared/Helpers/ApiDockHelper.cs b/code/Zxd.Core.Shared/Helpers/ApiDockHelper.cs new file mode 100644 index 0000000..192f8b3 --- /dev/null +++ b/code/Zxd.Core.Shared/Helpers/ApiDockHelper.cs @@ -0,0 +1,327 @@ +using DG.Tool; + +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Text.Encodings.Web; +using System.Text.Json; +using Zxd.Core.Shared.Helpers; + +namespace WX.CRM.Common.Employee +{ + public class ApiDockHelper + { + public ApiDockHelper(string username, string secret) + { + UserName = username; + Secret = secret; + } + /// + /// Get方法访问API + /// + /// + /// + public ApiResultTemp GetApi(string url, Dictionary param) + { + try + { + + //拼接验证头 + Dictionary header = new Dictionary(); + var timestamps = GetTimeStamp(); + var sign = GetSign(param, timestamps); + var authorization = $"{UserName}:{sign}"; + + header.Add("authorization", authorization); + header.Add("timestamps", timestamps); + + //请求 + var req = HttClientGet(url, param, header); + LogHelper.Write("alipay:" + req); + //返回 + var reqInfo = JsonHelper.FromJson>(req); + if (reqInfo == null) + { + return new ApiResultTemp { ret = 501, msg = "数据为空" }; + } + return reqInfo; + } + catch (Exception ex) + { + return new ApiResultTemp { ret = 501, msg = ex.Message }; + } + } + /// + /// post方法访问api + /// + /// + /// + /// + /// + public ApiResultTemp PostApi(string url, Dictionary param) + { + try + { + //拼接验证头 + Dictionary header = new Dictionary(); + var timestamps = GetTimeStamp(); + var sign = GetSign(param, timestamps); + var authorization = $"{UserName}:{sign}"; + + header.Add("authorization", authorization); + header.Add("timestamps", timestamps); + + //请求 + var req = Post(url, param, header); + //LogHelper.Info("alipay:" + req); + //返回 + var reqInfo = JsonHelper.FromJson>(req); + if (reqInfo == null) + { + return new ApiResultTemp { ret = 501, msg = "数据为空" }; + } + return reqInfo; + } + catch (Exception ex) + { + return new ApiResultTemp { ret = 501, msg = ex.Message }; + } + } + + #region 内部参数 + private string UserName { get; set; } + private string Secret { get; set; } + //DG_SOFTWARE + //private string IdentityKey { get; set; } + #endregion + + #region 内部方法 + /// + /// 内置请求 + /// + /// + /// + private string HttClientGet(string url, Dictionary param, Dictionary header) + { + try + { + var urlParam = string.Join("&", param.Select(m => m.Key + "=" + m.Value)); + if (url.IndexOf('?') > -1) + { + url = url + urlParam; + } + else + { + url = (url + "?" + urlParam); + } + + //MethodInfo priMethod = webReq.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic); + //priMethod.Invoke(webReq.Headers, new[] { "Date", timestamps }); + + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(); + httpRequestMessage.RequestUri = new Uri(url); + httpRequestMessage.Method = HttpMethod.Get; + foreach (var item in header) + { + httpRequestMessage.Headers.TryAddWithoutValidation(item.Key, item.Value); + } + //HttpContent httpContent = new StringContent(""); + //httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + //httpRequestMessage.Content = httpContent; + + var result = Send(httpRequestMessage); + + return result; + } + catch (Exception E) + { + throw E; + } + } + public static string Send(HttpRequestMessage httpRequestMessage) + { + using (HttpClient client = new HttpClient()) + { + HttpResponseMessage response = client.SendAsync(httpRequestMessage).Result; + return response.Content.ReadAsStringAsync().Result; + } + } + + + /// + /// 内置请求 + /// + /// + /// + private string Post(string url, Dictionary param, Dictionary header) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + //请求设置 + request.Method = "POST"; + request.ContentType = "application/json;charset=UTF-8"; + request.Timeout = 3000;//设置超时时间 + //拼接请求头 + foreach (var item in header) + { + request.Headers.Add(item.Key, item.Value); + } + //拼接参数 + if (param.Any()) + { + var pStr = JsonHelper.ToJson(param); + + byte[] data = Encoding.UTF8.GetBytes(pStr); + using (Stream stream = request.GetRequestStream()) + { + stream.Write(data, 0, data.Length); + } + } + //提交请求 + HttpWebResponse response; + try + { + response = (HttpWebResponse)request.GetResponse(); + + } + catch (WebException ex) + { + response = (HttpWebResponse)ex.Response; + } + //解析请求结果 + using (Stream myResponseStream = response.GetResponseStream()) + { + StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); + string retString = myStreamReader.ReadToEnd(); + myStreamReader.Close(); + //记录请求情况 + LogHelper.Write($"url:{url},param:{JsonHelper.ToJson(param)},header:{JsonHelper.ToJson(header)}"); + + return retString; + } + } + + /// + /// 内置请求 + /// + /// + /// + private string Get(string url, Dictionary param, Dictionary header) + { + var urlParam = string.Join("&", param.Select(m => m.Key + "=" + m.Value)); + if (url.IndexOf('?') > -1) + { + url = url + urlParam; + } + else + { + url = (url + "?" + urlParam); + } + + HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(url)); + //MethodInfo priMethod = webReq.Headers.GetType().GetMethod("AddWithoutValidate", BindingFlags.Instance | BindingFlags.NonPublic); + //priMethod.Invoke(webReq.Headers, new[] { "Date", timestamps }); + + foreach (var item in header) + { + webReq.Headers.Add(item.Key, item.Value); + } + webReq.Method = "GET"; + webReq.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; + webReq.Headers.Add("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"); + webReq.UserAgent = "Mozilla/5.0 (Windows NT 5.2; rv:12.0) Gecko/20100101 Firefox/12.0"; + + //webReq.Method = "get"; + //webReq.ContentType = "application/x-www-form-urlencoded"; + webReq.ContentType = "application/json;charset=UTF-8"; + //webReq.Timeout = 3000;//设置超时时间 + + HttpWebResponse response = (HttpWebResponse)webReq.GetResponse(); + StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8); + var _Result = sr.ReadToEnd(); + sr.Close(); + response.Close(); + return _Result; + } + /// + /// 计算签名 + /// + /// + /// + /// + private string GetSign(Dictionary param, string timestamps) + { + + //一次排序 + var newP = param.OrderBy(m => m.Key).ToDictionary(m => m.Key, n => n.Value); + var pJosn = JsonSerializer.Serialize(newP, new JsonSerializerOptions + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + IgnoreNullValues = true + }); + //二次排序 + var enStrList = new string[] { UserName, pJosn, Secret, timestamps }; + Array.Sort(enStrList, string.CompareOrdinal); + + //拼接 + var enStr = string.Join("", enStrList); + //md5 加密 + return _md5(enStr); + } + /// + /// 计算 md5 + /// + /// + /// + public string _md5(string enCode) + { + string res = ""; + byte[] data = Encoding.GetEncoding("utf-8").GetBytes(enCode); + MD5 md5 = new MD5CryptoServiceProvider(); + byte[] bytes = md5.ComputeHash(data); + for (int i = 0; i < bytes.Length; i++) + { + res += bytes[i].ToString("x2"); + } + return res; + } + /// + /// 获取时间戳 + /// + /// + private string GetTimeStamp() + { + TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0); + return Convert.ToInt64(ts.TotalSeconds).ToString(); + } + #endregion + } + + /// + /// code:状态码,0为请求成功; + /// 部分状态说明 + /// -1 未知异常 + /// -1001 签名不合法 + /// -1002 签名验证失败 + /// -1003 请求内容不合法 + /// -1004 AppID不合法 + // -1005 签名已过期 + /// + /// + public class ApiResultTemp + { + public int code { get; set; } + /// + /// -1 未知异常 + /// -1001 签名不合法 + /// -1002 签名验证失败 + /// -1003 请求内容不合法 + /// -1004 AppID不合法 + // -1005 签名已过期 + /// + public int ret { get; set; } + public T data { get; set; } + public string msg { get; set; } + + public string message { get; set; } + } +} diff --git a/code/Zxd.Core.Shared/Helpers/ConvertHelper.cs b/code/Zxd.Core.Shared/Helpers/ConvertHelper.cs new file mode 100644 index 0000000..24faf75 --- /dev/null +++ b/code/Zxd.Core.Shared/Helpers/ConvertHelper.cs @@ -0,0 +1,228 @@ +using System.Text; +using System.Text.RegularExpressions; + +namespace Zxd.Core.Shared.Helpers +{ + public class ConvertHelper + { + public static bool? GetBoolean(string input) + { + return GetBoolean(input, null); + } + + public static bool? GetBoolean(string input, bool? defaultValue) + { + if (bool.TryParse(input, out bool temp)) + { + return temp; + } + + return defaultValue; + } + + public static int? GetInt(string input) + { + return GetInt(input, null); + } + + public static int? GetInt(string input, int? defaultValue) + { + if (!string.IsNullOrEmpty(input)) + { + if (int.TryParse(input, out int temp)) + { + return temp; + } + } + + return defaultValue; + } + + public static long? GetLong(string input) + { + return GetLong(input, null); + } + + public static long? GetLong(string input, long? defaultValue) + { + if (!string.IsNullOrEmpty(input)) + { + if (long.TryParse(input, out long temp)) + { + return temp; + } + } + + return defaultValue; + } + + public static decimal? GetDecimal(string input) + { + return GetDecimal(input, null); + } + + public static decimal? GetDecimal(string input, decimal? defaultValue) + { + if (!string.IsNullOrEmpty(input)) + { + if (decimal.TryParse(input, out decimal temp)) + { + return temp; + } + } + + return defaultValue; + } + + public static DateTime? GetDateTime(string input) + { + return GetDateTime(input, null); + } + + public static DateTime? GetDateTime(string input, DateTime? defaultValue) + { + if (DateTime.TryParse(input, out DateTime temp)) + { + return temp; + } + + return defaultValue; + } + + public static DateTime? GetDateTimeExact(string input, string format) + { + return GetDateTimeExact(input, format, null); + } + + public static DateTime? GetDateTimeExact(string input, string format, DateTime? defaultValue) + { + if (DateTime.TryParseExact(input, format, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out DateTime temp)) + { + return temp; + } + + return defaultValue; + } + + public static decimal? ParseNumberFromString(string input) + { + return ParseNumberFromString(input, false); + } + + public static decimal? ParseNumberFromString(string input, bool exact_mode) + { + var exact_input = ""; + if (exact_mode) + { + var matches = Regex.Matches(input, "([0-9]+[.]?[0-9]+)"); + if (matches.Count > 0) + { + if (matches[0].Groups.Count > 1) + { + exact_input = matches[0].Groups[1].Value; + } + } + } + else + { + var sb = new StringBuilder(); + foreach (var ch in input) + { + if (!char.IsNumber(ch) && ch != '.') + { + continue; + } + + sb.Append(ch); + } + exact_input = sb.ToString(); + } + + return GetDecimal(exact_input); + } + + public static object GetVal(Type ttype, string val) + { + if (ttype == typeof(int) || ttype == typeof(int?)) + { + return GetInt(val).GetValueOrDefault(); + } + else if (ttype == typeof(long) || ttype == typeof(long?)) + { + return GetLong(val).GetValueOrDefault(); + } + else if (ttype == typeof(decimal) || ttype == typeof(decimal?)) + { + return GetDecimal(val).GetValueOrDefault(); + } + else if (ttype == typeof(bool) || ttype == typeof(bool?)) + { + return ParseBooleanFromString(val).GetValueOrDefault(); + } + else if (ttype == typeof(DateTime) || ttype == typeof(DateTime?)) + { + return GetDateTime(val).GetValueOrDefault(); + } + else if (ttype == typeof(string)) + { + return val; + } + else + { + throw new ArgumentException($"不支持的类型:{ttype.Name}"); + } + } + + public static bool? ParseGenderFromString(string input) + { + if (!string.IsNullOrEmpty(input)) + { + var males = new string[] { "1", "男", "true", "m", "male" }; + if (males.Any(a => input.ToLower().Contains(a))) + { + return true; + } + + var females = new string[] { "0", "女", "false", "f", "female" }; + if (females.Any(a => input.ToLower().Contains(a))) + { + return false; + } + } + + return null; + } + + public static bool? ParseBooleanFromString(string input) + { + if (!string.IsNullOrEmpty(input)) + { + var yes = new string[] { "1", "真", "true", "yes" }; + if (yes.Any(a => input.ToLower().Contains(a))) + { + return true; + } + + var no = new string[] { "0", "假", "false", "no" }; + if (no.Any(a => input.ToLower().Contains(a))) + { + return false; + } + } + + return null; + } + + /// + /// + /// java长整型日期,毫秒为单位 + /// + public static DateTime JavaLongToDateTime(long timeJavaLong) + { + var dt1970 = new DateTime(1970, 1, 1, 0, 0, 0); + var tricks1970 = dt1970.Ticks;//1970年1月1日刻度 + var timeTricks = tricks1970 + timeJavaLong * 10000;//日志日期刻度 + return new DateTime(timeTricks).AddHours(8);//转化为DateTime + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.Shared/Helpers/LogHelper.cs b/code/Zxd.Core.Shared/Helpers/LogHelper.cs new file mode 100644 index 0000000..6d65b31 --- /dev/null +++ b/code/Zxd.Core.Shared/Helpers/LogHelper.cs @@ -0,0 +1,143 @@ +using System.Text; + +namespace Zxd.Core.Shared.Helpers +{ + public class LogHelper + { + private static readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + + private static readonly object _lock = new object(); + + public static void Write(string message) + { + Write(message, null); + } + + public static void Write(string message, string directoryName) + { + Write(message, directoryName, null); + } + + public static void Write(string message, string directoryName, string fileName) + { + lock (_lock) + { + if (string.IsNullOrEmpty(message)) + { + return; + } + + string logDirectory; + if (string.IsNullOrEmpty(directoryName)) + { + logDirectory = Path.Combine(new string[] { _baseDirectory ?? "", "Log" }); + } + else + { + logDirectory = Path.Combine(new string[] { _baseDirectory ?? "", "Log", directoryName }); + } + + if (!Directory.Exists(logDirectory)) + { + Directory.CreateDirectory(logDirectory); + } + + var dt = DateTime.Now; + if (string.IsNullOrEmpty(fileName)) + { + fileName = dt.ToString("yyyy-MM-dd") + ".txt"; + } + + var filepath = Path.Combine(new string[] { logDirectory, fileName }); + using (var sw = new StreamWriter(filepath, true, Encoding.UTF8)) + { + sw.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss")); + sw.WriteLine(message); + sw.WriteLine(); + } + } + } + + public static void WriteAsync(string message) + { + WriteAsync(message, null); + } + + public static void WriteAsync(string message, string directoryName) + { + WriteAsync(message, directoryName, null); + } + + public static void WriteAsync(string message, string directoryName, string fileName) + { + Task.Run(() => + { + try + { + WriteAsync(new WriteLogSettings + { + Content = message, + DirectoryName = directoryName, + FileName = fileName + }); + } + catch + { } + }); + } + + private static void WriteAsync(WriteLogSettings settings) + { + Write(settings.Content, settings.DirectoryName, settings.FileName); + } + + public static void WriteDebug(string message) + { + Write(message, "Debug"); + } + + public static void WriteDebug(string message, string fileName) + { + Write(message, "Debug", fileName); + } + + public static void WriteDebugAsync(string message) + { + WriteAsync(message, "Debug"); + } + + public static void WriteDebugAsync(string message, string fileName) + { + WriteAsync(message, "Debug", fileName); + } + + public static void WriteError(string message) + { + Write(message, "Error"); + } + + public static void WriteError(string message, string fileName) + { + Write(message, "Error", fileName); + } + + public static void WriteErrorAsync(string message) + { + WriteAsync(message, "Error"); + } + + public static void WriteErrorAsync(string message, string fileName) + { + WriteAsync(message, "Error", fileName); + } + } + + public class WriteLogSettings + { + public string Content { get; set; } + + public string DirectoryName { get; set; } + + public string FileName { get; set; } + } +} diff --git a/code/Zxd.Core.Shared/Helpers/SecurityHelper.cs b/code/Zxd.Core.Shared/Helpers/SecurityHelper.cs new file mode 100644 index 0000000..37d5997 --- /dev/null +++ b/code/Zxd.Core.Shared/Helpers/SecurityHelper.cs @@ -0,0 +1,43 @@ +using System.Security.Cryptography; +using System.Text; + +namespace Zxd.Core.Shared.Helpers +{ + public class SecurityHelper + { + /// + /// 获取MD5加密的字符串(Unicode编码) + /// + /// + /// + public static string GetMD5String(string input) + { + return GetMD5String(input, Encoding.UTF8); + } + + /// + /// 获取MD5加密的字符串(指定编码) + /// + /// + /// + public static string GetMD5String(string input, Encoding enc) + { + if (string.IsNullOrEmpty(input)) + { + return ""; + } + + var md5 = new MD5CryptoServiceProvider(); + var source = enc.GetBytes(input); + var hashed = md5.ComputeHash(source); + var sb = new StringBuilder(); + + for (int i = 0; i < hashed.Length; i++) + { + sb.Append(hashed[i].ToString("x2")); + } + + return sb.ToString(); + } + } +} diff --git a/code/Zxd.Core.Shared/Helpers/ValidationHelper.cs b/code/Zxd.Core.Shared/Helpers/ValidationHelper.cs new file mode 100644 index 0000000..2d90905 --- /dev/null +++ b/code/Zxd.Core.Shared/Helpers/ValidationHelper.cs @@ -0,0 +1,133 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Reflection; +using System.Text.RegularExpressions; + +namespace Zxd.Core.Shared.Helpers +{ + public class ValidationHelper + { + public static List Validate(T model) where T : class, new() + { + var ttype = typeof(T); + return Validate(ttype, model); + } + + private static List Validate(Type ttype, object model) + { + var validations = new List(); + var tps = ttype.GetProperties(); + foreach (var tp in tps) + { + var valid = true; + var validation = new ValidationResult + { + Display = tp.Name, + Name = tp.Name + }; + + var descriptionAttr = tp.GetCustomAttribute(); + if (descriptionAttr != null) + { + validation.Display = descriptionAttr.Description; + } + + var obj = tp.GetValue(model, null); + if (obj != null) + { + var val = obj.ToString(); + var regexAttr = tp.GetCustomAttribute(); + if (regexAttr != null) + { + if (!Regex.IsMatch(val, regexAttr.Pattern)) + { + valid = false; + validation.Pattern = regexAttr.Pattern; + validation.Message = regexAttr.ErrorMessage; + } + } + + var maxLengthAttr = tp.GetCustomAttribute(); + if (maxLengthAttr != null) + { + if (val.Length > maxLengthAttr.Length) + { + valid = false; + validation.MaxLength = maxLengthAttr.Length; + validation.Message = string.Format(maxLengthAttr.ErrorMessage, maxLengthAttr.Length); + } + } + } + else + { + var requiredAttr = tp.GetCustomAttribute(); + if (requiredAttr != null) + { + valid = false; + validation.Required = true; + validation.Message = requiredAttr.ErrorMessage; + } + } + + if (!valid) + { + validations.Add(validation); + } + } + + return validations; + } + + public static string Validate2(T model) where T : class, new() + { + var ttype = typeof(T); + return Validate2(ttype, model); + } + + public static string Validate2(object obj) + { + var ttype = obj.GetType(); + return Validate2(ttype, obj); + } + + private static string Validate2(Type ttype, object model) + { + var validations = Validate(ttype, model); + var errors = string.Join(",", validations.Select(o => $"[{o.Name}]{o.Display}{o.Message}")); + return errors; + } + } + + public class ValidationResult + { + /// + /// 字段显示 + /// + public string Display { get; set; } + + /// + /// 字段 + /// + public string Name { get; set; } + + /// + /// 消息 + /// + public string Message { get; set; } + + /// + /// 最大长度 + /// + public int MaxLength { get; set; } + + /// + /// 正则模板 + /// + public string Pattern { get; set; } + + /// + /// 必填 + /// + public bool Required { get; set; } + } +} diff --git a/code/Zxd.Core.Shared/Zxd.Core.Shared.csproj b/code/Zxd.Core.Shared/Zxd.Core.Shared.csproj new file mode 100644 index 0000000..d6283bc --- /dev/null +++ b/code/Zxd.Core.Shared/Zxd.Core.Shared.csproj @@ -0,0 +1,15 @@ + + + + net6.0 + enable + enable + True + 1.0.5 + + + + + + + diff --git a/code/Zxd.Core.WebApi/Controllers/ActivityController.cs b/code/Zxd.Core.WebApi/Controllers/ActivityController.cs new file mode 100644 index 0000000..6a5af63 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/ActivityController.cs @@ -0,0 +1,53 @@ +using Zxd.Core.Domain.Dto.Activity; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 活动管理 + /// + [ApiSignatureFilterForbid] + public class ActivityController : BaseController + { + private readonly IActivityDomain _activityDomain; + + /// + /// 达量通知 + /// + /// + public ActivityController( + IActivityDomain activityDomain) + { + _activityDomain = activityDomain; + } + + /// + /// 获取活动名称 + /// + /// + /// + [HttpPost("GetActivityName")] + [ApiResultFilterForbid] + public async Task> GetActivityNameAsync([FromBody] GetActivityNameRequest request) + { + var rsp = new RetResult(null); + rsp.Ret=999; + rsp.Message="系统繁忙,请稍后再试"; + try + { + rsp.Data = await _activityDomain.GetActivityNameAsync(request); + rsp.Ret=0; + rsp.Message="获取成功"; + } + catch (ArgumentException ex) + { + rsp.Message = ex.Message; + rsp.Ret=1; + } + catch (Exception ex) + { + Serilog.Log.Error(ex, "GetActivityName"); + } + return rsp; + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/BaseController.cs b/code/Zxd.Core.WebApi/Controllers/BaseController.cs new file mode 100644 index 0000000..f2e35cb --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/BaseController.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiController] + [Route("Api/[controller]")] + [Produces("application/json")] + public class BaseController : Controller + { + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/BaseSsoController.cs b/code/Zxd.Core.WebApi/Controllers/BaseSsoController.cs new file mode 100644 index 0000000..cfd6519 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/BaseSsoController.cs @@ -0,0 +1,94 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Primitives; +using Zxd.Domain.Sso; + +namespace Zxd.Core.WebApi.Controllers +{ + public class BaseSsoController : BaseController + { + private readonly IServiceProvider _serviceProvider; + protected decimal Eid { get; set; } + + public BaseSsoController(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + if (context == null) return; + using IServiceScope scope = _serviceProvider.CreateScope(); + var configuration = scope.ServiceProvider.GetRequiredService(); + var cacheDomain = scope.ServiceProvider.GetRequiredService(); + var httpClient = scope.ServiceProvider.GetRequiredService(); + var systemConfig = configuration.GetSection("SystemConfig").Get(); + var appid = systemConfig.Appid; + var values = new StringValues(); + context?.HttpContext?.Request.Headers.TryGetValue("token", out values); + var authToken = values.ToString(); + if (!string.IsNullOrEmpty(authToken)) + { + var tokens = await cacheDomain.GetTokens(); + if (tokens != null && tokens.Any() && tokens.Any(x => x.Token == authToken)) + { + var token = tokens.First(x => x.Token == authToken); + if (token.ExpirationTime > DateTime.Now) + { + Eid = token.Eid; + await next.Invoke(); + return; + } + context.Result = new ObjectResult(ApiResult.Failed("token已过期或不合法!", 10001)); + return; + } + var data = new + { + appId = appid, + grantType = 1, + token = authToken + }; + try + { + var response = await httpClient.PostAsync>($"{systemConfig.GetSsoTokenUrl()}", data); + + if (response == null || response.Ret != 0 || !response.Data.EmployeeId.HasValue) + { + context.Result = new ObjectResult(ApiResult.Failed("token已过期或不合法!", 10001)); + return; + } + else + { + var eid = response.Data.EmployeeId.Value; + Eid = eid; + await cacheDomain.AddToken(new SsoUserTokenInfo { Eid = eid, ExpirationTime = DateTime.Now.AddDays(1), Token = authToken }); + await next.Invoke(); + } + } + catch (Exception ex) + { + var testresponse = await httpClient.PostAsync($"{systemConfig.GetSsoTokenUrl()}", data); + Log.Error($"获取{systemConfig.GetSsoTokenUrl()}【{JsonHelper.ToJson(data)}】用户对象为{JsonHelper.ToJson(testresponse)}"); + context.Result = new ObjectResult(ApiResult.Failed("token已过期或不合法!", 10001)); + } + } + else + { + context.Result = new ObjectResult(ApiResult.Failed("token不能为空!", 10002)); + } + } + } + + public class SsoZXDResponseDataDto + { + public string? AccessToken { get; set; } + + public string? RefreshToken { get; set; } + + public string? ExpireTime { get; set; } + + public int? EmployeeId { get; set; } + + public string? ExtensionNumber { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/CallbackController.cs b/code/Zxd.Core.WebApi/Controllers/CallbackController.cs new file mode 100644 index 0000000..52075f6 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/CallbackController.cs @@ -0,0 +1,169 @@ +using DG.Redis; +using Microsoft.EntityFrameworkCore.Query.Internal; +using Zxd.Core.Domain.Dto.Zxd.Callback; +using Zxd.Core.Shared.Helpers; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 回调管理 + /// + [ApiSignatureFilterForbid] + public class CallbackController : BaseController + { + private readonly IRedisManager _redisManager; + + private readonly IOrderDomain _orderDomain; + + private readonly PayCallbackConfig _payCallbackConfig; + + /// + /// + /// + /// + /// + /// + public CallbackController( + IRedisManager redisManager, + IOrderDomain orderDomain, + IConfiguration configuration) + { + _redisManager = redisManager; + _orderDomain = orderDomain; + _payCallbackConfig = configuration.GetSection("PayCallbackConfig").Get(); + } + + /// + /// 支付回调 + /// + /// + /// + [HttpPost("Pay")] + [ApiResultFilterForbid] + public async Task Pay(Dictionary dto) + { + var authorization = default(string); + var timestamps = default(string); + var json = default(string); + var success = false; + try + { + authorization = Request.Headers["authorization"].FirstOrDefault(); + if (string.IsNullOrEmpty(authorization)) + { + throw new ApiException("authorization必填", 1); + } + var parts = authorization.Split(':'); + if (parts.Length != 2) + { + throw new ApiException("authorization无效", 1); + } + var user = parts[0]; + var sign = parts[1]; + //var secret = await _redisManager.GetAsync($"ZxdCore:Secret:{user}"); + var secret = _payCallbackConfig.Secret; + if (string.IsNullOrEmpty(secret)) + { + throw new ApiException("还未配置secret", 999); + } + + timestamps = Request.Headers["timestamps"].FirstOrDefault(); + if (string.IsNullOrEmpty(timestamps)) + { + throw new ApiException("timestamps必填", 1); + } + json = GetSortedJson(dto); + + Log.Information($"Callback,{authorization},{timestamps},{json}"); + + var args = new List { user, json, secret, timestamps }; + args.Sort(new ASCIIComparer()); + var input = string.Join("", args); + var signData = Shared.Helpers.SecurityHelper.GetMD5String(input); + if (signData != sign) + { + throw new ApiException("签名不正确", 2); + } + + var req = Dict2Model(dto); + var invalids = ValidationHelper.Validate2(req); + if (!string.IsNullOrEmpty(invalids)) + { + throw new ApiException(invalids, 1); + } + + await _orderDomain.BindAsync(req); + success = true; + } + catch (Exception ex) + { + Log.Information($"CallbackError,{authorization},{timestamps},{json},{ex}"); + } + return success ? "支付回调成功" : "支付回调失败"; + } + + private string GetSortedJson(Dictionary dto) + { + var items = new List(); + foreach (var p in dto.Keys) + { + items.Add(p); + } + + items.Sort(new ASCIIComparer()); + var dict = new Dictionary(); + foreach (var item in items) + { + var val = dto[item]; + if (val!=null && val.ToString().Length>0) + { + dict[item]=val; + } + } + + return JsonSerializer.Serialize(dict); + } + + private T Dict2Model(Dictionary dict) where T : class, new() + { + var one = new T(); + var t = typeof(T); + var ps = t.GetProperties(); + foreach (var p in ps) + { + if (dict.ContainsKey(p.Name)) + { + var val = dict[p.Name]; + if (val != null) + { + var val_real = ConvertHelper.GetVal(p.PropertyType, val.ToString()); + p.SetValue(one, val_real, null); + } + } + } + return one; + } + } + + public class ASCIIComparer : IComparer + { + public int Compare(string x, string y) + { + var len = x.Length > y.Length ? y.Length : x.Length; + for (var i = 0; i < len; i++) + { + if (x[i] < y[i]) + { + return -1; + } + + if (x[i] > y[i]) + { + return 1; + } + } + + return 0; + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/ContractController.cs b/code/Zxd.Core.WebApi/Controllers/ContractController.cs new file mode 100644 index 0000000..b709c6d --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/ContractController.cs @@ -0,0 +1,32 @@ +using Zxd.Core.Domain.Dto.Contract; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class ContractController : BaseController + { + private readonly IProdcutDomain _prodcutDomain; + + public ContractController(IProdcutDomain prodcutDomain) + { + _prodcutDomain = prodcutDomain; + } + + /// + /// 基础产品列表 + /// + /// + /// + [HttpGet("GetContractByFreeOrder")] + public async Task GetContractAddressByFreeOrder([FromQuery] decimal orderId) + { + return await _prodcutDomain.GetContractByFreeOrderId(orderId); + } + + [HttpGet("GetContractView")] + public async Task GetContractView([FromQuery] ContractQueryDto queryDto) + { + return await _prodcutDomain.GetContractView(queryDto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/CustomerController.cs b/code/Zxd.Core.WebApi/Controllers/CustomerController.cs new file mode 100644 index 0000000..1fe0ead --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/CustomerController.cs @@ -0,0 +1,161 @@ +using Zxd.Core.Domain.Dto.Crm; +using Zxd.Core.Domain.Dto.Wework; +using Zxd.Core.Domain.Dto.Zxd.Order; +using static Zxd.Domain.Impl.ICustomerDomain; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class CustomerController : BaseController + { + private readonly ICustomerDomain _customerDomain; + private readonly IOrderDomain _orderDomain; + + public CustomerController(ICustomerDomain customerDomain, IOrderDomain orderDomain) + { + _customerDomain = customerDomain; + _orderDomain = orderDomain; + } + + + /// + /// 获取用户名 + /// + /// + /// + [HttpGet("Usernames")] + public async Task> GetUsernames(string? resId) + { + return await _customerDomain.GetUsernames(resId); + } + + /// + /// 通过订单获取当时下单的用户名 + /// + /// + /// + [HttpGet("UsernamesByOrderid")] + public async Task> GetUsernamesByOrderid(string? orderidList) + { + return await _customerDomain.GetUsernamesByOrderid(orderidList); + } + + /// + /// 获取销售线索 + /// + /// + /// + [HttpGet("SalesLeads")] + public async Task> GetSalesLeadList(string? resId) + { + return await _customerDomain.GetSalesLeadList(resId); + } + + /// + /// 创建客户 + /// + /// + [HttpGet("CreateCustomer")] + public async Task CreateCustomer(string MOBILE, string ResId, string CustomerFrom) + { + return await _customerDomain.CreateCustomer(MOBILE, ResId, CustomerFrom); + } + + /// + /// 获取关注状况 + /// + /// + /// + [HttpPost()] + public async Task> GetFollow(List queryList) + { + return await _customerDomain.GetFollow(queryList); + } + + /// + /// 获取企业微信用户下拉选择 + /// + /// + /// + [HttpGet("GetWorkWXUserSelect")] + public async Task> GetWorkWXUserSelectAsync(string? ResId, string? DeptCode) + { + return await _customerDomain.GetWorkWXUserSelectAsync(ResId, DeptCode); + } + + /// + /// 获取企业微信付费版本绑定的ID + /// + /// + /// + [HttpGet("ExtUserBandGet")] + public async Task> ExtUserBandGetAsync(string? ResId) + { + return await _customerDomain.ExtUserBandGetAsync(ResId); + }/// + + /// 根据外部联系人Userid获取resid + /// + /// + [HttpPost("GetResidByExtUser")] + public async Task> GetResidByExtUser([FromBody] string extUser) + { + List userids = extUser.Split(',').ToList(); + return await _customerDomain.GetResidByExtuser(userids); + } + + /// + /// 根据外部联系人Unionid获取Phone + /// + /// + [HttpGet("GetPhoneByUnionid")] + public async Task> GetPhoneByUnionid(string unionid) + { + return await _customerDomain.GetPhoneByUnionid(unionid); + } + + /// + /// 初始化客户 + /// + /// + /// + [HttpPost("initCustomerPasstime")] + public async Task initResPassTime([FromBody] ResPassTimeDto dto) + { + return await _orderDomain.initResPassTime(dto); + } + + /// + /// 添加标签 + /// + /// + /// + [HttpPost("AddTag")] + public async Task AddTag([FromBody] ResTagAddDto dto) + { + return await _customerDomain.AddTag(dto.resid, dto.tag, dto.ceid); + } + + /// + /// 获取标签 + /// + /// + /// + [HttpGet("GetTag")] + public async Task> GetTag(string resid) + { + return await _customerDomain.GetTag(resid); + } + + /// + /// 删除标签 + /// + /// + /// + [HttpPost("DelTag")] + public async Task DelTag([FromBody] DelResTagDto dto) + { + return await _customerDomain.DelTag(dto.id, dto.deleteeid); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/DeptmentController.cs b/code/Zxd.Core.WebApi/Controllers/DeptmentController.cs new file mode 100644 index 0000000..932f907 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/DeptmentController.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using Zxd.Core.Domain.Dto.Wework; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class DeptmentController : BaseController + { + private readonly IDeptmentDomain _deptDomain; + + /// + /// + /// + /// + public DeptmentController(IDeptmentDomain deptDomain) + { + _deptDomain = deptDomain; + } + + /// + /// 获取事业部 + /// + /// + /// + [HttpGet("Depts")] + public async Task> GetDeptments(bool? IsDept = null) + { + return await _deptDomain.GetDeptments(IsDept); + } + + /// + /// 根据渠道号获取事业部 + /// + /// + /// + [HttpGet("Dept")] + public async Task GetDeptmentByChannel([Required] int channel) + { + return await _deptDomain.GetDeptmentByChannel(channel); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/EarlyWarningController.cs b/code/Zxd.Core.WebApi/Controllers/EarlyWarningController.cs new file mode 100644 index 0000000..48320d6 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/EarlyWarningController.cs @@ -0,0 +1,75 @@ +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 达量通知 + /// + [ApiSignatureFilterForbid] + public class EarlyWarningController : BaseController + { + private readonly IEarlyWarningDomain _earlyWarningDomain; + + /// + /// 达量通知 + /// + /// + public EarlyWarningController(IEarlyWarningDomain earlyWarningDomain) + { + _earlyWarningDomain = earlyWarningDomain; + } + + /// + /// 达量通知日志分页 + /// + /// + /// + /// + [HttpGet("log/page")] + public async Task> GetEarlyWarningLogPage([FromQuery] SearchEarlyWarningLogDto dto, [FromQuery] string? sgin) + { + return await _earlyWarningDomain.GetEarlyWarningLogPage(dto, sgin); + } + + /// + /// 达量通知日志明细 + /// + /// + /// + [HttpGet("log/detail")] + public async Task GetEarlyWarningDetail(int id) + { + return await _earlyWarningDomain.GetEarlyWarningDetail(id); + } + + /// + /// 达量通知状态更新 + /// + /// + /// + [HttpPost("log/status")] + public async Task UpdateEarlyWarningStatus([FromBody] UpdateEarlyWarningStatusDto dto) + { + await _earlyWarningDomain.UpdateEarlyWarningStatus(dto); + } + + /// + /// 触发达量通知任务 + /// + /// + [HttpGet("sync")] + public async Task EarlyWarningSync() + { + await _earlyWarningDomain.EarlyWarningSync(); + } + + /// + /// 获取员工加微数 + /// + /// + /// + [HttpPost("ExternalUserTotal")] + public async Task> GetExternalUserTotal([FromBody]SearchExternalUserTotalDto dto) + { + return await _earlyWarningDomain.GetExternalUserTotal(dto); + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/FinishedProductController.cs b/code/Zxd.Core.WebApi/Controllers/FinishedProductController.cs new file mode 100644 index 0000000..ca6e6b6 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/FinishedProductController.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Zxd.Domain.Dto.Zxd; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 成品产品 + /// + [ApiSignatureFilterForbid] + public class FinishedProductController : BaseController + { + private readonly IFinishedProductDomain _finishedProductDomain; + private readonly IServiceProvider _serviceProvider; + + public FinishedProductController(IFinishedProductDomain finishedProductDomain, + IServiceProvider serviceProvider) + //: base(serviceProvider) + { + _finishedProductDomain = finishedProductDomain; + _serviceProvider = serviceProvider; + } + + /// + /// 获取产品系列 + /// + /// + [HttpGet("Select/Series")] + public async Task> GetProductSeriesSelect() + { + return await _finishedProductDomain.GetProductSeriesSelect(); + } + + /// + /// 获取产品大类 + /// + /// 系列 + /// + [HttpGet("Select/Category")] + public async Task> GetProductCategorySelect(int? productSeriesId) + { + return await _finishedProductDomain.GetProductCategorySelect(productSeriesId); + } + + /// + /// 获取基准产品信息 + /// + /// + /// + [HttpGet("standard")] + public async Task GetStandardProduct(int productid) + { + return await _finishedProductDomain.GetStandardProduct(productid); + } + + /// + /// 创建成品产品 + /// + /// + /// + [HttpPost("create")] + public async Task CreateFinishedProduct([FromBody] CreateFinishedProductDto dto) + { + await _finishedProductDomain.CreateFinishedProduct(dto); + } + + /// + /// 编辑成品产品 + /// + /// + /// + [HttpPost("edit")] + public async Task EditFinishedProduct(EditFinishedProductDto dto) + { + await _finishedProductDomain.EditFinishedProduct(dto); + } + + /// + /// 获取成品产品详情 + /// + /// + /// + [HttpGet("detail")] + public async Task GetFinishedProductDetail(int productid) + { + return await _finishedProductDomain.GetFinishedProductDetail(productid); + } + + /// + /// 成品产品分页 + /// + /// + /// + [HttpGet("page")] + public async Task> FinishedProductPage([FromQuery] SearchFinishedProductDto dto) + { + return await _finishedProductDomain.FinishedProductPage(dto); + } + + /// + /// 获取赠送产品设置 + /// + /// + /// + [HttpGet("actives")] + public async Task> Getctives(string? productCode) + { + return await _finishedProductDomain.GetActives(productCode); + } + + /// + /// 删除赠送产品 + /// + /// + /// + [HttpDelete("active")] + public async Task DeleteActive(int? id) + { + await _finishedProductDomain.DeleteActive(id); + } + + /// + /// 创建或修改成品产品的赠送产品 + /// + /// + /// + [HttpPost("active")] + public async Task CreateOrEditActive([FromBody] CreateOrEditActiveDto dto) + { + await _finishedProductDomain.CreateOrEditActive(dto); + } + + /// + /// 创建或修改赠送产品 + /// + /// + /// + [HttpPost("gift")] + public async Task CreateOrEditProductGift([FromBody] CreateOrEditProducGiftDto dto) + { + await _finishedProductDomain.CreateOrEditProductGift(dto); + } + + /// + /// 删除赠送产品 + /// + /// + /// + [HttpDelete("gift")] + public async Task DeleteProductGift(int? id) + { + await _finishedProductDomain.DeleteProductGift(id); + } + } +} + diff --git a/code/Zxd.Core.WebApi/Controllers/ImportanceItemController.cs b/code/Zxd.Core.WebApi/Controllers/ImportanceItemController.cs new file mode 100644 index 0000000..aab05df --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/ImportanceItemController.cs @@ -0,0 +1,40 @@ +using System.ComponentModel.DataAnnotations; +using Zxd.Core.Domain.Dto.ImportanceItem; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 重要线索事件 + /// + [ApiSignatureFilterForbid] + public class ImportanceItemController : BaseController + { + private readonly IImportanceItemDomain _importanceItemDomain; + public ImportanceItemController(IImportanceItemDomain importanceItemDomain) + { + _importanceItemDomain = importanceItemDomain; + } + + /// + /// 获取客户重要线索事件 + /// + /// + /// + [HttpGet("list")] + public async Task> GetCustomerBehaviorLog([FromQuery] SearchCustomerBehaviorLogDto dto) + { + return await _importanceItemDomain.GetCustomerBehaviorLog(dto); + } + + /// + /// 获取客户重要线索统计 + /// + /// + /// + [HttpGet("statistics")] + public async Task> GetCustomerBehaviorStatistics([FromQuery] SearchCustomerBehaviorLogDto dto) + { + return await _importanceItemDomain.GetCustomerBehaviorStatistics(dto); + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/InneruserController.cs b/code/Zxd.Core.WebApi/Controllers/InneruserController.cs new file mode 100644 index 0000000..09468a5 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/InneruserController.cs @@ -0,0 +1,36 @@ +using Zxd.Core.Domain.Dto; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiController] + [Route("[controller]")] + public class InneruserController : ControllerBase + { + private readonly IInneruserDomain _inneruserDomain; + public InneruserController(IInneruserDomain inneruserDomain) + { + _inneruserDomain = inneruserDomain; + } + + /// + /// SSO同步 + /// + /// + [HttpGet("[action]")] + public async Task SyncSsoOrganization() + { + return await _inneruserDomain.SyncSsoOrganization(); + } + + /// + /// 获取员工组织架构 + /// + /// + [HttpGet("Organization")] + [ApiSignatureFilterForbid] + public async Task> GetOrganization() + { + return await _inneruserDomain.GetOrganization(); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/MeetingController.cs b/code/Zxd.Core.WebApi/Controllers/MeetingController.cs new file mode 100644 index 0000000..57e4d56 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/MeetingController.cs @@ -0,0 +1,62 @@ +using System; +using Zxd.Core.Domain.Dto.Zxd; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class MeetingController : BaseSsoController + { + private readonly IMeetingDomain _meetingDomain; + public MeetingController(IMeetingDomain meetingDomain, + IServiceProvider serviceProvider) + : base(serviceProvider) + { + _meetingDomain = meetingDomain; + } + + /// + /// 分页 + /// + /// + /// + [HttpGet("page")] + public async Task> GetPage([FromQuery] SearchMeetingDto dto) + { + return await _meetingDomain.GetPage(dto); + } + + /// + /// 获取会议参与人 + /// + /// + /// + [HttpGet("participants")] + public async Task> GetMeetingParticipants(int? meetingId) + { + return await _meetingDomain.GetMeetingParticipants(meetingId); + } + + /// + /// 获取会议附件 + /// + /// + /// + [HttpGet("accessory")] + public async Task GetMeetingAccessory(int? meetingId) + { + return await _meetingDomain.GetMeetingAccessory(meetingId); + } + + /// + /// 创建或修改会议 + /// + /// + /// + [HttpPost("CreateOrEdit")] + public async Task CreateOrEditMeeting(CreateOrEditMeetingDto dto) + { + await _meetingDomain.CreateOrEditMeeting(dto, (int)Eid); + } + } +} + diff --git a/code/Zxd.Core.WebApi/Controllers/OrderController.cs b/code/Zxd.Core.WebApi/Controllers/OrderController.cs new file mode 100644 index 0000000..3f8c010 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/OrderController.cs @@ -0,0 +1,99 @@ +using Zxd.Core.Domain.Dto.Zxd.Order; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 订单管理 + /// + [ApiSignatureFilterForbid] + public class OrderController : BaseController + { + private readonly IOrderDomain _orderDomain; + + /// + /// 达量通知 + /// + /// + public OrderController(IOrderDomain orderDomain) + { + _orderDomain = orderDomain; + } + + /// + /// 支付列表 + /// + /// + /// + [HttpGet("bind/page")] + public async Task> GetBindListPageAsync([FromQuery] SearchBindListDto dto) + { + return await _orderDomain.GetBindListPageAsync(dto); + } + + /// + /// 支付明细 + /// + /// + /// + [HttpGet("bind/detail")] + public async Task GetBindDetailAsync([FromQuery] SearchBindListDto dto) + { + return await _orderDomain.GetBindDetailAsync(dto.Id); + } + + /// + /// 获取绑定用户列表 + /// + /// + /// + [HttpGet("bind/userselect")] + public async Task> GetUserSelectAsync([FromQuery] SearchBindListDto dto) + { + return await _orderDomain.GetUserSelectAsync(dto.UnionId); + } + + /// + /// 获取用户 + /// + /// + /// + [HttpGet("bind/useritem")] + public async Task GetUserItemAsync([FromQuery] SearchBindListDto dto) + { + return await _orderDomain.GetUserItemAsync(dto.ResId); + } + + /// + /// 修改绑定 + /// + /// + /// + [HttpGet("bind/edit")] + public async Task EditBindAsync([FromQuery] SearchBindListDto dto) + { + return await _orderDomain.EditBindAsync(dto); + } + + /// + /// 订单状态修改插入日志 重算过期时间 + /// + /// + /// + [HttpPost("addOrderLog")] + public async Task OrderChange([FromBody] OrderChangeDto dto) + { + return await _orderDomain.OrderChange(dto); + } + + /// + /// 导入预览赠送产品 + /// + /// + /// + [HttpPost("ImportHandGiftPreview")] + public async Task> ImportHandGiftPreview([FromBody] List dto) + { + return await _orderDomain.ImportHandGiftPreview(dto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/ProductController.cs b/code/Zxd.Core.WebApi/Controllers/ProductController.cs new file mode 100644 index 0000000..9357d97 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/ProductController.cs @@ -0,0 +1,246 @@ +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 基础产品/组合产品 + /// + [ApiSignatureFilterForbid] + public class ProductController : BaseSsoController + { + private readonly IProdcutDomain _prodcutDomain; + private readonly IServiceProvider _serviceProvider; + + public ProductController(IProdcutDomain prodcutDomain, + IServiceProvider serviceProvider) + : base(serviceProvider) + { + _prodcutDomain = prodcutDomain; + _serviceProvider = serviceProvider; + } + + /// + /// 基础产品列表 + /// + /// + /// + [HttpGet("page")] + public async Task> ProductPage([FromQuery] SearchProductDto dto) + { + return await _prodcutDomain.ProductPage(dto); + } + + /// + /// 基础产品编辑 + /// + /// + /// + [HttpGet("detail")] + public async Task ProductEdit([FromQuery] ChangeProductStatusDto dto) + { + return await _prodcutDomain.ProductEdit(dto); + } + + /// + /// 组合产品列表 + /// + /// + /// + [HttpGet("package/page")] + public async Task> ProductPackagePage([FromQuery] SearchProductDto dto) + { + return await _prodcutDomain.ProductPackagePage(dto); + } + + /// + /// 获取分组下拉 + /// + /// + [HttpGet("Select/Group")] + public async Task> GetProductGroupSelect() + { + return await _prodcutDomain.GetProductGroupSelect(); + } + + /// + /// 获取权限下拉 + /// + /// + [HttpGet("Select/Module")] + public async Task> GetModuleSelect() + { + return await _prodcutDomain.GetModuleSelect(); + } + + /// + /// 获取投顾老师下拉 + /// + /// + [HttpGet("Select/Teacher")] + public async Task> GetProductTeacherSelect() + { + return await _prodcutDomain.GetProductTeacherSelect(); + } + + /// + /// 获取基准产品分类下拉 + /// + /// + [HttpGet("Select/StandardType")] + public async Task> GetStandardTypeSelect() + { + return await _prodcutDomain.GetStandardTypeSelect(); + } + + /// + /// 下线产品 + /// + /// 产品编码 + /// + [HttpPost("Inactive")] + public async Task InactiveProduct([FromBody] ChangeProductStatusDto dto) + { + await _prodcutDomain.InactiveProduct(dto.ProductCode); + } + + /// + /// 上线产品 + /// + /// + /// + [HttpPost("Active")] + public async Task ActiveProduct([FromBody] ChangeProductStatusDto dto) + { + await _prodcutDomain.ActiveProduct(dto.ProductCode); + } + + /// + /// 创建基础产品 + /// + /// + /// + [HttpPost("Create")] + public async Task CreateProduct([FromBody] CreateProductDto dto) + { + await _prodcutDomain.CreateProduct(dto); + } + + /// + /// 导入预览基础产品 + /// + /// + /// + [HttpPost("ImportPreview")] + public async Task> ImportPreview([FromBody] List dto) + { + return await _prodcutDomain.ImportPreview(dto); + } + + /// + /// 导入预览基础产品 + /// + /// + /// + [HttpPost("ImportProduct")] + public async Task ImportProduct([FromBody] List dto) + { + await _prodcutDomain.ImportProduct(dto); + } + + /// + /// 导入预览组合产品 + /// + /// + /// + [HttpPost("Package/ImportPreview")] + public async Task> ImportCombinationProductPreview([FromBody] List dto) + { + return await _prodcutDomain.ImportCombinationProductPreview(dto); + } + + /// + /// 导入组合产品 + /// + /// + /// + [HttpPost("Package/Import")] + public async Task ImportCombinationProduct([FromBody] List dto) + { + await _prodcutDomain.ImportCombinationProduct(dto); + } + + /// + /// 创建基础产品 + /// + /// + /// + [HttpPost("DownProduct")] + public async Task DownProduct([FromBody] ChangeProductStatusDto dto) + { + await _prodcutDomain.DownProduct(dto.ProductCode); + } + + /// + /// 下线组合产品 + /// + /// + /// + [HttpPost("Package/Inactive")] + public async Task InactiveProductPackage([FromBody] ChangeProductStatusDto dto) + { + await _prodcutDomain.InactiveProductPackage(dto.ProductCode); + } + + /// + /// 上线组合产品 + /// + /// + /// + [HttpPost("Package/Active")] + public async Task ActiveProductPackage([FromBody] ChangeProductStatusDto dto) + { + await _prodcutDomain.ActiveProductPackage(dto.ProductCode); + } + + /// + /// 下架组合产品 + /// + /// + /// + [HttpPost("Package/Down")] + public async Task DownProductPackage([FromBody] ChangeProductStatusDto dto) + { + await _prodcutDomain.DownProductPackage(dto.ProductCode); + } + + /// + /// 编辑组合产品 + /// + /// + /// + [HttpGet("Package/Detail")] + public async Task EditProductPackage([FromQuery] ChangeProductStatusDto dto) + { + return await _prodcutDomain.EditProductPackage(dto); + } + + /// + /// 创建组合产品 + /// + /// + /// + [HttpPost("Package/Create")] + public async Task CreateProductPackage([FromBody] CreateProductPackageDto dto) + { + await _prodcutDomain.CreateProductPackage(dto); + } + /// + /// 一键创建组合产品 + /// + /// + /// + [HttpPost("Package/SuperCreate")] + public async Task SuperCreatePackage([FromBody] CreateSuperProductPackageDto dto) + { + await _prodcutDomain.CreateSuperProductPackage(dto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/QwWebSideController.cs b/code/Zxd.Core.WebApi/Controllers/QwWebSideController.cs new file mode 100644 index 0000000..c6de92c --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/QwWebSideController.cs @@ -0,0 +1,46 @@ +using Zxd.Core.Domain.Dto.Zxd.QwWeiSide; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 企微侧边栏 接口 + /// + [ApiSignatureFilterForbid] + public class QwWebSideController : BaseController + { + private readonly IOrderDomain _orderDomain; + private readonly IProdcutDomain _prodcutDomain; + + /// + /// 企微侧边栏 + /// + /// + public QwWebSideController(IOrderDomain orderDomain, IProdcutDomain prodcutDomain) + { + _orderDomain = orderDomain; + _prodcutDomain = prodcutDomain; + } + + /// + /// 订单列表 + /// + /// + /// + [HttpGet("GetOrderListByEid")] + public async Task> GetOrderListByEid([FromQuery] SearchSideOrderDto dto) + { + return await _orderDomain.GetOrderListByEid(dto); + } + + /// + /// 获取三要素合同地址 + /// + /// + /// + [HttpGet("GetContractByOrder")] + public async Task GetContractByOrder([FromQuery] decimal orderId) + { + return await _prodcutDomain.GetContractByFreeOrderId(orderId); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/StandardProductController.cs b/code/Zxd.Core.WebApi/Controllers/StandardProductController.cs new file mode 100644 index 0000000..44b74ce --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/StandardProductController.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Zxd.Core.Domain.Impl; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 基准产品 + /// + [ApiSignatureFilterForbid] + public class StandardProductController : BaseSsoController + { + private readonly IStandardProductDomain _standardProductDomain; + private readonly IServiceProvider _serviceProvider; + + public StandardProductController(IStandardProductDomain standardProductDomain, + IServiceProvider serviceProvider) + : base(serviceProvider) + { + _standardProductDomain = standardProductDomain; + _serviceProvider = serviceProvider; + } + + /// + /// 获取基础产品资料 + /// + /// 产品编号 + /// + [HttpGet("base")] + public async Task GetBaseProduct(string code) + { + return await _standardProductDomain.GetBaseProduct(code); + } + + /// + /// 获取结算方式下拉 + /// + /// + [HttpGet("Select/StandardWay")] + public async Task> GetStandardWaySelect() + { + return await _standardProductDomain.GetStandardWaySelect(); + } + + /// + /// 获取产品权限下拉 + /// + /// + [HttpGet("Select")] + public async Task> GetProductSelect() + { + return await _standardProductDomain.GetProductSelect(); + } + + /// + /// 基准产品分页 + /// + /// + /// + [HttpGet("page")] + public async Task> StandardProductPage([FromQuery] SearchStandardProductDto dto) + { + return await _standardProductDomain.StandardProductPage(dto); + } + + /// + /// 创建基准产品 + /// + /// + /// + [HttpPost("Create")] + public async Task CreateStandardProduct([FromBody] CreateStandardProductDto dto) + { + await _standardProductDomain.CreateStandardProduct(dto); + } + } +} + diff --git a/code/Zxd.Core.WebApi/Controllers/StatisticsController.cs b/code/Zxd.Core.WebApi/Controllers/StatisticsController.cs new file mode 100644 index 0000000..88d8018 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/StatisticsController.cs @@ -0,0 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using Zxd.Core.Domain.Dto.Dncmsbase; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class StatisticsController : BaseController + { + private readonly IStatisticsDomain _statisticsDomain; + public StatisticsController(IStatisticsDomain statisticsDomain) + { + _statisticsDomain = statisticsDomain; + } + + [HttpGet("MonthAttention")] + public async Task GetMonthAttentionData([Required] string year, [Required] string month) + { + return await _statisticsDomain.GetMonthAttentionData(year, month); + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/TodoItemController.cs b/code/Zxd.Core.WebApi/Controllers/TodoItemController.cs new file mode 100644 index 0000000..f4ac274 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/TodoItemController.cs @@ -0,0 +1,58 @@ +using Zxd.Core.Domain.Dto.TodoItem; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 待办事项管理 + /// + [ApiSignatureFilterForbid] + public class TodoItemController : BaseController + { + private readonly ITodoItemDomain _todoItemDomain; + + public TodoItemController(ITodoItemDomain todoItemDomain) + { + _todoItemDomain = todoItemDomain; + } + + /// + /// 获取待办事项列表 + /// + /// + [HttpGet("GetList")] + public async Task> GetListAsync([FromQuery] GetListRequest request) + { + return await _todoItemDomain.GetListNewAsync(request); + } + + /// + /// 获取事件分类下拉选项 + /// + /// + [HttpGet("GetEventTypeSelect")] + public async Task> GetEventTypeSelectAsync([FromQuery] GetEventTypeSelectRequest request) + { + return await _todoItemDomain.GetEventTypeSelectAsync(request); + } + + /// + /// 修改已读 + /// + /// + [HttpGet("EditRead")] + public async Task EditReadAsync([FromQuery] EditReadRequest request) + { + return await _todoItemDomain.EditReadAsync(request); + } + + /// + /// 重要线索消息通知 + /// + /// + [HttpGet("Notice")] + public async Task NoticeAsync() + { + await _todoItemDomain.NoticeAsync(); + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/UserInfoController.cs b/code/Zxd.Core.WebApi/Controllers/UserInfoController.cs new file mode 100644 index 0000000..b08d249 --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/UserInfoController.cs @@ -0,0 +1,40 @@ +using Zxd.Core.Domain.Dto.Dncmsbase; + +namespace Zxd.Core.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class UserInfoController : BaseController + { + private readonly IUserInfoDomain _userInfoDomain; + + public UserInfoController(IUserInfoDomain userInfoDomain) + { + _userInfoDomain = userInfoDomain; + } + + /// + /// 根据条件获取用户信息 + /// + /// + /// + /// + /// + /// + /// + [HttpGet("list")] + public async Task> GetUserInfos(int? cid, string? appid, string? appuserid, string? resid, string? unionid) + => await _userInfoDomain.GetUserInfos(cid, appid, appuserid, resid, unionid); + + /// + /// 获取业务线Id + /// + /// + /// + [HttpGet] + [Route("GetLineId")] + public async Task> GetLineIdAsync(string userids) + { + return await _userInfoDomain.GetLineIdAsync(userids); + } + } +} diff --git a/code/Zxd.Core.WebApi/Controllers/WeWorkController.cs b/code/Zxd.Core.WebApi/Controllers/WeWorkController.cs new file mode 100644 index 0000000..a02c6af --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/WeWorkController.cs @@ -0,0 +1,40 @@ +using Zxd.Core.Domain; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 企业微信管理 + /// + [ApiSignatureFilterForbid] + public class WeWorkController : BaseController + { + /// + /// 同步绑定 + /// + /// + /// + [HttpPost("SyncBinding")] + [ApiResultFilterForbid] + public async Task> SyncBinding([FromBody] WeworkWorkerDto dto) + { + var rsp = new RetResult(null); + rsp.Ret = 999; + rsp.Message = "系统繁忙,请稍后再试"; + try + { + _ = Task.Run(() => + { + _ = new WeworkUserDomain().SyncBinding(dto); + }); + rsp.Ret = 0; + rsp.Message = "操作成功"; + rsp.Data = "操作成功"; + } + catch (Exception ex) + { + Serilog.Log.Error(ex, "SyncBinding"); + } + return rsp; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Controllers/WeWorkResourceController.cs b/code/Zxd.Core.WebApi/Controllers/WeWorkResourceController.cs new file mode 100644 index 0000000..502781a --- /dev/null +++ b/code/Zxd.Core.WebApi/Controllers/WeWorkResourceController.cs @@ -0,0 +1,79 @@ +using Zxd.Core.Domain; +using Zxd.Core.Domain.Dto.Resource; +using Zxd.Core.Domain.Dto.WxResource; +using Zxd.Entity.Dncms; + +namespace Zxd.Core.WebApi.Controllers +{ + /// + /// 企业微信管理 + /// + [ApiSignatureFilterForbid] + public class WeWorkResourceController : BaseController + { + private readonly IWxResourceDomain _wxResourceDomain; + + public WeWorkResourceController(IWxResourceDomain wxResourceDomain) + { + _wxResourceDomain = wxResourceDomain; + } + + /// + /// 获取分群列表 + /// + /// + [HttpGet("UserGroupList")] + public async Task> GetUserGroupList([FromQuery] UserGroupQueryDto dto) + { + return await _wxResourceDomain.GetUserGroupList(dto); + } + + /// + /// 获取分群列表 + /// + /// + [HttpGet("KFResourceCount")] + public async Task> GetKFResourceCount([FromQuery] ResourceCountQueryDto dto) + { + return await _wxResourceDomain.GetKfSourceCount(dto); + } + + /// + /// 获取分群列表 + /// + /// + [HttpGet("KFResourceCountByCrm")] + public async Task KFResourceCountByCrm([FromQuery] ResourceCountQueryDto dto) + { + return await _wxResourceDomain.GetKfSourceCountByCrm(dto); + } + + /// + /// 获取分群列表 + /// + /// + [HttpPost("SubmitSourceTask")] + public async Task SubmitSourceTask([FromBody] ResourceConfigCreateDto dto) + { + await _wxResourceDomain.SubmitSourceTask(dto); + } + + [HttpGet("page")] + public async Task> GetSourceTaskPage([FromQuery] SearchSourceTaskDto dto) + { + return await _wxResourceDomain.GetSourceTaskPage(dto); + } + + [HttpGet("FromUser")] + public async Task> GetFromUserPage([FromQuery] SearchFromDto dto) + { + return await _wxResourceDomain.GetFromUserPage(dto); + } + + [HttpGet("ToUser")] + public async Task GetToUserPage([FromQuery] SearchToDto dto) + { + return await _wxResourceDomain.GetToUserPage(dto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Dockerfile b/code/Zxd.Core.WebApi/Dockerfile new file mode 100644 index 0000000..be46788 --- /dev/null +++ b/code/Zxd.Core.WebApi/Dockerfile @@ -0,0 +1,25 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["Zxd.Core.WebApi/Zxd.Core.WebApi.csproj", "Zxd.Core.WebApi/"] +COPY ["Zxd.Core.Domain/Zxd.Core.Domain.csproj", "Zxd.Core.Domain/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +RUN dotnet restore "Zxd.Core.WebApi/Zxd.Core.WebApi.csproj" +COPY . . +WORKDIR "/src/Zxd.Core.WebApi" +RUN dotnet build "Zxd.Core.WebApi.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Zxd.Core.WebApi.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Zxd.Core.WebApi.dll"] \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Program.cs b/code/Zxd.Core.WebApi/Program.cs new file mode 100644 index 0000000..7b83874 --- /dev/null +++ b/code/Zxd.Core.WebApi/Program.cs @@ -0,0 +1,133 @@ +using Exceptionless; + +using MySqlConnector; +using System.Data; + +try +{ + // Add services to the container. + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true) + .Build(); + + var builder = WebApplication.CreateBuilder(args); + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .WriteTo.Exceptionless(builder.Configuration.GetValue("Exceptionless:ApiKey"), builder.Configuration.GetValue("Exceptionless:ServerUrl"), new string[] { "zxd-core-webapi" }) + .CreateLogger(); + Log.Logger = logger; + builder.Services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(logger); + }); + + Log.Information("Starting ZXD Service"); + builder.Services.AddControllers() + .AddApiResult() + .AddApiSignature() + .AddJsonOptions(options => + { + options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; + options.JsonSerializerOptions.Converters.Add(new JsonOptionsExtensions()); + }); + builder.Services.AddDGHttpClient(); + builder.Services.AddHostedService(); + builder.Services.AddKafka(builder.Configuration); + //builder.Services.AddHostedService(); + builder.Services.AddHostedService(); + builder.Services.AddHostedService(); + var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; + builder.Services.AddCors(option => + { + option.AddPolicy(MyAllowSpecificOrigins, + policy => + { + policy.SetIsOriginAllowed(_ => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); + + }); + builder.Services.AddExceptionless(builder.Configuration); + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo + { + Version = "v1", + Title = "ZXD CORE API", + Description = "ZXD CORE API" + }); + var xmlFilename = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"; + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Zxd.Core.Domain.xml")); + }); + builder.Services.AddRedis(builder.Configuration); + builder.Services.AddOptions() + .Configure(e => builder.Configuration.GetSection("SystemConfig").Bind(e)) + .Configure(e => builder.Configuration.GetSection("ClientKey").Bind(e)) + .Configure(e => builder.Configuration.GetSection("PayCallbackConfig").Bind(e)); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("zxdcrm"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("dncmsbase"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("usercenter"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("usercenter"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("dncms"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("dncms"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("crm"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("crm"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("hgaction"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("hgaction"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("crmcloud"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("hgaction"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("companyBaseConf"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("companyBaseConf"))); + }); + builder.Services.AddScoped(options => new MySqlConnection(builder.Configuration.GetConnectionString("usercenter"))); + builder.Services.AddAutoIoc(typeof(IScopedDependency), LifeCycle.Scoped) + .AddAutoIoc(typeof(ISingletonDependency), LifeCycle.Singleton) + .AddAutoIoc(typeof(ITransientDependency), LifeCycle.Transient) + .AddMapper(); + var app = builder.Build(); + app.UseCors(MyAllowSpecificOrigins); + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment() || Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "PreProduction") + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseAuthorization(); + app.UseExceptionless(); + app.MapControllers(); + //app.UseHttpLogging(); + app.Run(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Properties/launchSettings.json b/code/Zxd.Core.WebApi/Properties/launchSettings.json new file mode 100644 index 0000000..622132e --- /dev/null +++ b/code/Zxd.Core.WebApi/Properties/launchSettings.json @@ -0,0 +1,39 @@ +{ + "profiles": { + "Zxd.Core.WebApi": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5244" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true, + "useSSL": true, + "httpPort": 5260, + "sslPort": 5259 + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:53498", + "sslPort": 0 + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/ReadMe.md b/code/Zxd.Core.WebApi/ReadMe.md new file mode 100644 index 0000000..e70e66d --- /dev/null +++ b/code/Zxd.Core.WebApi/ReadMe.md @@ -0,0 +1,11 @@ +# 主要内部使用的中心点接口 +# 连接数据库: zxdcrm,dncmsbase,dncms,usercenter,db_crm,db_company_base_conf +# 测试地址:http://192.168.11.81:8089/ +# 正式地址:http://120.77.165.155:8089 +# 循环任务: sso员工系统数据同步 +# 达量通知相关执行任务 +# 相关api: 获取事业部接口 +# 培训档案 +# 达量通知 +# 支付回调 +# 基准产品和标准产品 \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Serilog.Production.json b/code/Zxd.Core.WebApi/Serilog.Production.json new file mode 100644 index 0000000..c97597b --- /dev/null +++ b/code/Zxd.Core.WebApi/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.AspNetCore" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/Zxd.Core.WebApi/Serilog.json b/code/Zxd.Core.WebApi/Serilog.json new file mode 100644 index 0000000..b9a91e5 --- /dev/null +++ b/code/Zxd.Core.WebApi/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.AspNetCore" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/Zxd.Core.WebApi/Workers/EarlyWarningWorker.cs b/code/Zxd.Core.WebApi/Workers/EarlyWarningWorker.cs new file mode 100644 index 0000000..3fcb7b5 --- /dev/null +++ b/code/Zxd.Core.WebApi/Workers/EarlyWarningWorker.cs @@ -0,0 +1,39 @@ +namespace Zxd.Core.WebApi.Workers +{ + /// + /// 达量通知任务 + /// + public class EarlyWarningWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + /// + /// 达量通知任务 + /// + /// + public EarlyWarningWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var prodcutDomain = scope.ServiceProvider.GetRequiredService(); + var cacheDomain = scope.ServiceProvider.GetRequiredService(); + var delay = await cacheDomain.GetEarlyWarningValue(); + try + { + await prodcutDomain.EarlyWarningSync(); + } + catch (Exception ex) + { + Log.Error($"EarlyWarningWorker运行出错{ex.Message}"); + } + await Task.Delay(delay * 60 * 1000, stoppingToken); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Workers/ProductSyncWorker.cs b/code/Zxd.Core.WebApi/Workers/ProductSyncWorker.cs new file mode 100644 index 0000000..43da55b --- /dev/null +++ b/code/Zxd.Core.WebApi/Workers/ProductSyncWorker.cs @@ -0,0 +1,34 @@ +using System; +using Zxd.Domain.Impl; + +namespace Zxd.WebApi.Workers +{ + public class ProductSyncWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + public ProductSyncWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + try + { + using var scope = _serviceProvider.CreateAsyncScope(); + var prodcutDomain = scope.ServiceProvider.GetRequiredService(); + await prodcutDomain.SyncProduct(); + await prodcutDomain.SyncProductPackage(); + } + catch (Exception ex) + { + Log.Error($"ProductSyncWorker运行出错{ex.Message}"); + } + await Task.Delay(10 * 60 * 1000, stoppingToken); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Workers/SsoWorker.cs b/code/Zxd.Core.WebApi/Workers/SsoWorker.cs new file mode 100644 index 0000000..51b6f65 --- /dev/null +++ b/code/Zxd.Core.WebApi/Workers/SsoWorker.cs @@ -0,0 +1,30 @@ +namespace Zxd.WebApi.Workers +{ + public class SsoWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + public SsoWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + using var scope = _serviceProvider.CreateAsyncScope(); + var inneruserDomain = scope.ServiceProvider.GetRequiredService(); + while (!stoppingToken.IsCancellationRequested) + { + await inneruserDomain.SyncSsoOrganization(); + await Task.Delay(60 * 60 * 1000); + } + } + catch (Exception ex) + { + Log.Error(ex, $"{typeof(SsoWorker).Name}任务报错!"); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/Workers/TodoItemWorker.cs b/code/Zxd.Core.WebApi/Workers/TodoItemWorker.cs new file mode 100644 index 0000000..b66041c --- /dev/null +++ b/code/Zxd.Core.WebApi/Workers/TodoItemWorker.cs @@ -0,0 +1,34 @@ +namespace Zxd.Core.WebApi.Workers +{ + /// + /// 重要线索消息通知 + /// + public class TodoItemWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + public TodoItemWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + using var scope = _serviceProvider.CreateAsyncScope(); + var todoItemDomain = scope.ServiceProvider.GetRequiredService(); + + while (!stoppingToken.IsCancellationRequested) + { + await todoItemDomain.NoticeAsync(); + await Task.Delay(60 * 60 * 1000); + } + } + catch (Exception ex) + { + Log.Error(ex, $"{typeof(TodoItemWorker).Name}任务报错!"); + } + } + } +} diff --git a/code/Zxd.Core.WebApi/Zxd.Core.WebApi.csproj b/code/Zxd.Core.WebApi/Zxd.Core.WebApi.csproj new file mode 100644 index 0000000..9c9b72c --- /dev/null +++ b/code/Zxd.Core.WebApi/Zxd.Core.WebApi.csproj @@ -0,0 +1,77 @@ + + + + net6.0 + enable + enable + Linux + True + 575b1a56-a746-45f7-91ce-561873619af8 + + + + 4 + + + + <_ContentIncludedByDefault Remove="appsettings.Production.json" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + true + PreserveNewest + + + PreserveNewest + true + PreserveNewest + + + PreserveNewest + true + PreserveNewest + + + + + diff --git a/code/Zxd.Core.WebApi/appsettings.Disaster.json b/code/Zxd.Core.WebApi/appsettings.Disaster.json new file mode 100644 index 0000000..d260ccc --- /dev/null +++ b/code/Zxd.Core.WebApi/appsettings.Disaster.json @@ -0,0 +1,153 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "Consumers": [ + { + "Host": "172.18.11.77:9092", + "GroupId": "crm", + "Topic": "crm-topic" + }, + { + "Host": "172.18.11.77:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "ConnectionStrings": { + "zxdcrm": "Data Source=rm-10.22.15.61;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=10.22.15.68;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "crm": "Data Source=rm-10.22.15.61;Port=3306;Initial Catalog=db_crm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "companyBaseConf": "Data Source=10.22.15.68;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "afrcHIMprcRywoE64jGGaZzkkpSdeI3csZniS38Q" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Apps": [ + { + "Deptids": [ 27, 32, 33 ], + "AppName": "投顾坐席", + "Appid": "crm_tg_dng8", + "AppSecret": "17D4xLHTFQbRrMchTr4Dd5RcUyn4WbJda+MarKTlw78=", + "CrmUrl": "http://192.168.11.36:808/" + }, + { + "Deptids": [ 16, 29 ], + "AppName": "东一东二坐席", + "Appid": "crm_d1d2_dnzz", + "AppSecret": "tXxYuzU3H9Wki0Qh5HhxVnBKg9kbqIYGyxGqgtbPljc=", + "CrmUrl": "http://192.168.11.200:808/" + }, + { + "Deptids": [ 23 ], + "AppName": "东三坐席", + "Appid": "crm_d3_dnyy", + "AppSecret": "3gy2vCskdrpPziFykGKNmeTkyKGCitgGPO7q5qIvmfs=", + "CrmUrl": "http://192.168.11.216:808/" + }, + { + "Deptids": [ 30, 31 ], + "AppName": "内容二、三坐席", + "Appid": "crm_tg_dnbb", + "AppSecret": "N0e44dEIA0hQwOOATZu/bij55N0fD0CNAA9IsisCZeM=", + "CrmUrl": "http://192.168.11.226:808/" + }, + { + "Deptids": [ 19, 8 ], + "AppName": "首华", + "Appid": "crm_df_yypt", + "AppSecret": "TYd8USnG3yKFuW/hFigwxfMpzygMEmfZYNewXdJVaU4=", + "CrmUrl": "http://192.168.200.235:808/" + } + ], + "Appid": "qt_core", + "AppSecret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=", + "SsoUrl": "http://10.22.15.22:15814", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "WeworkSendUrl": "http://post.hc.dn8188.com/Wework/sendmsg.html", + "SalesLeadUrl": "http://10.22.15.22:16549/dev.html", + "CrmBaseUrl": "http://10.22.15.30:15517", + "GroupUrl": "http://idss.soft.dn8188.com", + "UserGroupList": "/usercollection/group/list", + "BdMarkting": "http://bd-markting.soft.dn8188.com", + "KfUserCount": "/user/group", + "ActiveProduct": "/product/modifyproduct", + "ActivePackage": "/product/modifypackage", + "AddStandardProduct": "/product/addstandardproduct", + "AddStandardPackage": "/product/addstandardpackage", + "AddVirtualProduct": "/product/addvirtualproduct", + "AddVirtualPackage": "/product/addvirtualpackage", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CmsUrl": "http://192.168.111.143:19855/", + "CrmCoreUrl": "http://api.crm.tcfortune.com:8282/", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://qm.dn8188.com:8099/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=" + }, + "Redis": [ + { + "Name": "ZXD", + "HostName": "10.22.15.65", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + }, + { + "Name": "UserCenter", + "HostName": "10.22.15.65", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } + ], + "PayCallbackConfig": { + "AppId": "dg", + "Secret": "21db98fb79bedb542b979866e2720744", + "PushUrl": "http://qm.dn8188.com:8096/OrderService.svc/OrderDeposit/Add" + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/appsettings.Production.json b/code/Zxd.Core.WebApi/appsettings.Production.json new file mode 100644 index 0000000..b7d7d8d --- /dev/null +++ b/code/Zxd.Core.WebApi/appsettings.Production.json @@ -0,0 +1,157 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "Consumers": [ + { + "Host": "172.18.11.77:9092", + "GroupId": "crm", + "Topic": "crm-topic" + }, + { + "Host": "172.18.11.77:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None;Allow Zero Datetime=True;Convert Zero Datetime=True;", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "crm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=db_crm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "hgaction": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=hgaction;user id=hguser;password=nH5L$&Hxxco;SslMode=None", + "companyBaseConf": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "crmcloud": "Server=dgbigdata.mysql.rds.aliyuncs.com;Database=crm_cloud;UserId=crm_rd;Password=K#RQ1TYx9my;port=3306;" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "afrcHIMprcRywoE64jGGaZzkkpSdeI3csZniS38Q" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Apps": [ + { + "Deptids": [ 27, 32, 33, 43 ], + "AppName": "投顾坐席", + "Appid": "crm_tg_dng8", + "AppSecret": "17D4xLHTFQbRrMchTr4Dd5RcUyn4WbJda+MarKTlw78=", + "CrmUrl": "http://192.168.11.36:808/" + }, + { + "Deptids": [ 16, 29 ], + "AppName": "东一东二坐席", + "Appid": "crm_d1d2_dnzz", + "AppSecret": "tXxYuzU3H9Wki0Qh5HhxVnBKg9kbqIYGyxGqgtbPljc=", + "CrmUrl": "http://192.168.11.200:808/" + }, + { + "Deptids": [ 23 ], + "AppName": "东三坐席", + "Appid": "crm_d3_dnyy", + "AppSecret": "3gy2vCskdrpPziFykGKNmeTkyKGCitgGPO7q5qIvmfs=", + "CrmUrl": "http://192.168.11.216:808/" + }, + { + "Deptids": [ 30, 31 ], + "AppName": "内容二、三坐席", + "Appid": "crm_tg_dnbb", + "AppSecret": "N0e44dEIA0hQwOOATZu/bij55N0fD0CNAA9IsisCZeM=", + "CrmUrl": "http://192.168.11.226:808/" + }, + { + "Deptids": [ 19, 38, 42, 37 ], + "AppName": "首华", + "Appid": "crm_df_yypt", + "AppSecret": "TYd8USnG3yKFuW/hFigwxfMpzygMEmfZYNewXdJVaU4=", + "CrmUrl": "http://192.168.200.235:808/" + } + ], + "Appid": "qt_core", + "AppSecret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=", + "SsoUrl": "http://conf.soft.dn8188.com", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "WeworkSendUrl": "http://post.hc.dn8188.com/Wework/sendmsg.html", + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "CrmBaseUrl": "http://172.18.10.92:10010", + "GroupUrl": "http://idss.soft.dn8188.com", + "UserGroupList": "/usercollection/group/list", + "BdMarkting": "http://bd-markting.soft.dn8188.com", + "KfUserCount": "/user/group", + "ActiveProduct": "/product/modifyproduct", + "ActivePackage": "/product/modifypackage", + "AddStandardProduct": "/product/addstandardproduct", + "AddStandardPackage": "/product/addstandardpackage", + "AddVirtualProduct": "/product/addvirtualproduct", + "AddVirtualPackage": "/product/addvirtualpackage", + "CRMClientKey": "TDORDERSITE", + "NODEClientKey": "UPWEBSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CmsUrl": "http://192.168.111.143:19855/", + "CrmCoreUrl": "http://api.crm.tcfortune.com:8282/", + "UsercenterUrl": "http://172.18.10.92:10061/", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://qm.dn8188.com:8099/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=" + }, + "Redis": [ + { + "Name": "ZXD", + "HostName": "redis-cngzdnddztrevahsz.redis.ivolces.com", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + }, + { + "Name": "UserCenter", + "HostName": "redis-cngzdnddztrevahsz.redis.ivolces.com", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } + ], + "PayCallbackConfig": { + "AppId": "dg", + "Secret": "21db98fb79bedb542b979866e2720744", + "PushUrl": "http://qm.dn8188.com:8096/OrderService.svc/OrderDeposit/Add" + } +} \ No newline at end of file diff --git a/code/Zxd.Core.WebApi/appsettings.json b/code/Zxd.Core.WebApi/appsettings.json new file mode 100644 index 0000000..721f80f --- /dev/null +++ b/code/Zxd.Core.WebApi/appsettings.json @@ -0,0 +1,142 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "Consumers": [ + { + "Host": "192.168.11.101:9092", + "GroupId": "crm", + "Topic": "crm-topic" + }, + { + "Host": "192.168.11.101:9092", + "GroupId": "crm", + "Topic": "ResPassTime" + } + ], + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "hgaction": "Server=192.168.11.141;Database=hgaction;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "companyBaseConf": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "crmcloud": "Server=192.168.11.141;Database=crm_cloud;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "UWIBUhn0AXArToEwrOd9AbMO435MC4gvj0MQjtu5" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Apps": [ + { + "Deptids": [ 27 ], + "AppName": "投顾坐席", + "Appid": "crm_tg_dng8", + "AppSecret": "kBCjri03z27aOU8a0TQX2CJ6Ox7UZ4SZU/jbTjbObcM=", + "CrmUrl": "http://192.168.11.45:808/" + }, + { + "Deptids": [ 16 ], + "AppName": "东一坐席", + "Appid": "crm_d1_dnzz", + "AppSecret": "QmsBFl/UyQcgdmwvEn0BZ3HunvKeNacfWQdzRDhyBYM=" + }, + { + "Deptids": [ 23 ], + "AppName": "东三坐席", + "Appid": "crm_d3_dnyy", + "AppSecret": "Qtn9PDagR7+5Kp+Ma6yGno5rljM6MqSImwFsT9tod3k=" + } + ], + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "SsoUrl": "http://192.168.11.141:24434", + "SsoTokenUrl": "/v1/api/open/sso/token", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "WeworkSendUrl": "http://post.hc.dn8188.com/Wework/sendmsg.html", + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "CrmBaseUrl": "http://192.168.11.141:10014", + "GroupUrl": "http://idss.soft.dn8188.com", + "UserGroupList": "/usercollection/group/list", + "BdMarkting": "http://bd-markting.soft.dn8188.com", + "KfUserCount": "/user/group", + "AddStandardProduct": "/product/addstandardproduct", + "AddStandardPackage": "/product/addstandardpackage", + "AddVirtualProduct": "/product/addvirtualproduct", + "AddVirtualPackage": "/product/addvirtualpackage", + "ActiveProduct": "/product/modifyproduct", + "ActivePackage": "/product/modifypackage", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CmsUrl": "http://192.168.111.143:19855/", + "CrmCoreUrl": "http://192.168.11.81:8088/", + "TestUrl": "http://192.168.11.81:8088/", + "UsercenterUrl": "http://192.168.11.141:10096/", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://192.168.11.46/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=" + }, + "Redis": [ + { + "Name": "ZXD", + "HostName": "192.168.11.81", + "Port": "6379", + "Password": "Abc@123456", + "Defaultdatabase": "1" + }, + { + "Name": "UserCenter", + "HostName": "192.168.11.103", + "Port": "6379", + "Password": "123", + "Defaultdatabase": "0" + } + ], + "PayCallbackConfig": { + "AppId": "fanfan", + "Secret": "f53bafd8c2b602abca59e4c2854440d8", + "PushUrl": "http://192.168.11.46:8096/OrderService.svc/OrderDeposit/Add" + } +} \ No newline at end of file diff --git a/code/Zxd.Core.sln b/code/Zxd.Core.sln new file mode 100644 index 0000000..25c7f02 --- /dev/null +++ b/code/Zxd.Core.sln @@ -0,0 +1,160 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33627.172 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.WebApi", "Zxd.WebApi\Zxd.WebApi.csproj", "{A29F23B3-FF52-4059-B9EB-CCBD9DDB1CDF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Domain", "Zxd.Domain\Zxd.Domain.csproj", "{EDED1232-1539-442E-8F70-9CD18D3AF69B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.EntityFramework", "Zxd.EntityFramework\Zxd.EntityFramework.csproj", "{CD2D1E70-4D18-47AF-B1D1-9718EE8ED258}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Entity", "Zxd.Entity\Zxd.Entity.csproj", "{C0F1146E-A44A-4F15-8964-C74436F0BDB3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Core.Shared", "Zxd.Core.Shared\Zxd.Core.Shared.csproj", "{A00CD7FD-C3AD-47D0-8BBD-1225C3C08729}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{E608FC47-CF55-46D2-AAE8-64D2CF64CAAE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Core.Test", "..\test\Zxd.Core.Test\Zxd.Core.Test.csproj", "{DC3D31DD-F923-41A6-8EBE-C59CFF77A8C2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Core.Domain", "Zxd.Core.Domain\Zxd.Core.Domain.csproj", "{8D63F1A6-E2D5-4DAC-8DD1-6838D846E931}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Core.WebApi", "Zxd.Core.WebApi\Zxd.Core.WebApi.csproj", "{59BF85D9-E787-401E-873B-1B627DCB4908}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Zxd.Core", "Zxd.Core", "{7AA4839C-DB18-4246-8CDD-6875398EAE0F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{7056EBA1-BC2D-4700-BEEA-EF4A49070268}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Zxd.Web", "Zxd.Web", "{7AB337A1-88AD-4C22-86C0-FE9A8834EB8C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Zxd.Crm", "Zxd.Crm", "{329748DE-D7DA-4D1B-A044-717DA57D69FB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Crm.Domain", "Zxd.Crm.Domain\Zxd.Crm.Domain.csproj", "{3D7E2DB6-8735-4153-8942-C7DD64931F33}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.Crm.WebApi", "Zxd.Crm.WebApi\Zxd.Crm.WebApi.csproj", "{AA69804D-D78C-41DE-B477-49E285FEADA5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Worker", "Worker", "{19629268-FAF2-42CA-A7D4-D5CCE739FF4A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WeworkUserWorker", "WeworkUserWorker\WeworkUserWorker.csproj", "{91BE759D-481B-4246-8DC3-8462E6F26B48}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonWorker", "CommonWorker\CommonWorker.csproj", "{A02E1F91-E4F9-4EE8-B2D2-D19457BDE903}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmployeeDepartmentDetailServices", "EmployeeDepartmentDetailWorker\EmployeeDepartmentDetailServices.csproj", "{C5EC958E-26E6-4AAF-A569-7C76216CA9FD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ResourceFlowWorker", "ResourceFlowWorker\ResourceFlowWorker.csproj", "{C2F6CF99-F96B-48AC-934A-7B59BC7F026D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToDoWorker", "ToDoWorker\ToDoWorker.csproj", "{BB3183D9-38F5-4860-ADE6-735EF9F8EF7F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zxd.SqlSugar", "Zxd.SqlSugar\Zxd.SqlSugar.csproj", "{CF6783BB-EE8A-475D-8268-513713AFAC7B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DGCommon", "DGCommon", "{5E8706D3-CCF5-4654-B3AC-00DF95CED9EE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DG.Kafka", "DG.Kafka\DG.Kafka.csproj", "{FAA4E537-81BF-462E-BE19-3194B7DD7D47}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DG.Kafka.Worker", "DG.Kafka.Worker\DG.Kafka.Worker.csproj", "{1E97050D-CA19-46A7-92A2-7BFA09006971}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A29F23B3-FF52-4059-B9EB-CCBD9DDB1CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A29F23B3-FF52-4059-B9EB-CCBD9DDB1CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A29F23B3-FF52-4059-B9EB-CCBD9DDB1CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A29F23B3-FF52-4059-B9EB-CCBD9DDB1CDF}.Release|Any CPU.Build.0 = Release|Any CPU + {EDED1232-1539-442E-8F70-9CD18D3AF69B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDED1232-1539-442E-8F70-9CD18D3AF69B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDED1232-1539-442E-8F70-9CD18D3AF69B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDED1232-1539-442E-8F70-9CD18D3AF69B}.Release|Any CPU.Build.0 = Release|Any CPU + {CD2D1E70-4D18-47AF-B1D1-9718EE8ED258}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD2D1E70-4D18-47AF-B1D1-9718EE8ED258}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD2D1E70-4D18-47AF-B1D1-9718EE8ED258}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD2D1E70-4D18-47AF-B1D1-9718EE8ED258}.Release|Any CPU.Build.0 = Release|Any CPU + {C0F1146E-A44A-4F15-8964-C74436F0BDB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C0F1146E-A44A-4F15-8964-C74436F0BDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C0F1146E-A44A-4F15-8964-C74436F0BDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C0F1146E-A44A-4F15-8964-C74436F0BDB3}.Release|Any CPU.Build.0 = Release|Any CPU + {A00CD7FD-C3AD-47D0-8BBD-1225C3C08729}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A00CD7FD-C3AD-47D0-8BBD-1225C3C08729}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A00CD7FD-C3AD-47D0-8BBD-1225C3C08729}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A00CD7FD-C3AD-47D0-8BBD-1225C3C08729}.Release|Any CPU.Build.0 = Release|Any CPU + {DC3D31DD-F923-41A6-8EBE-C59CFF77A8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC3D31DD-F923-41A6-8EBE-C59CFF77A8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC3D31DD-F923-41A6-8EBE-C59CFF77A8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC3D31DD-F923-41A6-8EBE-C59CFF77A8C2}.Release|Any CPU.Build.0 = Release|Any CPU + {8D63F1A6-E2D5-4DAC-8DD1-6838D846E931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D63F1A6-E2D5-4DAC-8DD1-6838D846E931}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D63F1A6-E2D5-4DAC-8DD1-6838D846E931}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D63F1A6-E2D5-4DAC-8DD1-6838D846E931}.Release|Any CPU.Build.0 = Release|Any CPU + {59BF85D9-E787-401E-873B-1B627DCB4908}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59BF85D9-E787-401E-873B-1B627DCB4908}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59BF85D9-E787-401E-873B-1B627DCB4908}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59BF85D9-E787-401E-873B-1B627DCB4908}.Release|Any CPU.Build.0 = Release|Any CPU + {3D7E2DB6-8735-4153-8942-C7DD64931F33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D7E2DB6-8735-4153-8942-C7DD64931F33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D7E2DB6-8735-4153-8942-C7DD64931F33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D7E2DB6-8735-4153-8942-C7DD64931F33}.Release|Any CPU.Build.0 = Release|Any CPU + {AA69804D-D78C-41DE-B477-49E285FEADA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA69804D-D78C-41DE-B477-49E285FEADA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA69804D-D78C-41DE-B477-49E285FEADA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA69804D-D78C-41DE-B477-49E285FEADA5}.Release|Any CPU.Build.0 = Release|Any CPU + {91BE759D-481B-4246-8DC3-8462E6F26B48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91BE759D-481B-4246-8DC3-8462E6F26B48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91BE759D-481B-4246-8DC3-8462E6F26B48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91BE759D-481B-4246-8DC3-8462E6F26B48}.Release|Any CPU.Build.0 = Release|Any CPU + {A02E1F91-E4F9-4EE8-B2D2-D19457BDE903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A02E1F91-E4F9-4EE8-B2D2-D19457BDE903}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A02E1F91-E4F9-4EE8-B2D2-D19457BDE903}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A02E1F91-E4F9-4EE8-B2D2-D19457BDE903}.Release|Any CPU.Build.0 = Release|Any CPU + {C5EC958E-26E6-4AAF-A569-7C76216CA9FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5EC958E-26E6-4AAF-A569-7C76216CA9FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5EC958E-26E6-4AAF-A569-7C76216CA9FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5EC958E-26E6-4AAF-A569-7C76216CA9FD}.Release|Any CPU.Build.0 = Release|Any CPU + {C2F6CF99-F96B-48AC-934A-7B59BC7F026D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2F6CF99-F96B-48AC-934A-7B59BC7F026D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2F6CF99-F96B-48AC-934A-7B59BC7F026D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2F6CF99-F96B-48AC-934A-7B59BC7F026D}.Release|Any CPU.Build.0 = Release|Any CPU + {BB3183D9-38F5-4860-ADE6-735EF9F8EF7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB3183D9-38F5-4860-ADE6-735EF9F8EF7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB3183D9-38F5-4860-ADE6-735EF9F8EF7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB3183D9-38F5-4860-ADE6-735EF9F8EF7F}.Release|Any CPU.Build.0 = Release|Any CPU + {CF6783BB-EE8A-475D-8268-513713AFAC7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF6783BB-EE8A-475D-8268-513713AFAC7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF6783BB-EE8A-475D-8268-513713AFAC7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF6783BB-EE8A-475D-8268-513713AFAC7B}.Release|Any CPU.Build.0 = Release|Any CPU + {FAA4E537-81BF-462E-BE19-3194B7DD7D47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FAA4E537-81BF-462E-BE19-3194B7DD7D47}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FAA4E537-81BF-462E-BE19-3194B7DD7D47}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FAA4E537-81BF-462E-BE19-3194B7DD7D47}.Release|Any CPU.Build.0 = Release|Any CPU + {1E97050D-CA19-46A7-92A2-7BFA09006971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E97050D-CA19-46A7-92A2-7BFA09006971}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E97050D-CA19-46A7-92A2-7BFA09006971}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E97050D-CA19-46A7-92A2-7BFA09006971}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A29F23B3-FF52-4059-B9EB-CCBD9DDB1CDF} = {7AB337A1-88AD-4C22-86C0-FE9A8834EB8C} + {EDED1232-1539-442E-8F70-9CD18D3AF69B} = {7AB337A1-88AD-4C22-86C0-FE9A8834EB8C} + {CD2D1E70-4D18-47AF-B1D1-9718EE8ED258} = {7056EBA1-BC2D-4700-BEEA-EF4A49070268} + {C0F1146E-A44A-4F15-8964-C74436F0BDB3} = {7056EBA1-BC2D-4700-BEEA-EF4A49070268} + {A00CD7FD-C3AD-47D0-8BBD-1225C3C08729} = {7056EBA1-BC2D-4700-BEEA-EF4A49070268} + {DC3D31DD-F923-41A6-8EBE-C59CFF77A8C2} = {E608FC47-CF55-46D2-AAE8-64D2CF64CAAE} + {8D63F1A6-E2D5-4DAC-8DD1-6838D846E931} = {7AA4839C-DB18-4246-8CDD-6875398EAE0F} + {59BF85D9-E787-401E-873B-1B627DCB4908} = {7AA4839C-DB18-4246-8CDD-6875398EAE0F} + {3D7E2DB6-8735-4153-8942-C7DD64931F33} = {329748DE-D7DA-4D1B-A044-717DA57D69FB} + {AA69804D-D78C-41DE-B477-49E285FEADA5} = {329748DE-D7DA-4D1B-A044-717DA57D69FB} + {91BE759D-481B-4246-8DC3-8462E6F26B48} = {19629268-FAF2-42CA-A7D4-D5CCE739FF4A} + {A02E1F91-E4F9-4EE8-B2D2-D19457BDE903} = {19629268-FAF2-42CA-A7D4-D5CCE739FF4A} + {C5EC958E-26E6-4AAF-A569-7C76216CA9FD} = {19629268-FAF2-42CA-A7D4-D5CCE739FF4A} + {C2F6CF99-F96B-48AC-934A-7B59BC7F026D} = {19629268-FAF2-42CA-A7D4-D5CCE739FF4A} + {BB3183D9-38F5-4860-ADE6-735EF9F8EF7F} = {19629268-FAF2-42CA-A7D4-D5CCE739FF4A} + {FAA4E537-81BF-462E-BE19-3194B7DD7D47} = {5E8706D3-CCF5-4654-B3AC-00DF95CED9EE} + {1E97050D-CA19-46A7-92A2-7BFA09006971} = {5E8706D3-CCF5-4654-B3AC-00DF95CED9EE} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6C94942A-1B07-4CF7-BB70-E63A968E909D} + EndGlobalSection +EndGlobal diff --git a/code/Zxd.Crm.Domain/AssignRuleDomain.cs b/code/Zxd.Crm.Domain/AssignRuleDomain.cs new file mode 100644 index 0000000..95a5a24 --- /dev/null +++ b/code/Zxd.Crm.Domain/AssignRuleDomain.cs @@ -0,0 +1,291 @@ +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto.AssignRule; +using Zxd.Crm.Domain.Impl.AssignRule; +using Zxd.Entity.Dncms; + +namespace Zxd.Crm.Domain +{ + /// + /// 客服分配规则 + /// + public class AssignRuleDomain : IAssignRuleDomain + { + private readonly IBaseRepository _cmsRepository; + private readonly IMapper _mapper; + + public AssignRuleDomain(IBaseRepository cmsRepository, + IMapper mapper) + { + _cmsRepository = cmsRepository; + _mapper = mapper; + } + + /// + /// 列表 + /// + /// + /// + public async Task> GetList(AssignRuleQueryDto dto) + { + var filter = new List(); + var ps = new List(); + var tableFilter = ""; + if (!string.IsNullOrWhiteSpace(dto.allsgids)) + { + filter.Add($" t1.salegroupid in( {dto.allsgids} )"); + } + if (dto.UserId.HasValue) + { + filter.Add($" t1.inneruserid = @userid "); + ps.Add(new MySqlParameter("userid", dto.UserId)); + } + if (dto.sgid.HasValue) + { + filter.Add($" t1.salegroupid = @sgid"); + ps.Add(new MySqlParameter("sgid", dto.sgid)); + } + if (!string.IsNullOrWhiteSpace(dto.name)) + { + filter.Add($" (t2.employee_name like @cname or t1.eid like @cname)"); + ps.Add(new MySqlParameter("cname", $"%{dto.name}%")); + } + if (dto.departmentId.HasValue) + { + tableFilter = $"{Environment.NewLine}JOIN employee_department_detail t3 on t3.eid = t1.eid"; + filter.Add($"t3.department_id = @deptid"); + filter.Add($"t3.is_deleted = 0"); + ps.Add(new MySqlParameter("deptid", dto.departmentId)); + } + if (dto.Level.HasValue) + { + filter.Add($" t1.levelno = @level"); + ps.Add(new MySqlParameter("level", dto.Level)); + } + if (dto.isvalid.HasValue) + { + filter.Add($" t1.isvalid = @isvalid"); + ps.Add(new MySqlParameter("isvalid", dto.isvalid)); + } + var weworkUserJoinSql = " left join"; + if (!string.IsNullOrWhiteSpace(dto.AppUserId)) + { + weworkUserJoinSql = " join "; + filter.Add($" b.userid = @AppUserId"); + ps.Add(new MySqlParameter("AppUserId", dto.AppUserId)); + } + if (!string.IsNullOrWhiteSpace(dto.NickName)) + { + weworkUserJoinSql = " join "; + filter.Add($" b.name like @NickName"); + ps.Add(new MySqlParameter("NickName", $"%{dto.NickName}%")); + } + if (!string.IsNullOrWhiteSpace(dto.ResId)) + { + weworkUserJoinSql = " join "; + filter.Add($" b.ResId = @ResId"); + ps.Add(new MySqlParameter("ResId", dto.ResId)); + } + var where = ""; + if (filter.Count > 0) + { + where = $"{Environment.NewLine}where {string.Join(" and ", filter)}"; + } + var fields = " t1.*,we.name as AppName,b.name as nickName,b.resid as Phone "; + var tables = $@"AssignRules t1 {tableFilter} + join db_company_base_conf.employee t2 on t1.eid =t2.employee_id + left join Wework we on t1.appid = we.appid + {weworkUserJoinSql} WeworkUser as b on t1.appid=b.appid and t1.userid=b.userid "; + var sql = $"select count(1) from {tables}{where}"; + var total = await _cmsRepository.ExecuteSqlToCountLongAsync(sql, ps.ToArray()); + + var skip = (dto.PageIndex - 1) * dto.PageSize; + var take = dto.PageSize; + sql = $"select {fields} from {tables}{where} order by t1.id desc limit {skip},{take}"; + var res = await _cmsRepository.ExecuteSqlToListAsync(sql, ps.ToArray()); + foreach (var item in res) + { + item.nickName = System.Web.HttpUtility.UrlDecode(item.nickName, System.Text.Encoding.UTF8); + } + return new PageResult(dto.PageIndex, dto.PageSize, Convert.ToInt32(total), res); + } + + /// + /// 创建编辑 + /// + /// + /// + public async Task Create(List ruleList) + { + //校验 todo + using var transaction = await _cmsRepository.BeginTransactionAsync(); + var group = ruleList.GroupBy(n => new { n.salegroupid, n.eid }) + .Select(n => new { n.Key.salegroupid, n.Key.eid, count = n.Count() }).ToList(); + if (group.Exists(n => n.count > 1)) + { + throw new Exception($"同个规则组不能存在多条相同工号的记录,重复工号为【{string.Join(",", group.Where(n => n.count > 1).Select(n => n.eid))}】"); + } + var eids = ruleList.Select(n => n.eid).Distinct().ToList(); + var gid = ruleList.FirstOrDefault().salegroupid; + var dbList = await _cmsRepository.GetRepository().Query().Where(n => n.salegroupid == gid && eids.Contains(n.eid)).ToListAsync(); + + foreach (var rule in ruleList) + { + if (dbList.Exists(n => n.eid == rule.eid && n.salegroupid == gid)) + { + throw new Exception($"同个规则组不能存在多条相同工号的记录,重复工号为【{rule.eid}】"); + } + var dbassign = _cmsRepository.GetRepository().Query().FirstOrDefault(n => n.eid == rule.eid && n.salegroupid == rule.salegroupid); + if (dbassign == null) + { + var info = new Assign() + { + eid = rule.eid, + salegroupid = rule.salegroupid.Value, + allocations = 0, + quantity = 0, + todayquantity = 0, + tgallocations = 0, + tgtodayallocations = 0, + tgquantity = 0 + }; + + await _cmsRepository.GetRepository().InsertAsync(info); + } + AssignRules newrule = new AssignRules + { + eid = rule.eid, + salegroupid = rule.salegroupid, + appid = rule.appid, + userid = rule.userid, + uname = rule.uname, + rate = rule.rate, + num = rule.num, + islimit = rule.islimit, + isvalid = rule.isvalid, + levelno = rule.levelno, + crmdeptid = rule.crmdeptid, + deptrate = rule.deptrate, + inneruserid = rule.inneruserid, + ctime = DateTime.Now, + utime = DateTime.Now, + }; + await _cmsRepository.GetRepository().InsertAsync(newrule); + } + + await transaction.CommitAsync(); + return true; + } + + /// + /// 上下线 + /// + /// + /// + public async Task UpOrDowmAssignRule(AssignRuleUpOrDowmDto dto) + { + var ruleList = await _cmsRepository.GetRepository().Query().Where(n => dto.ids.Contains(n.id)).ToListAsync(); + if (dto.type == 1) + { + foreach (var rule in ruleList) + { + rule.isvalid = dto.isvalid; + rule.startTime = dto.startTime; + rule.endTime = dto.endTime; + rule.utime = DateTime.Now; + } + } + else + { + foreach (var rule in ruleList) + { + if (dto.islimit.HasValue) + { + rule.islimit = dto.islimit; + } + if (dto.num.HasValue) + { + rule.num = dto.num; + } + if (dto.levelno.HasValue) + { + rule.levelno = dto.levelno; + } + rule.utime = DateTime.Now; + } + } + await _cmsRepository.GetRepository().BatchUpdateAsync(ruleList); + return true; + } + + public async Task Delete(List ids) + { + var ruleList = await _cmsRepository.GetRepository().Query().Where(n => ids.Contains(n.id)).ToListAsync(); + await _cmsRepository.GetRepository().BatchDeleteAsync(ruleList); + return true; + } + + public async Task> GetNotSetAssignList(AssignRuleNotSetQueryDto dto) + { + if (!dto.sgid.HasValue) + { + return new List(); + } + var query = await _cmsRepository.GetRepository().Query().Where(n => n.salegroupid == dto.sgid).Select(n => n.eid).ToListAsync(); + var wheresql = $" where a.eid >0 and r.eid is null and a.assignstatus=1 and te.is_deleted =0"; + var sql = @$" select a.id,a.appid,a.userid,a.eid,b.avatar,te.employee_name as Uname,b.name as NickName,we.name as AppName from WeworkUser2Eid as a + + left join Wework we on a.appid = we.appid + left join WeworkUser as b on a.appid=b.appid and a.userid=b.userid + JOIN db_company_base_conf.employee AS te ON a.eid=te.employee_id + LEFT join AssignRules r on a.eid = r.eid and salegroupid = @salegroupid "; + var ps = new List + { + new MySqlParameter("salegroupid",dto.sgid) + }; + if (!string.IsNullOrWhiteSpace(dto.uname)) + { + wheresql += $" and (te.employee_name like @cname or te.employee_id like @cname)"; + ps.Add(new MySqlParameter("cname", $"%{dto.uname}%")); + } + if (dto.departmentId.HasValue) + { + sql += $" join employee_department_detail em on a.eid = em.eid and em.department_id = @departmentid "; + ps.Add(new MySqlParameter("departmentid", dto.departmentId)); + } + if (!string.IsNullOrWhiteSpace(dto.deptIds)) + { + wheresql += $" and a.deptid in ({dto.deptIds})"; + } + sql += wheresql; + sql += " order by a.eid desc"; + var res = await _cmsRepository.ExecuteSqlToListAsync(sql, ps.ToArray()); + return res; + } + + /// + /// 自动上下线 + /// + /// + public async Task AutoUpAssignRule() + { + var nowTime = DateTime.Now; + var upList = await _cmsRepository.GetRepository().Query().Where(n => n.isvalid == 0 && n.startTime <= nowTime && (!n.endTime.HasValue || (n.endTime.HasValue && n.endTime >= nowTime))).ToListAsync(); + foreach (var up in upList) + { + up.isvalid = 1; + } + await _cmsRepository.GetRepository().BatchUpdateAsync(upList, x => new { x.isvalid }); + var downList = await _cmsRepository.GetRepository().Query().Where(n => n.isvalid == 1 && n.endTime.HasValue && n.endTime <= nowTime).ToListAsync(); + foreach (var up in downList) + { + up.isvalid = 0; + } + await _cmsRepository.GetRepository().BatchUpdateAsync(downList, x => new { x.isvalid }); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/CacheDomain.cs b/code/Zxd.Crm.Domain/CacheDomain.cs new file mode 100644 index 0000000..dff7210 --- /dev/null +++ b/code/Zxd.Crm.Domain/CacheDomain.cs @@ -0,0 +1,99 @@ +using DG.EntityFramework; +using DG.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; +using Zxd.Domain.Config; +using Zxd.Entity.Zxd; +using Zxd.EntityFramework; + +namespace Zxd.Crm.Domain +{ + public class CacheDomain : ICacheDomain + { + private readonly IRedisManager _redisManager; + private readonly IBaseRepository _repository; + + public CacheDomain(IRedisManager redisManager, + IBaseRepository repository) + { + _redisManager = redisManager; + _repository = repository; + } + + private async Task> GetParameterList() + { + if (!await _redisManager.ExistsAsync(CacheKeys.ParameterList)) + { + var list = await _repository.GetRepository().QueryListAsync(); + await _redisManager.SetAsync(CacheKeys.ParameterList, list); + return list; + } + else + { + return await _redisManager.GetListAsync(CacheKeys.ParameterList); + } + } + + public async Task GetValueParameter(string key) + { + var list = await GetParameterList(); + return list.FirstOrDefault(x => x.PARAKEY == key)?.PARAVALUE ?? ""; + } + + public async Task> GetDeptMapList() + { + var key = CacheKeys.UserDeptMapList; + if (await _redisManager.ExistsAsync(key)) + { + try + { + return await _redisManager.GetListAsync(key); + } + catch (Exception ex) + { + await _redisManager.RemoveAsync(key); + } + } + return new List(); + } + + public async Task AddDeptMapInfo(List deptList) + { + var key = CacheKeys.UserDeptMapList; + if (!await _redisManager.ExistsAsync(key)) + { + await _redisManager.SetAsync(key, deptList, TimeSpan.FromMinutes(30)); + } + else + { + var list = await _redisManager.GetListAsync(key); + list.AddRange(deptList); + await _redisManager.SetAsync(key, list, TimeSpan.FromMinutes(30)); + } + } + + public async Task UpdateDeptMapInfo(List deptList) + { + var key = CacheKeys.UserDeptMapList; + if (deptList == null || deptList.Count == 0) + { + await _redisManager.RemoveAsync(key); + return; + } + + if (!await _redisManager.ExistsAsync(key)) + { + await _redisManager.SetAsync(key, deptList); + } + else + { + await _redisManager.SetAsync(key, deptList, TimeSpan.FromMinutes(30)); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Config/CacheKeys.cs b/code/Zxd.Crm.Domain/Config/CacheKeys.cs new file mode 100644 index 0000000..2181f3b --- /dev/null +++ b/code/Zxd.Crm.Domain/Config/CacheKeys.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Config +{ + internal class CacheKeys + { + public const string ProductModuleList = "product_module_list"; + + public const string ProductGroupList = "product_group_list"; + + public const string ProductTypeList = "product_type_list"; + + public const string ProductTeacherList = "product_teacher_list"; + + public const string ProductList = "product_list"; + + public const string StandardType = "standard_product_type"; + + public const string StandardWay = "standard_product_way"; + + public const string DeptmentList = "deptment_list"; + + public const string ModuleList = "module_list"; + + public const string ParameterList = "cache_parameter_list"; + + public const string TokenList = "cache_token_list"; + public const string UserDeptMapList = "cache_usermap_list"; + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Config/ClientKey.cs b/code/Zxd.Crm.Domain/Config/ClientKey.cs new file mode 100644 index 0000000..a5137a4 --- /dev/null +++ b/code/Zxd.Crm.Domain/Config/ClientKey.cs @@ -0,0 +1,13 @@ +namespace Zxd.Domain.Config +{ + public class ClientKey + { + public string Id { get; set; } + + public string Name { get; set; } + + public string AccessKey { get; set; } + public string Vi { get; set; } + public string NewAccessKey { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Config/Enum.cs b/code/Zxd.Crm.Domain/Config/Enum.cs new file mode 100644 index 0000000..4f752d4 --- /dev/null +++ b/code/Zxd.Crm.Domain/Config/Enum.cs @@ -0,0 +1,191 @@ + +using System.ComponentModel; + +namespace Zxd.Domain.Config +{ + #region 注册,认证码表 + + public enum EnumInterfaceErrcode + { + 调用成功 = 10000, + 调用成功且有数据 = 10001,//新增的code + 用户名已存在 = 10002, + 参数错误 = 10003, + 手机号码错误 = 10004, + 系统错误 = 10005, + 用户已经认证 = 10006, + 验证码过期 = 10007, + 该订单已开通不能撤销 = 10008, + 用户无手机号码 = 10009, + 手机号码已认证 = 10010, + 用户付款失败 = 10011, + 无手机号码不能重置密码 = 10012, + 订单已开通只充值 = 10013, + 订单不存在账户充值成功 = 10014, + 非法请求 = 10015, + 支付金额不足开通失败 = 10016, + 数据不存在 = 10017, + 类型已存在不能重复添加 = 10018, + 非认证用户 = 10019, + 该用户没有手机号码 = 10020, + 十五分钟已连续发送三次 = 10021, + 积分不够业务失败 = 10022, + 验证码错误 = 10023, + 已提交不同身份证开户信息请联系客服处理 = 10024, + 该资源已被他人认领 = 10025, + 资源无须覆盖 = 10026, + 该客户的身份证已存在不能重复提交 = 10027, + 此申请已经授权 = 10028, + 不存在此代理商 = 10029, + 不存在此用户 = 10030, + 平台信息出错请审核数据 = 10031, + 此号码的已被使用 = 10032, + 该渠道禁止申请 = 10033, + 已拥有相同或更高版本 = 10034, + 开通则撤销之前低版本 = 10035, + 正在处理 = 10036, + 交易商号已注册好视通 = 10037, + 好视通用户名不能重复注册 = 10038, + 好视通注册失败 = 10039, + 好视通授权失败 = 10040, + 不能重复提交 = 10041, + 无效产品大类 = 10042, + 无效产品小类 = 10043, + 订单已开通 = 10044, + 订单已取消 = 10045, + 支付步骤出错 = 10046, + 订单未开通 = 10047, + 订单不可取消 = 10048, + 该openID已存在绑定 = 10049, + 密码不正确 = 10050, + 该UP账号已存在绑定 = 10051, + 验证码不能重复使用 = 10052, + 该UP账号已被管理员禁止修改密码 = 10053, + 调用成功但有错误 = 10054, + 找不到订单 = 10055, + 此订单状态不能再开通 = 10056, + 文件路径不能为空 = 10057 + } + + #endregion 注册,认证码表 + + #region 系统参数配置 + + public enum Parameter + { + 资源, 转换, 导出资源, 是否开启加密, + ORD_MemoStatistics_01, //工单统计 + ORD_MemoStatistics_ZhenGu, //诊股资源工单统计 + + Sys_Environment_DeptCode,//当前系统部门编码 + Sys_ExlceImport_PhoneRule,//手机号码生成规则 + Sys_ExcelImport_SkipOran,//是否跳过机构验证导入等于配置的机构数据 + Sys_IsShowFXH,//是否显示渤海信息 + Sys_RetrievePwd_Name,//找回密码短信配置 您好,密码找回短信配置:{0}是密码,{1}是帐号 + Is_ShowCustomerMobileArea,//是否显示号码地区 + Sys_HomeTab_Javascript,//系统home页面的主题框架脚本 主页面的js,Tab打开风格JS + Sys_IsFreeze_Wdzm,//是否冻结我的桌面 默认是不冻结可以关闭的true=冻结,false=可以关闭 + Sys_IsMiniCustomerInfo,//显示简单详细资料 + ISVR_AD_CheckUserNameCompetence, + ISVR_AD_upAgentCreateActiveOrder, + ISVR_AD_upAgentOpenOrder, + ISVR_AD_CancelActiveOrder, + ISVR_AD_HstRegUser, + ISVR_AD_HstDelUserName, + ISVR_AD_HstRoomConfig, + ISVR_AD_HstBatchAddUserRight, + ISVR_AD_HstAddUserPower, + ISVR_AD_TbHstRegUser, + ISVR_AD_TbHstRight, + ISVR_AD_TGHstRoomConfig, + ISVR_AD_HstBlackConfig, + + ISVR_IAD_localhostOpenOrder, + ISVR_IAD_localhostSimpleOpenOrder, + ISVR_IAD_localhostCanclOrder, + ISVR_IAD_localhostHstBatchAddUserRight, + ISVR_IAD_localhostHstRoomConfig, + ISVR_IAD_localhostHstDelUserName, + ISVR_IAD_localhostHstRegUser, + ISVR_IAD_localhostHstAddUserPower, + + HQ_RiaService_ActiveMaunl, + + Sms_TencentResetPwdTid, //腾讯云重置密码模板ID + Sms_TencentHgMsgTid, //腾讯云合规消息模板ID + Sms_TencentOpenOrderTid, + Sms_TencentRegisterTid,//腾讯云用户注册模板ID + Sms_TencentOpenOrderDonateTid, + Sms_TencentSign, //腾讯云短信签名 + Sms_TencentPayMsgTid, //腾讯云在线支付消息模板ID + + CustomerCheckData,//质检抓取时间 + Res_EffectAnalysis_01, //资源效果分析 + ISVR_AD_UpdateManager, + + Sys_Bussiness_Code, //营业部Code + Sys_Environment_LogOn, //当前系统部门编码 + WeiXin_OrderCountShowColumn, //微信订单统计产品小类展示列 + WeiXin_WorkAccountInitCount, //客服工作微信号数量 + WeiXIn_SzzyOrderUnPayDayInterval, //上证综研未支付订单间隔天数 + UserCenter_RiaService_AddOrderOpen,//创建订单 + UserCenter_RiaService_OpenOrder,//开通订单 + UserCenter_RiaService_AddOrderOpenFree,//免费订单 + UserCenter_RiaService_refund,//退款接口 + UserCenter_RiaService_closeFreeOrder,//关闭活动免费订单 + UserCenter_RiaService_ResetPwd,//重置密码接口 + UserCenter_RiaService_ResetMobile,//重置手机号接口 + UserCenter_RiaService_UnBindQW,//软件和企业微信关系解绑 + UserCenter_RiaService_ContractSign,//签订合同 + UserCenter_RiaService_Settlement,//和解协议 + UserCenter_RiaService_CancelComplaint,//撤销投诉协议 + UserCenter_RiaService_SignPdf,//合同pdf地址 + UserCenter_RiaService_OrderGet,//订单信息获取 + UserCenter_RiaService_ForceMerge,//调用Node用户中心进行客户合并 + UserCenter_RiaService_UnBind,//调用Node用户中心进行客户解绑 + UserCenter_RiaService_Risk,//获取风险评测信息 + UserCenter_RiaService_Flag,//获取是否适合信息 + + //UserCenter_RiaService_Riske,//风控URL + Sys_ProjectType, //项目类型,1:证券之星广州 2:南京鼎迈 + + Sys_OrderOpenCountByTimeType, //订单开通统计的时间周期 otime:开通时间 arrivaltime:到账时间 + Sys_ShowMobileStartDate, //为空:就都不显示手机 日期:从该日期之后的资源,显示电话 + Sys_UserComBoxAllShow, //员工分组下拉菜单显示所有员工 0:不显示离职 1:显示全部 + WeiXin_GroupLeaderPasueReceiveRes, //主管是否暂停接收资源 1:暂停 0:接收 + WeiXin_TotalPauseReceiveRes, //微信总资源客户数较多暂停接收资源 1:暂停 0:接收 + Sys_CanExportAllocate, //是否能导出资源 + Sys_OrderClientIdKey, //订单加密客户端ID的键名 + Sys_CanShowResMobile, //是否在资源页面显示手机号 + WeiXin_TotalPauseUserNum, //总资源暂停客服人数 + WeiXin_OrderUserNameRequired, //订单用户微信用户名必填项 + WeiXin_IllegalKewords, //合规关键词词配置 + MonthCommission, //月份提成 + WeiXin_CrossDBSzzyOrder, //跨库订单数据 + Sys_QHData, //期货业务 + WeiXin_OfflineResTypeIds, //线下资源类型id + Sys_IsShowMobileOfContent, //是否显示内容中的手机号 + WeiXin_IsShowOpenOrderTip, //是否显示我的微信客户开通订单提示 + Sys_SaleDeptId_Three, //三部的SaleDeptId + Sys_SaleDeptId_OneAndTwo, //一二部的SaleDeptId + Sys_rpt_json_config,//业绩预测配置 + UserCenter_RiaService_RefundContract, //退款合同 + WeiXin_IllegalKewordsDeptConfig,//合规关键词推送deptcode + UserCenter_UserEnter,//用户中心注册接口 + UserCenter_HandelLabel,//用户中心写标签接口 + HG_Level,//合规类型等级 + AI_CallTaskConfig //回访机器人配置 + } + + public enum ParameterGroup + { + ORD_MemoStatistics, + FavoritesCustType, + SystemConfig,//系统配置 + ExternalInterfaceAddress, + SMS_CONFIG, + OrderPayType + } + + #endregion 系统参数配置 +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Config/SystemConfig.cs b/code/Zxd.Crm.Domain/Config/SystemConfig.cs new file mode 100644 index 0000000..f124f0c --- /dev/null +++ b/code/Zxd.Crm.Domain/Config/SystemConfig.cs @@ -0,0 +1,84 @@ +namespace Zxd.Domain.Config +{ + /// + /// 系统参数 + /// + public class SystemConfig + { + public string Appid { get; set; } + + public string AppSecret { get; set; } + + public string SsoUrl { get; set; } + public string CrmCoreUrl { get; set; } + public string ZxdCoreUrl { get; set; } + public string SsoOrganizationUrl { get; set; } + + /// + /// 销售线索URL + /// + public string? SalesLeadUrl { get; set; } + + /// + /// CRM号码加密key(clientKey) + /// + public string? CRMClientKey { get; set; } + + /// + /// 推送部门编码 + /// + + public string? DataClientCode { get; set; } + + /// + /// 深海捷固定坐席 + /// + public string? Shj { get; set; } + + /// + /// 客户端密钥 + /// + public List? ClientKey { get; set; } + + /// + /// + /// + + public string DataSyncApiUrl { get; set; } + + /// + /// 短信注册信息 + /// + public string SoftRegisterMsg { get; set; } + + public string SsoTokenUrl { get; set; } + public string GetEidByBusinessLineUrl() + { + return $"{CrmCoreUrl}/Api/Customer/BusinessLineByDeptMentIds"; + } + public string GetSsoOrganizationUrl() + { + return $"{SsoUrl}{SsoOrganizationUrl}"; + } + public string GetDeptsUrl() + { + return $"{ZxdCoreUrl}/Api/Deptment/Depts"; + } + public string GetSsoTokenUrl() + { + return $"{SsoUrl}{SsoTokenUrl}"; + } + + /// + /// 资源系统ip地址 + /// + public string CmsUrl { get; set; } + + public string[] ClearCacheUrls { get; set; } + + public string GetAccessKey(string id) + { + return ClientKey?.First(x => x.Id == id).AccessKey ?? ""; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Config/Utility.cs b/code/Zxd.Crm.Domain/Config/Utility.cs new file mode 100644 index 0000000..fcb267f --- /dev/null +++ b/code/Zxd.Crm.Domain/Config/Utility.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Config +{ + public static class Utility + { + /// + /// 获取数据 + /// + /// + /// + /// + public static string GetData(string Url, string RequestPara, IDictionary headers, Encoding encoding, int timeout = 5000) + { + RequestPara = RequestPara.IndexOf('?') > -1 ? (RequestPara) : ("?" + RequestPara); + + WebRequest hr = HttpWebRequest.Create(Url + RequestPara); + + byte[] buf = encoding.GetBytes(RequestPara); + hr.Method = "GET"; + hr.Timeout = timeout; + foreach (var item in headers) + { + hr.Headers.Add(item.Key, item.Value); + } + System.Net.WebResponse response = hr.GetResponse(); + StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")); + string ReturnVal = reader.ReadToEnd(); + reader.Close(); + response.Close(); + + return ReturnVal; + } + /// + /// 时间戳转为C#格式时间 + /// + /// + /// + public static DateTime ConvertStringToDateTime(string timeStamp) + { + DateTime dtStart = TimeZone.CurrentTimeZone.ToUniversalTime(new DateTime(1970, 1, 1)); + long lTime = long.Parse(timeStamp + "0000"); + TimeSpan toNow = new TimeSpan(lTime); + return dtStart.Add(toNow); + } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/AssignRule/AssignRuleQueryDto.cs b/code/Zxd.Crm.Domain/Dto/AssignRule/AssignRuleQueryDto.cs new file mode 100644 index 0000000..576898f --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/AssignRule/AssignRuleQueryDto.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto.AssignRule +{ + public class AssignRuleQueryDto : SearchPageBase + { + /// + /// 根据这个区分坐席 + /// + public string? allsgids { get; set; } + + public int? sgid { get; set; } + + public int? departmentId { get; set; } + public string? name { get; set; } + public int? UserId { get; set; } + + /// + /// 档位 + /// + public int? Level { get; set; } + + /// + /// 是否上线 + /// + public int? isvalid { get; set; } + + public string? AppUserId { get; set; } + public string? NickName { get; set; } + public string? ResId { get; set; } + } + + public class AssignRuleModel + { + public int id { get; set; } + + public int? eid { get; set; } + public int? salegroupid { get; set; } + public string? appid { get; set; } + public string? userid { get; set; } + public string? uname { get; set; } + + /// + /// 最终比例 + /// + public decimal? rate { get; set; } + + /// + /// 档位 + /// + public int? num { get; set; } + + /// + /// 是否限制 + /// + public int? islimit { get; set; } + + /// + /// 限制数量 + /// + public int? limitnum { get; set; } + + /// + /// 是否有效 + /// + public int? isvalid { get; set; } + + /// + /// 渠道号 + /// + public int? ch { get; set; } + + /// + /// 档位 + /// + public int? levelno { get; set; } + + /// + /// Crm部门ID + /// + public int? crmdeptid { get; set; } + + /// + /// 部门比例 + /// + public decimal? deptrate { get; set; } + + /// + /// 客服ID + /// + public int? inneruserid { get; set; } + + /// + /// 创建时间 + /// + public DateTime? ctime { get; set; } + + /// + /// 更新时间 + /// + public DateTime? utime { get; set; } + + /// + /// 企微昵称 + /// + public string? nickName { get; set; } + + /// + /// 企微名称 + /// + public string? AppName { get; set; } + + /// + /// 手机号 + /// + public string? Phone { get; set; } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + } + + public class AssignRuleCreateDto + { + public int? id { get; set; } + + public int? eid { get; set; } + public int? salegroupid { get; set; } + public string? appid { get; set; } + public string? userid { get; set; } + public string? uname { get; set; } + + /// + /// 最终比例 + /// + public decimal? rate { get; set; } + + /// + /// 档位 + /// + public int? num { get; set; } + + /// + /// 是否限制 + /// + public int? islimit { get; set; } + + /// + /// 是否有效 + /// + public int? isvalid { get; set; } + + /// + /// 档位 + /// + public int? levelno { get; set; } + + /// + /// Crm部门ID + /// + public int? crmdeptid { get; set; } + + /// + /// 部门比例 + /// + public decimal? deptrate { get; set; } + + /// + /// 客服ID + /// + public int? inneruserid { get; set; } + } + + public class AssignRuleUpOrDowmDto + { + /// + /// 1 为上下线 2 为换档 + /// + public int? type { get; set; } = 1; + + public int? islimit { get; set; } + + /// + /// 是否有效 + /// + public int? isvalid { get; set; } + + /// + /// 几档 + /// + public int? levelno { get; set; } + + public int? num { get; set; } + public DateTime? startTime { get; set; } + public DateTime? endTime { get; set; } + public List ids { get; set; } + } + + public class AssignRuleNotSetQueryDto + { + public int? sgid { get; set; } + + /// + /// 部门Id + /// + public int? departmentId { get; set; } + + public string? deptIds { get; set; } + public string? uname { get; set; } + } + + public class NotSetAssignRuleDto + { + public int? Id { get; set; } + public int? Eid { get; set; } + public string? AppId { get; set; } + public string? UserId { get; set; } + public string? AppName { get; set; } + public string? DepartmentId { get; set; } + public string? Uname { get; set; } + public string? NickName { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/BindAppUserDto.cs b/code/Zxd.Crm.Domain/Dto/BindAppUserDto.cs new file mode 100644 index 0000000..488b39b --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/BindAppUserDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class BindAppUserDto + { + public string from { get; set; } + public int eid { get; set; } + public string resid { get; set; } + public string softusername { get; set; } + public string show_phone { get; set; } + public int type { get; set; } + public int phone { get; set; } + public int verificationCode { get; set; } + + } +} diff --git a/code/Zxd.Crm.Domain/Dto/CreateFieldDto.cs b/code/Zxd.Crm.Domain/Dto/CreateFieldDto.cs new file mode 100644 index 0000000..bcd4463 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/CreateFieldDto.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class CreateFieldDto + { + /// + /// 字段 + /// + public string? Field { get; set; } + + /// + /// 类型 + /// normal(常规列,无需设定) + /// checkbox(复选框列) + /// radio(单选框列) + /// numbers(序号列) + /// space(空列) + /// + public string? Type { get; set; } + + /// + /// 标题 + /// + public string? Title { get; set; } + + /// + /// 设定列宽 + /// + public int? Width { get; set; } + + /// + /// 固定列。可选值有:left(固定在左)、right(固定在右) + /// + public string? Fixed { get; set; } + + /// + /// 自定义列模板 + /// + public string? Templet { get; set; } + + /// + /// 是否允许排序 + /// + public bool? Sort { get; set; } + + /// + /// 是否初始隐藏列 + /// + public bool? Hide { get; set; } + + /// + /// 排序 + /// + public int? Order { get; set; } + + /// + /// checkbox + /// + public bool? Checkbox { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/CreateOrUpdateUserSettingDto.cs b/code/Zxd.Crm.Domain/Dto/CreateOrUpdateUserSettingDto.cs new file mode 100644 index 0000000..611bf57 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/CreateOrUpdateUserSettingDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class CreateOrUpdateUserSettingDto + { + public string? Module { get; set; } + + public int? Eid { get; set; } + + public List? Data { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/CreateTableFieldDto.cs b/code/Zxd.Crm.Domain/Dto/CreateTableFieldDto.cs new file mode 100644 index 0000000..080d319 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/CreateTableFieldDto.cs @@ -0,0 +1,23 @@ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class CreateTableFieldDto + { + /// + /// 模块 + /// + public string? Module { get; set; } + + /// + /// 字段 + /// + public List? Fields { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/DeptmentDto.cs b/code/Zxd.Crm.Domain/Dto/DeptmentDto.cs new file mode 100644 index 0000000..491dc06 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/DeptmentDto.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Shared.Dto; + +namespace Zxd.Crm.Domain.Dto +{ + public class DeptmentDto + { + public int id { get; set; } + public int? groupId { get; set; } + public string? title { get; set; } + + public string? code { get; set; } + + public string? appid { get; set; } + + public int departmentId { get; set; } + + public bool? isDept { get; set; } + + public string? companyCode { get; set; } + + public List? deptmentCampains { get; set; } + } + + public class DeptmentCampainDto + { + public int startCampainId { get; set; } + + public int endCampainId { get; set; } + } + + /// + /// redis 里面的值 + /// + public class RedisDeptmentDto + { + public int Id { get; set; } + public int? GroupId { get; set; } + public string? Title { get; set; } + + public string? Code { get; set; } + + public string? Appid { get; set; } + + public int DepartmentId { get; set; } + + public bool? IsDept { get; set; } + + public string? CompanyCode { get; set; } + + public int? SortNo { get; set; } + + public List? DeptmentCampains { get; set; } + } + + public class RedisDeptmentCampainDto + { + public int StartCampainId { get; set; } + + public int EndCampainId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/Extuser/ExtUserCreateDto.cs b/code/Zxd.Crm.Domain/Dto/Extuser/ExtUserCreateDto.cs new file mode 100644 index 0000000..7072455 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/Extuser/ExtUserCreateDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto.Extuser +{ + public class ExtUserCreateDto + { + public string resid { get; set; } + public string userid { get; set; } + public string? deptcode { get; set; } + public string? type { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/GetDeptMentDto.cs b/code/Zxd.Crm.Domain/Dto/GetDeptMentDto.cs new file mode 100644 index 0000000..f9dc872 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/GetDeptMentDto.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class GetDeptMentDto + { + public int? eid { get; set; } + public string? CompanyCode { get; set; } + } + + public class DeptMentReturnModel + { + public string? Eid { get; set; } + public int? DeptId { get; set; } + public string? DeptName { get; set; } + public string? CompanyCode { get; set; } + public string? AppId { get; set; } + public int? SaleDeptId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/GetEmpowermentDto.cs b/code/Zxd.Crm.Domain/Dto/GetEmpowermentDto.cs new file mode 100644 index 0000000..2a530ff --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/GetEmpowermentDto.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class GetEmpowermentDto + { + public int id { get; set; } + //public bool? check { get; set; } + //public int? sort { get; set; } + public int? employee_id { get; set; } + public string? employee_name { get; set; } + public string? phone { get; set; } + public string? showPhone { get; set; } + public string? resid { get; set; } + public string? umid { get; set; } + public int? is_deleted { get; set; } + public int? appid { get; set; } + public int is_main { get; set; } + public string? appusername { get; set; } + public DateTime? update_time { get; set; } + public DateTime? create_time { get; set; } + public DateTime? soft_create_time { get; set; } + public string? productString { get; set; } + public DateTime? regdate { get; set; } + public DateTime? last_empower_time { get; set; } + } + public class GetEmpowermentByAppidDto : SearchPageBase + { + public string appid { get; set; } + public int? eid { get; set; } + public string? name { get; set; } + public int? userId { get; set; } + public int? deptId { get; set; } + public string? umid { get; set; } + } + public class BusinessLineDto + { + public bool isLine { get; set; } + + public int deptId { get; set; } + + public List eidInfo { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/GetProductByAppidDto.cs b/code/Zxd.Crm.Domain/Dto/GetProductByAppidDto.cs new file mode 100644 index 0000000..b1aaf71 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/GetProductByAppidDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + + public class GetProductByAppidDto : SearchPageBase + { + public string appid { get; set; } + + } +} diff --git a/code/Zxd.Crm.Domain/Dto/GetWarnningTemplateDto.cs b/code/Zxd.Crm.Domain/Dto/GetWarnningTemplateDto.cs new file mode 100644 index 0000000..b9879e7 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/GetWarnningTemplateDto.cs @@ -0,0 +1,207 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class GetWarnningTemplateDto : SearchPageBase + { + public GetWarnningTemplateDto() + { + } + + /// + /// id + /// + public int? Id { get; set; } + + /// + /// 名称 + /// + public string? Name { get; set; } + + public string? DeptId { get; set; } + } + + public class WarnningTemplateCreateDto + { + public int Id { get; set; } + public int DeptId { get; set; } + public string? TemplateName { get; set; } + public DateTime PeriodFrom { get; set; } + + public DateTime PeriodTo { get; set; } + public string? PrewarningValue { get; set; } + + public int? Count { get; set; } + public int Maxnum { get; set; } + } + + public class TemplateSettingDetail + { + public string? guid { get; set; } + public int? type { get; set; } + public int? value { get; set; } + } + + public class WarnningTemplateReturnModel : WarnningTemplateCreateDto + { + } + + #region 配置 + + public class CreateOrEditSettingDto + { + public CreateOrEditSettingDto() + { + } + + public int DeptId { get; set; } + + /// + /// 最大数量 + /// + public int? MaxNum { get; set; } + + /// + /// 用户 + /// + public string Participant { get; set; } + + public List WarnUserInfo { get; set; } + + /// + /// 模板id + /// + public int? templateId { get; set; } + + public string Eid { get; set; } + } + + public class WarnUserInfo + { + public decimal Eid { get; set; } + public string Name { get; set; } + } + + public class WarnningSetting + { + public int? DeptId { get; set; } + + /// + /// 最大数量 + /// + public int MaxNum { get; set; } + + /// + /// 模板id + /// + public int? templateId { get; set; } + + /// + /// 参与人 + /// + [JsonIgnore] + public string? Participant { get; set; } + + /// + /// 参与人 + /// + public List? ParticipantIds { get; set; } + + public List Template { get; set; } + } + + public class TemplateSelectList + { + public int Id { get; set; } + public string? TemplateName { get; set; } + public bool selected { get; set; } = false; + } + + public class ReportListModel + { + public decimal? Eid { get; set; } + public int? MaxNum { get; set; } + public string Name { get; set; } + } + + #endregion 配置 + + #region 预警人员配置 + + public class GetWarnningUserTotalDto : SearchPageBase + { + public GetWarnningUserTotalDto() + { + } + + public string? DeptId { get; set; } + } + + public class GetWarnningSettingDto + { + public int? DeptId { get; set; } + public string? EidList { get; set; } + } + + public class WarnUserList + { + public string? Code { get; set; } + public int? DeptId { get; set; } + public int? Count { get; set; } + public List ParticipantIds + { + get + { + return string.IsNullOrEmpty(Participant) ? new List() : Participant.Split(',').Select(x => int.Parse(x)).ToList(); + } + } + + public string Participant { get; set; } + } + + public class EarlyWarningUserModel + { + public int? Deptid { get; set; } + public string? WxWorkId { get; set; } + public List ParticipantIds + { + get + { + return string.IsNullOrEmpty(Participant) ? new List() : Participant.Split(',').Select(x => int.Parse(x)).ToList(); + } + } + + public string? Participant { get; set; } + public string? Code { get; set; } + } + + public class EarlyWarningUserCreateDto + { + public string? Code { get; set; } + public int? DeptId { get; set; } + public string WxWorkId { get; set; } + public int Type { get; set; } //1 为 新增 2 为 编辑 + public string? AppId { get; set; } + public string? Cropid { get; set; } + public string? CropName { get; set; } + public string Participant { get; set; } + public List ParticipantIds + { + get + { + return string.IsNullOrEmpty(Participant) ? new List() : Participant.Split(',').Select(x => int.Parse(x)).ToList(); + } + } + } + + #endregion 预警人员配置 +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActProductCreateDto.cs b/code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActProductCreateDto.cs new file mode 100644 index 0000000..0cee7e4 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActProductCreateDto.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Zxd.QiweiOnlePay; + +namespace Zxd.Crm.Domain.Dto.QWOnlinePay +{ + public class ActProductCreateDto + { + public int? Id { get; set; } + public int ActId { get; set; } + public string ProductCode { get; set; } + public int? IsFirst { get; set; } + public int? Eid { get; set; } + public string? Ename { get; set; } + public int? Status { get; set; } + public int? Order { get; set; } + } + + public class ActProductQueryDto : SearchPageBase + { + public string? DeptIds { get; set; } + public int? ActId { get; set; } + public int? Status { get; set; } + public string? ProductCode { get; set; } + public string? ProductName { get; set; } + public int? Eid { get; set; } + public int? DeptId { get; set; } + public int? Ch { get; set; } + } + public class ActProductQueryModel + { + public int? Id { get; set; } + public int? ActId { get; set; } + public string? ActName { get; set; } + public string? ProductCode { get; set; } + public string? ProductName { get; set; } + public int? Day { get; set; } + public decimal? Price { get; set; } + public int? IsFirst { get; set; } + public int? Eid { get; set; } + public string? Ename { get; set; } + public int? Status { get; set; } + public int? Order { get; set; } + public string? PayLink { get; set; } + public string? callbacklink { get; set; } + public string? buylink { get; set; } + } + + public class ActProductModel + { + public int? Id { get; set; } + public int? ActId { get; set; } + public string? ActName { get; set; } + public string? ProductCode { get; set; } + public string? ProductName { get; set; } + public int? Day { get; set; } + public decimal? Price { get; set; } + public int? IsFirst { get; set; } + public int? Eid { get; set; } + public string? Ename { get; set; } + public int? Status { get; set; } + public int? Order { get; set; } + public string? PayLink { get; set; } + } + + public class ProductDownSelect + { + public string name { get; set; } + public string value { get; set; } + } + + public class ProductEditQueryDto + { + public int? Id { get; set; } + public string? CompanyCode { get; set; } + public string? ProductCode { get; set; } + } + + public class ProductEditModel + { + public ActProductModel QWActivityProduct { get; set; } + public List ActList { get; set; } + public List ActProducts { get; set; } + } + + public class ProductInfoQueryDto + { + public int Eid { get; set; } + public string Code { get; set; } + public int? Ch { get; set; } + public int? DeptId { get; set; } + } + + public class ProductInfo + { + public string? ProductCode { get; set; } + public string? ProductName { get; set; } + public decimal? Price { get; set; } + public int? Day { get; set; } + public string? PayLink { get; set; } + } + + public class PayRedirectSetting + { + public bool isThree { get; set; } + public string TowUrl { get; set; } + public string ThreeUrl { get; set; } + } + + public class DelActProductModel + { + public string? Ids { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActivityCreateDto.cs b/code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActivityCreateDto.cs new file mode 100644 index 0000000..fc8b451 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/QWOnlinePay/ActivityCreateDto.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto.QWOnlinePay +{ + public class ActivityQueryDto : SearchPageBase + { + public string? DeptIds { get; set; } + public int? Status { get; set; } + public int? IsCrm { get; set; } + } + + public class ActivityCreateDto + { + public int? Id { get; set; } + public string Name { get; set; } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + public int? Num { get; set; } + public string? Remark { get; set; } + public int? Status { get; set; } = 1; + public string? DeptIdList { get; set; } + public int? Eid { get; set; } + public string? EName { get; set; } + public string? CompanyCode { get; set; } + public int? Order { get; set; } + } + + public class ActivityModel + { + public int? Id { get; set; } + public string Name { get; set; } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + public int? Num { get; set; } + public string? Remark { get; set; } + public int? Status { get; set; } + public int? Eid { get; set; } + public string? EName { get; set; } + public string? DeptName { get; set; } + } + + public class ActivityEidtModel + { + public int? Id { get; set; } + public string Name { get; set; } + public string? StartTime { get; set; } + public string? EndTime { get; set; } + public int? Num { get; set; } + public string? Remark { get; set; } + public int? Status { get; set; } + public int? Eid { get; set; } + public string? EName { get; set; } + public string? DeptIds { get; set; } + public int? Order { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/SetEmpowermentDto.cs b/code/Zxd.Crm.Domain/Dto/SetEmpowermentDto.cs new file mode 100644 index 0000000..ea6ea1d --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/SetEmpowermentDto.cs @@ -0,0 +1,48 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class SetEmpowermentDto + { + public int fromByEid { get; set; } + public List EmployeeList { get; set; } + public List ProductList { get; set; } + public int duration { get; set; } + public string appid { get; set; } + public string orderid { get; set; } + public DateTime endtime { get; set; } + } + public class UpdateLastEmpowerTime + { + public string residString { get; set; } + public long? timestamp { get; set; } + } + public class Employee + { + public int employee_id { get; set; } + public string resid { get; set; } + public string softusername { get; set; } + } + public class SubProduct + { + public int subproductid { get; set; } + public string subproductname { get; set; } + public string productcode { get; set; } + public decimal? price { get; set; } + public int? isEmpower { get; set; } + public int? producttype { get; set; } + public int? mid { get; set; } + } + public class SoftEmployeeBindChangeDto + { + public int to_by_eid { get; set; } + public string resid { get; set; } + public string show_phone { get; set; } + public int from_by_eid { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/TableFieldSettingDto.cs b/code/Zxd.Crm.Domain/Dto/TableFieldSettingDto.cs new file mode 100644 index 0000000..9d97472 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/TableFieldSettingDto.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class TableFieldSettingDto + { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Checkbox { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Field { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Type { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Title { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public int? Width { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Fixed { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Templet { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Sort { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? Hide { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Dto/UserInfoDto.cs b/code/Zxd.Crm.Domain/Dto/UserInfoDto.cs new file mode 100644 index 0000000..33a9433 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/UserInfoDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class UserInfoDto + { + public string? Resid { get; set; } + + public string? Unionid { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/Dto/UserTableFieldSettingDto.cs b/code/Zxd.Crm.Domain/Dto/UserTableFieldSettingDto.cs new file mode 100644 index 0000000..5733dd3 --- /dev/null +++ b/code/Zxd.Crm.Domain/Dto/UserTableFieldSettingDto.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Dto +{ + public class UserTableFieldSettingDto + { + public int Id { get; set; } + + public bool Checkbox { get; set; } + + public string? Field { get; set; } + + public string? Title { get; set; } + + public string? Fixed { get; set; } + + public int Order { get; set; } + + public bool IsSetting { get; set; } + } +} diff --git a/code/Zxd.Crm.Domain/ExtuserDomain.cs b/code/Zxd.Crm.Domain/ExtuserDomain.cs new file mode 100644 index 0000000..e591394 --- /dev/null +++ b/code/Zxd.Crm.Domain/ExtuserDomain.cs @@ -0,0 +1,60 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Dto.Extuser; +using Zxd.Crm.Domain.Impl; +using Zxd.Entity.SSO; +using Zxd.EntityFramework; + +namespace Zxd.Crm.Domain +{ + public class ExtuserDomain : IExtuserDomain + { + private readonly IServiceProvider _serviceProvider; + + public ExtuserDomain(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task BindExtUser(ExtUserCreateDto model) + { + try + { + var sql = @"INSERT INTO ww_extuser_resid(resid,userid,deptcode) + values(@resid,@userid,@deptcode) + on duplicate key update putnum = putnum+1; "; + if (model.type == "unbind") + { + sql = "delete from ww_extuser_resid where resid=@resid and userid=@userid"; + } + using (var scope = _serviceProvider.CreateAsyncScope()) + { + var userCenterRepository = scope.ServiceProvider.GetRequiredService>(); + var param = new List() + { + new MySqlParameter() { ParameterName="resid", MySqlDbType = MySqlDbType.VarChar, Value=model.resid }, + new MySqlParameter() { ParameterName="userid", MySqlDbType = MySqlDbType.VarChar, Value=model.userid }, + new MySqlParameter() { ParameterName="deptcode", MySqlDbType = MySqlDbType.VarChar, Value=model.deptcode } + }; + Log.Information($"sql: {sql}, param: {model.ToJson()}"); + await userCenterRepository.ExecuteSqlCommandNonQueryAsync(CommandType.Text, sql, param.ToArray()); + } + } + catch (Exception ex) + { + Log.Error($"绑定客户企微关系失败{ex.Message}【{model.ToJson()}】"); + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/FieldDomain.cs b/code/Zxd.Crm.Domain/FieldDomain.cs new file mode 100644 index 0000000..621ba64 --- /dev/null +++ b/code/Zxd.Crm.Domain/FieldDomain.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Zxd; + +namespace Zxd.Crm.Domain +{ + internal class FieldDomain : IFieldDomain + { + private readonly IBaseRepository _zxdRepository; + private readonly IMapper _mapper; + + public FieldDomain(IBaseRepository zxdRepository, + IMapper mapper) + { + _zxdRepository = zxdRepository; + _mapper = mapper; + } + + public async Task> GetTableFieldSettings(string? module, decimal? eid) + { + var data = new List(); + if (!await _zxdRepository.GetRepository().Query() + .Include(x => x.TableField) + .AnyAsync(x => x.Eid == eid && x.TableField.Module == module)) + { + data = await _zxdRepository.GetRepository().Query() + .OrderBy(x => x.Fixed == "right") + .ThenBy(x => x.Order) + .Where(x => x.Module == module) + .Select(x => new TableFieldSettingDto + { + Type = x.Type, + Field = x.Field, + Fixed = x.Fixed, + Templet = x.Templet, + Hide = x.Hide, + Width = x.Width, + Sort = x.Sort, + Title = x.Title, + Checkbox = x.Checkbox + }).ToListAsync(); + + return data; + } + + data = await _zxdRepository.GetRepository().Query() + .Include(x => x.TableField) + .Where(x => x.Eid == eid && x.TableField.Module == module) + .OrderBy(x => x.Fixed == "right") + .ThenBy(x => x.Order) + .Select(x => new TableFieldSettingDto + { + Type = x.TableField.Type, + Field = x.TableField.Field, + Fixed = x.Fixed ?? x.TableField.Fixed, + Templet = x.TableField.Templet, + Hide = x.TableField.Hide != x.Hide || x.Hide, + Width = x.TableField.Width, + Sort = x.TableField.Sort, + Title = x.TableField.Title, + Checkbox = x.TableField.Checkbox + }).ToListAsync(); + return data; + } + + public async Task CreateTableField(CreateTableFieldDto createTable) + { + var tableFields = _mapper.Map(createTable.Fields); + var i = 0; + tableFields.ForEach(x => + { + x.Module = createTable.Module; + x.CreateTime = DateTime.Now; + x.Order = i; + i++; + }); + await _zxdRepository.GetRepository().BatchInsertAsync(tableFields); + } + + public async Task> GetUserTableFieldSettings(string? module, decimal? eid) + { + var data = new List(); + if (!await _zxdRepository.GetRepository().Query() + .Include(x => x.TableField) + .AnyAsync(x => x.Eid == eid && x.TableField.Module == module)) + { + data = await _zxdRepository.GetRepository().Query() + .OrderBy(x => x.Order) + .Where(x => x.Module == module && x.Hide == false) + .Select(x => new UserTableFieldSettingDto + { + Id = x.Id, + Field = x.Field, + Checkbox = true, + Fixed = x.Fixed, + Order = x.Order, + Title = x.Title, + IsSetting = false + }).ToListAsync(); + + return data; + } + data = await _zxdRepository.GetRepository().Query() + .Include(x => x.TableField) + .Where(x => x.Eid == eid && x.TableField.Module == module && x.TableField.Hide == false) + .OrderBy(x => x.Order) + .Select(x => new UserTableFieldSettingDto + { + Id = x.Id, + Field = x.TableField.Field, + Checkbox = !x.Hide, + Fixed = x.Fixed, + Order = x.Order, + Title = x.TableField.Title, + IsSetting = true + }).ToListAsync(); + + return data; + } + + public async Task CreateOrUpdateUserSetting(CreateOrUpdateUserSettingDto dto) + { + if (string.IsNullOrEmpty(dto.Module)) throw new ApiException("请输入模块"); + if (dto.Eid == null) throw new ApiException("请输入员工id"); + if (dto.Data == null || !dto.Data.Any()) throw new ApiException("请输入字段内容"); + var ids = dto.Data.Select(x => x.Id).ToList(); + var userSettings = await _zxdRepository.GetRepository().Query() + .Include(x => x.TableField) + .Where(x => x.Eid == dto.Eid) + .Where(x => x.TableField.Module == dto.Module) + .ToListAsync(); + var addUserSettings = new List(); + foreach (var item in dto.Data) + { + var userSetting = userSettings?.FirstOrDefault(x => x.Id == item.Id); + if (userSetting == null) + { + var setting = new FieldSetting + { + Eid = dto.Eid.Value, + FieldId = item.Id, + Fixed = item.Fixed, + Hide = !item.Checkbox, + Order = item.Order + }; + addUserSettings.Add(setting); + } + else + { + userSetting.Order = item.Order; + userSetting.Fixed = item.Fixed; + userSetting.Hide = !item.Checkbox; + } + } + + var transaction = await _zxdRepository.BeginTransactionAsync(); + try + { + if (addUserSettings.Any()) + { + await _zxdRepository.GetRepository().BatchInsertAsync(addUserSettings); + } + if (userSettings.Any()) + { + await _zxdRepository.GetRepository().BatchUpdateAsync(userSettings, x => new + { + x.Order, + x.Fixed, + x.Hide + }); + } + await transaction.CommitAsync(); + } + catch + { + await transaction.RollbackAsync(); + await transaction.DisposeAsync(); + throw; + } + } + + + public async Task ResetUserTableFieldSettings(string? module, decimal? eid) + { + var fieldSettings = await _zxdRepository.GetRepository().Query() + .Include(x => x.TableField) + .Where(x => x.Eid == eid && x.TableField.Module == module).ToListAsync(); + + if (fieldSettings.Any()) + { + await _zxdRepository.GetRepository().BatchDeleteAsync(fieldSettings); + } + } + + } +} diff --git a/code/Zxd.Crm.Domain/Impl/AssignRule/IAssignRuleDomain.cs b/code/Zxd.Crm.Domain/Impl/AssignRule/IAssignRuleDomain.cs new file mode 100644 index 0000000..4dc6f6c --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/AssignRule/IAssignRuleDomain.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto.AssignRule; +using Zxd.Entity.Dncms; + +namespace Zxd.Crm.Domain.Impl.AssignRule +{ + public interface IAssignRuleDomain : IScopedDependency + { + Task> GetList(AssignRuleQueryDto queryDto); + + Task Create(List dto); + + Task UpOrDowmAssignRule(AssignRuleUpOrDowmDto dto); + + Task Delete(List ids); + + Task> GetNotSetAssignList(AssignRuleNotSetQueryDto dto); + + Task AutoUpAssignRule(); + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Impl/ICacheDomain.cs b/code/Zxd.Crm.Domain/Impl/ICacheDomain.cs new file mode 100644 index 0000000..b227efa --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/ICacheDomain.cs @@ -0,0 +1,21 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; + +namespace Zxd.Crm.Domain.Impl +{ + public interface ICacheDomain : ITransientDependency + { + Task GetValueParameter(string key); + + Task> GetDeptMapList(); + + Task AddDeptMapInfo(List dept); + + Task UpdateDeptMapInfo(List deptList); + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Impl/IExtuserDomain.cs b/code/Zxd.Crm.Domain/Impl/IExtuserDomain.cs new file mode 100644 index 0000000..de48512 --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/IExtuserDomain.cs @@ -0,0 +1,16 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Dto.Extuser; + +namespace Zxd.Crm.Domain.Impl +{ + public interface IExtuserDomain : IScopedDependency + { + Task BindExtUser(ExtUserCreateDto model); + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Impl/IFieldDomain.cs b/code/Zxd.Crm.Domain/Impl/IFieldDomain.cs new file mode 100644 index 0000000..2a0ed3a --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/IFieldDomain.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Impl +{ + public interface IFieldDomain : IScopedDependency + { + Task> GetTableFieldSettings(string? module, decimal? eid); + + Task CreateTableField(CreateTableFieldDto createTable); + + Task> GetUserTableFieldSettings(string? module, decimal? eid); + + Task CreateOrUpdateUserSetting(CreateOrUpdateUserSettingDto dto); + Task ResetUserTableFieldSettings(string? module, decimal? eid); + } +} diff --git a/code/Zxd.Crm.Domain/Impl/ISSOEmployeeDomain.cs b/code/Zxd.Crm.Domain/Impl/ISSOEmployeeDomain.cs new file mode 100644 index 0000000..ce0bef7 --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/ISSOEmployeeDomain.cs @@ -0,0 +1,35 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; +using static Zxd.Crm.Domain.SSOEmployeeDomain; + +namespace Zxd.Crm.Domain.Impl +{ + public interface ISSOEmployeeDomain : IScopedDependency + { + Task> GetDeptmentByEid(string? eidList); + Task> GetEmpowerment(GetEmpowermentByAppidDto dto); + Task AsyncEmplyeeData(); + + Task AsyncEmplyeeData(string eid); + Task ClearZxdEmpolyee(); + Task SSOBindDataInit(); + Task BindSoftUserInit(); + + Task RemoveEidCache(string? activeModel); + + Task> SetEmpowerment(SetEmpowermentDto dto); + Task> UpdateLastEmpowerTime(string residString,long? timestamp); + Task> UpdateAppusername(List UpdateAppusernameList); + Task>> GetAppuserByEid(int eid); + + Task> AddSoftEmployeeBind(int to_by_eid, string resid, string show_phone, int from_by_eid, int is_main = 0); + Task> DeleteSoftEmployeeBind(int to_by_eid, string resid, string show_phone, int from_by_eid); + Task> AddSoftEmployeeBindLog(int to_by_eid, string resid, string type, int from_by_eid); + Task> SetEmployeeSoftDict(EMPLOYEE_SOFT_DICT data); + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Impl/IUserInfoDomain.cs b/code/Zxd.Crm.Domain/Impl/IUserInfoDomain.cs new file mode 100644 index 0000000..39fa3fe --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/IUserInfoDomain.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Crm.Domain.Impl +{ + public interface IUserInfoDomain : IScopedDependency + { + + Task GetUserInfo(string? appid, string? appuserid); + } +} diff --git a/code/Zxd.Crm.Domain/Impl/IWarnningDomain.cs b/code/Zxd.Crm.Domain/Impl/IWarnningDomain.cs new file mode 100644 index 0000000..359a962 --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/IWarnningDomain.cs @@ -0,0 +1,30 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; + +namespace Zxd.Crm.Domain.Impl +{ + public interface IWarnningDomain : IScopedDependency + { + Task> GetTemplatePage(GetWarnningTemplateDto dto); + Task> GetWarnUserTotal(GetWarnningUserTotalDto dto); + Task GetWarnUser(string? code); + + Task DeleteWarnUser(string? code); + Task AddTemplate(WarnningTemplateCreateDto dto); + Task AddWarnSetting(CreateOrEditSettingDto dto); + + Task GetWarnSetting(GetWarnningSettingDto dto); + + Task> GetWarnSettingByEid(string eid); + Task AddWarnUser(EarlyWarningUserCreateDto dto, int? eid); + + Task GetNewTemplatePeriod(int deptid); + + Task GetTemplate(int id); + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/Impl/IWeworkUserWorkerDomain.cs b/code/Zxd.Crm.Domain/Impl/IWeworkUserWorkerDomain.cs new file mode 100644 index 0000000..a3cb82d --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/IWeworkUserWorkerDomain.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Dncms; + +namespace Zxd.Crm.Domain.Impl +{ + public interface IWeworkUserWorkerDomain: IScopedDependency + { + /// + /// 获取客户关系 + /// + /// + /// + /// + Task> GetWeworkUserWorkerList(int? deptid,int minId, int limit = 100); + } +} diff --git a/code/Zxd.Crm.Domain/Impl/QwOnlinePay/IQwOnlinePayDomain.cs b/code/Zxd.Crm.Domain/Impl/QwOnlinePay/IQwOnlinePayDomain.cs new file mode 100644 index 0000000..3b363c6 --- /dev/null +++ b/code/Zxd.Crm.Domain/Impl/QwOnlinePay/IQwOnlinePayDomain.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto.QWOnlinePay; +using Zxd.Entity.Zxd.QiweiOnlePay; + +namespace Zxd.Crm.Domain.Impl.QwOnlinePay +{ + public interface IQwOnlinePayDomain : IScopedDependency + { + Task CreateActivity(ActivityCreateDto dto); + + Task> GetActivityList(ActivityQueryDto queryDto); + + Task GetEditActivityModel(int Id); + + /// + /// 创建活动产品 + /// + /// + /// + + Task CreateActProduct(ActProductCreateDto dto); + + Task> GetActProductList(ActProductQueryDto dto); + + Task GetProductEditModel(ProductEditQueryDto dto); + + Task GetProductInfo(ProductInfoQueryDto dto); + + Task DelActProduct(DelActProductModel dto); + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/QwOnlinePayDomain.cs b/code/Zxd.Crm.Domain/QwOnlinePayDomain.cs new file mode 100644 index 0000000..b3401ea --- /dev/null +++ b/code/Zxd.Crm.Domain/QwOnlinePayDomain.cs @@ -0,0 +1,418 @@ +using MySqlConnector; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto.QWOnlinePay; +using Zxd.Crm.Domain.Impl.QwOnlinePay; +using Zxd.Entity.Zxd; +using Zxd.Entity.Zxd.QiweiOnlePay; + +namespace Zxd.Crm.Domain +{ + public class QwOnlinePayDomain : IQwOnlinePayDomain + { + private readonly IBaseRepository _zxdRepository; + private readonly IMapper _mapper; + private readonly IRedisManager _redisManager; + + public QwOnlinePayDomain(IBaseRepository zxdRepository, + IMapper mapper, + IRedisManager redisManager) + { + _zxdRepository = zxdRepository; + _mapper = mapper; + _redisManager = redisManager; + } + + #region 企微侧边栏活动 + + public async Task CreateActivity(ActivityCreateDto dto) + { + if (dto.StartTime.HasValue && dto.EndTime.HasValue && dto.StartTime > dto.EndTime) + { + throw new Exception("活动开始时间不能大于结束时间"); + } + using var transaction = await _zxdRepository.BeginTransactionAsync(); + var actRepository = _zxdRepository.GetRepository(); + + if (dto.Id.HasValue) + { + var updateItem = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.Id == dto.Id); + if (updateItem == null) + { + throw new Exception("找不到对应的活动"); + } + updateItem.Name = dto.Name; + updateItem.StartTime = dto.StartTime; + updateItem.Eid = dto.Eid; + updateItem.EName = dto.EName; + updateItem.Order = dto.Order; + updateItem.EndTime = dto.EndTime; + updateItem.Status = dto.Status; + updateItem.Num = dto.Num; + updateItem.Remark = dto.Remark; + updateItem.Utime = DateTime.Now; + await actRepository.UpdateAsync(updateItem); + var delMap = await _zxdRepository.GetRepository().Query().Where(n => n.ActId == dto.Id).ToListAsync(); + await _zxdRepository.GetRepository().BatchDeleteAsync(delMap); + } + else + { + if (string.IsNullOrWhiteSpace(dto.DeptIdList)) + { + throw new Exception("事业部不能为空"); + } + QiWeiActivity qiWeiActivity = new QiWeiActivity() + { + Name = dto.Name, + StartTime = dto.StartTime, + Eid = dto.Eid, + EName = dto.EName, + EndTime = dto.EndTime, + Status = dto.Status, + Num = dto.Num, + Remark = dto.Remark, + Ctime = DateTime.Now, + CompanyCode = dto.CompanyCode, + Order = dto.Order + }; + await actRepository.InsertAsync(qiWeiActivity); + dto.Id = qiWeiActivity.Id; + } + List deptMap = new List(); + var deptList = dto.DeptIdList.Split(',').Select(n => Convert.ToInt32(n)).ToList(); + foreach (var deptid in deptList) + { + QiWeiActivityDept qiWeiActivityDept = new QiWeiActivityDept() + { + ActId = dto.Id.Value, + DeptId = deptid, + Ctime = DateTime.Now + }; + deptMap.Add(qiWeiActivityDept); + } + await _zxdRepository.GetRepository().BatchInsertAsync(deptMap); + await transaction.CommitAsync(); + return true; + } + + public async Task> GetActivityList(ActivityQueryDto dto) + { + if (string.IsNullOrWhiteSpace(dto.DeptIds)) + { + throw new Exception("事业线必填"); + } + var deptIds = dto.DeptIds.Split(',').Select(n => Convert.ToInt32(n)).ToList(); + + var query = from a in _zxdRepository.GetRepository().Query().Include(x => x.QiWeiActivityDept) + .Where(n => true) + .If(dto.Status.HasValue, x => x.Where(m => m.Status == dto.Status)) + .If(!dto.IsCrm.HasValue, x => x.Where(m => m.EndTime == null || m.EndTime >= DateTime.Now)) + .Where(n => n.QiWeiActivityDept.Any(x => deptIds.Contains(x.DeptId))) + .OrderBy(n => n.Order) + select new ActivityModel + { + Id = a.Id, + Name = a.Name, + StartTime = a.StartTime, + EndTime = a.EndTime, + Num = a.Num, + Remark = a.Remark, + Status = a.Status, + EName = a.EName, + Eid = a.Eid, + DeptName = string.Join(",", a.QiWeiActivityDept.Select(n => n.DeptId)) + }; + var total = await query.CountAsync(); + var data = await query.Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + await SetDeptInfo(data); + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + private async Task SetDeptInfo(List model) + { + var deptInfo = await GetDeptMentDto(); + if (deptInfo != null && deptInfo.Count > 0) + { + foreach (var item in model) + { + var deptids = item.DeptName.Split(",").Select(n => Convert.ToInt32(n)).ToList(); + List deptName = new List(); + foreach (var deptid in deptids) + { + var dept = deptInfo.FirstOrDefault(n => n.Id == deptid); + deptName.Add(dept?.Title); + } + item.DeptName = string.Join(",", deptName.Where(n => !string.IsNullOrWhiteSpace(n)).ToList()); + } + } + } + + private async Task> GetDeptMentDto() + { + var key = "deptment_list_new"; + var deptInfo = new List(); + if (await _redisManager.ExistsAsync(key)) + { + deptInfo = await _redisManager.GetListAsync(key); + } + return deptInfo; + } + + public async Task GetEditActivityModel(int Id) + { + ActivityEidtModel res = new ActivityEidtModel(); + var model = await _zxdRepository.GetRepository().Query().Include(x => x.QiWeiActivityDept).FirstOrDefaultAsync(n => n.Id == Id); + if (model != null) + { + res = new ActivityEidtModel() + { + Id = Id, + Name = model.Name, + StartTime = model.StartTime.HasValue ? model.StartTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "", + EndTime = model.EndTime.HasValue ? model.EndTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "", + Num = model.Num, + Remark = model.Remark, + Status = model.Status, + EName = model.EName, + Eid = model.Eid, + Order = model.Order, + DeptIds = string.Join(",", model.QiWeiActivityDept.Select(n => n.DeptId).ToList()) + }; + } + return res; + } + + #endregion 企微侧边栏活动 + + #region 活动产品 + + public async Task CreateActProduct(ActProductCreateDto dto) + { + var actRepository = _zxdRepository.GetRepository(); + var activity = await actRepository.FirstOrDefaultAsync(n => n.Id == dto.ActId && n.Status == 1); + if (activity == null) + { + throw new Exception("找不到相关的活动"); + } + var actProRepository = _zxdRepository.GetRepository(); + if (dto.Id.HasValue && dto.Id > 0) + { + var product = await actProRepository.FirstOrDefaultAsync(n => n.Id == dto.Id); + product.ProductCode = dto.ProductCode; + product.ActId = dto.ActId; + product.IsFirst = dto.IsFirst; + product.Utime = DateTime.Now; + product.Eid = dto.Eid; + product.EName = dto.Ename; + product.Status = dto.Status; + product.Order = dto.Order; + await actProRepository.UpdateAsync(product); + } + else + { + var existModel = await actProRepository.FirstOrDefaultAsync(n => n.ProductCode == dto.ProductCode && n.ActId == dto.ActId); + if (existModel != null) + { + throw new Exception("活动已经存在该产品,请进行编辑!"); + } + QWActivityProduct product = new QWActivityProduct + { + ProductCode = dto.ProductCode, + ActId = dto.ActId, + IsFirst = dto.IsFirst, + Ctime = DateTime.Now, + Eid = dto.Eid, + EName = dto.Ename, + Status = dto.Status, + Order = dto.Order, + }; + await actProRepository.InsertAsync(product); + } + return true; + } + + public async Task> GetActProductList(ActProductQueryDto dto) + { + List deptIds = new List(); + if (!string.IsNullOrWhiteSpace(dto.DeptIds)) + { + deptIds = dto.DeptIds.Split(',').Select(n => Convert.ToInt32(n)).ToList(); + } + + var actProRepository = _zxdRepository.GetRepository(); + var proQuery = _zxdRepository.GetRepository().Query(); + + var query = from a in actProRepository.Query().Include(x => x.QiWeiActivity).ThenInclude(s => s.QiWeiActivityDept) + .Where(n => true) + .If(dto.ActId.HasValue, x => x.Where(m => m.ActId == dto.ActId)) + .If(dto.Status.HasValue, x => x.Where(m => m.Status == dto.Status)) + .If(deptIds.Count > 0, x => x.Where(m => m.QiWeiActivity.QiWeiActivityDept.Any(s => deptIds.Contains(s.DeptId)))) + .If(!string.IsNullOrWhiteSpace(dto.ProductCode), x => x.Where(m => m.ProductCode == dto.ProductCode)) + join b in _zxdRepository.GetRepository().Query() on a.ProductCode equals b.productcode + select new ActProductQueryModel + { + Id = a.Id, + ActId = a.QiWeiActivity.Id, + ActName = a.QiWeiActivity.Name, + Price = b.price, + ProductCode = a.ProductCode, + ProductName = b.subproductname, + IsFirst = a.IsFirst, + Eid = a.Eid, + Ename = a.EName, + Day = b.rightperiod, + Status = a.Status, + Order = a.Order, + callbacklink = b.callbacklink, + buylink = b.buylink + }; + if (!string.IsNullOrWhiteSpace(dto.ProductName)) + { + query = query.Where(n => n.ProductName.Contains(dto.ProductName)); + } + query = query.OrderByDescending(n => n.Id).OrderBy(n => n.Order); + var total = await query.CountAsync(); + var data = await query.Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + var paySetting = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "PayRedirectSetting"); + var set = JsonConvert.DeserializeObject(paySetting.PARAVALUE); + if (!dto.Ch.HasValue) + { + var deptList = await GetDeptMentDto(); + var dept = deptList.FirstOrDefault(n => n.Id == dto.DeptId); + if (dept != null) + { + dto.Ch = dept?.DeptmentCampains?.FirstOrDefault()?.StartCampainId; + } + } + foreach (var item in data) + { + var paramObject = new + { + ch = dto.Ch, + callback = item.callbacklink, + ext = new + { + eid = dto.Eid + } + }; + var param = JsonConvert.SerializeObject(paramObject); + param = SecurityHelper.EncyptData(param, "upchina3"); + item.PayLink = string.Format("{0}/{1}?ch={2}&uname=¶m={3}&isWeb=true", set.ThreeUrl, string.IsNullOrEmpty(item.buylink) ? "" : item.buylink.Replace("unifiedpay/", ""), dto.Ch, param); + } + var result = _mapper.Map(data); + return new PageResult(dto.PageIndex, dto.PageSize, total, result); + } + + public async Task GetProductEditModel(ProductEditQueryDto dto) + { + if (string.IsNullOrWhiteSpace(dto.CompanyCode)) + { + throw new Exception("事业线必填"); + } + ProductEditModel res = new ProductEditModel(); + if (dto.Id > 0) + { + var pro = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.Id == dto.Id); + + res.QWActivityProduct = new ActProductModel + { + Id = pro.Id, + ActId = pro.ActId, + ProductCode = pro.ProductCode, + IsFirst = pro.IsFirst, + Status = pro.Status, + Order = pro.Order, + }; + } + var query = from a in _zxdRepository.GetRepository().Query() + .Where(n => n.companycode == dto.CompanyCode && n.isValid == 1) + join b in _zxdRepository.GetRepository().Query().Where(n => n.isonlinebuy != null) on a.subproductid equals b.subproductid + select new ActProductModel + { + Price = b.price, + ProductCode = b.productcode, + ProductName = b.subproductname, + Day = b.rightperiod, + }; + res.ActProducts = query.Distinct().ToList(); + var actRepository = _zxdRepository.GetRepository(); + var actList = await actRepository.Query().Where(n => n.Status == 1 && n.CompanyCode == dto.CompanyCode && (n.EndTime == null || n.EndTime >= DateTime.Now)) + .Select(n => new ActivityModel { Id = n.Id, Name = n.Name }) + .ToListAsync(); + res.ActList = actList; + return res; + } + + /// + /// 获取产品价格期限 在线支付链接 + /// + /// + /// + public async Task GetProductInfo(ProductInfoQueryDto dto) + { + var pro = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.productcode == dto.Code); + if (pro == null) + { + throw new Exception("找不到对应的产品"); + } + var paySetting = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n => n.PARAKEY == "PayRedirectSetting"); + var set = JsonConvert.DeserializeObject(paySetting.PARAVALUE); + + ProductInfo res = new ProductInfo() + { + ProductCode = pro.productcode, + ProductName = pro.subproductname, + Day = pro.rightperiod, + Price = pro.price, + }; + if (!dto.Ch.HasValue) + { + var deptList = await GetDeptMentDto(); + var dept = deptList.FirstOrDefault(n => n.Id == dto.DeptId); + if (dept != null) + { + dto.Ch = dept?.DeptmentCampains?.FirstOrDefault()?.StartCampainId; + } + } + if (dto.Ch.HasValue) + { + var paramObject = new + { + ch = dto.Ch, + callback = pro.callbacklink, + ext = new + { + eid = dto.Eid + } + }; + var param = JsonConvert.SerializeObject(paramObject); + param = SecurityHelper.EncyptData(param, "upchina3"); + res.PayLink = string.Format("{0}/{1}?ch={2}&uname=¶m={3}&isWeb=true", set.ThreeUrl, string.IsNullOrEmpty(pro.buylink) ? "" : pro.buylink.Replace("unifiedpay/", ""), dto.Ch, param); + } + return res; + } + + public async Task DelActProduct(DelActProductModel dto) + { + if (string.IsNullOrWhiteSpace(dto.Ids)) + { + throw new Exception("找不到对应的活动产品"); + } + var ids = dto.Ids.Split(',').Select(n => Convert.ToInt32(n)).ToList(); + var proList = await _zxdRepository.GetRepository().Query().Where(n => ids.Contains(n.Id)).ToListAsync(); + await _zxdRepository.GetRepository().BatchDeleteAsync(proList); + return true; + } + + #endregion 活动产品 + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/SSOEmployeeDomain.cs b/code/Zxd.Crm.Domain/SSOEmployeeDomain.cs new file mode 100644 index 0000000..d457514 --- /dev/null +++ b/code/Zxd.Crm.Domain/SSOEmployeeDomain.cs @@ -0,0 +1,945 @@ +using DG.EntityFramework; +using Exceptionless.Models; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; +using Serilog; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Numerics; +using System.Reflection.Emit; +using System.Security.Cryptography; +using System.Security.Cryptography.Xml; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using WX.CRM.Common.Employee; +using Zxd.Core.Shared.Dto; +using Zxd.Core.Shared.Helpers; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; +using Zxd.Domain.Config; +using Zxd.Entity.SSO; +using Zxd.Entity.Zxd; +using Zxd.EntityFramework; +using DeptmentDto = Zxd.Crm.Domain.Dto.DeptmentDto; +using Employee = Zxd.Entity.SSO.Employee; + +namespace Zxd.Crm.Domain +{ + public class SSOEmployeeDomain : ISSOEmployeeDomain + { + private readonly IConfiguration _configuration; + private readonly ICacheDomain _cacheDomain; + private readonly IBaseRepository _repository; + private readonly IBaseRepository _zxdRepository; + private readonly IServiceProvider _serviceProvider; + + public SSOEmployeeDomain(IConfiguration configuration, ICacheDomain cacheDomain, IBaseRepository repository, IBaseRepository zxdRepository, IServiceProvider serviceProvider) + { + _configuration = configuration; + _cacheDomain = cacheDomain; + _repository = repository; + _zxdRepository = zxdRepository; + _serviceProvider = serviceProvider; + } + + /// + /// 记录员工软件用户字典 + /// + /// + /// + public async Task> SetEmployeeSoftDict(EMPLOYEE_SOFT_DICT data) + { + try + { + var existModel = await _zxdRepository.GetRepository().FirstOrDefaultAsync(n => n.eid == data.eid && n.resid == data.resid && n.appusername == data.appusername); + if (existModel == null) + { + await _zxdRepository.GetRepository().InsertAsync(data); + } + } + catch (Exception ex) + { + Log.Error($"记录员工软件用户字典失败:{ex.ToString()}"); + return new ApiResult { Code = 0, Data = false, Message = "记录员工软件用户字典失败" }; + } + return new ApiResult { Code = 0, Data = false, Message = "记录员工软件用户字典成功" }; + } + + public async Task> GetEmpowerment(GetEmpowermentByAppidDto dto) + { + var resList = new List(); + int count; + try + { + var appid = dto.appid; + + var eidsByBusinessLine = new List(); + + if (appid == null || appid == "") return new PageResult(dto.PageIndex, dto.PageSize, 0, resList); + + // 员工数据 + var employeeList = _zxdRepository.GetRepository().Query().Where(e => e.is_deleted != 1 && (e.status == 1 || e.status == 3)); + + //employeeList = employeeList.Where(e => e.appid == appid); + // 筛选条件 + // 筛选员工id + if (dto.eid != null || dto.userId != null) + { + employeeList = employeeList.Where(e => (dto.eid != null && e.employee_id == dto.eid) || (dto.userId != null && e.id == dto.userId)); + }; + // 筛选事业部 + if (dto.deptId != null) + { + eidsByBusinessLine = await _zxdRepository.GetRepository().Query().Where(d => d.department_id == (int)dto.deptId).Select(s => (int)s.eid).ToListAsync(); + + employeeList = employeeList.Where(e => eidsByBusinessLine.Contains((int)e.employee_id)); + } + // 筛选姓名 + if (dto.name != null && dto.name != "") + { + employeeList = employeeList.Where(e => e.employee_name.Contains(dto.name)); + } + // 员工软件用户数据 + var softEmployeeBindList = _zxdRepository.GetRepository().Query().Where(w => employeeList.FirstOrDefault(f => f.employee_id == w.eid) != null); + //var softuserList = _zxdRepository.GetRepository().Query().Where(s => s.RESID != null && s.RESID != "" && softEmployeeBindList.FirstOrDefault(so => so.resid == s.RESID) != null); + // 根据resid分类,并获取创建时间最新的软件账号再转成字典 + //var softTemp = softuserList.AsEnumerable().GroupBy(m => m.RESID).Select(s => s.OrderByDescending(g => g.CTIME).FirstOrDefault()).ToList(); + //var softDict = softTemp.ToDictionary(soft => soft.RESID == null ? "" : soft.RESID, soft => soft.USERNAME == null ? "" : soft.USERNAME); + // 获取员工绑定数据 + + var resQuery = from bind in softEmployeeBindList + join employee in employeeList on bind.eid equals employee.employee_id + join ef in _zxdRepository.GetRepository().Query() on bind.eid equals ef.eid into tmpef + from ef in tmpef.DefaultIfEmpty() + join a in _zxdRepository.GetRepository().Query() on bind.resid equals a.RESID into tmpAB + from a in tmpAB.DefaultIfEmpty() + //join soft in softuserList on bind.resid equals soft.RESID into softRes + //from res in softRes.DefaultIfEmpty() + where ef.appid == appid + orderby bind.eid + select + new GetEmpowermentDto + { + employee_id = bind.eid, + employee_name = employee.employee_name, + showPhone = bind.show_phone, + phone = bind.show_phone, + resid = bind.resid, + umid = a.UMID, + is_main = bind.is_main, + last_empower_time = bind.last_empower_time, + appusername = bind.appusername, + } + ; + + resQuery = resQuery.If(!string.IsNullOrEmpty(dto.umid), x => x.Where(x => x.umid == dto.umid)); + count = resQuery.Count(); + var bindList = resQuery.Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize); + + resList = await bindList.ToListAsync(); + //resList.ForEach(resItem => + //{ + // string value; + // softDict.TryGetValue(resItem.resid, out value); + // resItem.appusername = value; + //}); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + throw new ApiException($"获取数据失败:{ex}"); + } + return new PageResult(dto.PageIndex, dto.PageSize, count, resList); + } + + public class softRes + { + public string username { get; set; } + public DateTime createdTime { get; set; } + } + + public List getDeptment() + { + List departmentList = new List(); + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var url = systemConfig.GetDeptsUrl(); + var req = HttpHelper.GetData(url, "", Encoding.UTF8); + var resModel = JsonHelper.FromJson>>(req); + if (resModel.Code == 0) + { + departmentList = resModel.Data.ToList(); + //departmentList = resModel.Data.Where(d => d.Appid == appid).ToList(); + } + return departmentList; + } + + public class TempMapForDeptidAppid + { + public int deptId { get; set; } + public string appId { get; set; } + } + + // 递归出坐席id + public string? FindDepartment(int id, List departmap, List SSODeptsList) + { + // 当层递归的部门id + var curDept = SSODeptsList.FirstOrDefault(d => d.id == id); + // 当层部门id对应的坐席id + var curMap = departmap.FirstOrDefault(de => de.department_id == id); + // 没有更上层,不需要递归,直接返回结果 + if (curDept.parent_id == null) return curMap == null ? null : curMap.AppId; + if (curMap == null) + { + // 没找到坐席id,进入递归 + return FindDepartment((int)curDept.parent_id, departmap, SSODeptsList); + } + else + { + return curMap.AppId; + } + } + + // 清空备份表 + public async Task ClearZxdEmpolyee() + { + try + { + var employeeList = _zxdRepository.GetRepository().Query().ToList(); + await _zxdRepository.GetRepository().BatchDeleteAsync(employeeList); + return true; + } + catch (Exception ex) + { + Log.Error("清空备份表失败:" + ex.Message); + return false; + } + } + + public async Task BindSoftUserInit() + { + try + { + // 拿绑定表的数据,调用 UpdateAppusername 接口 + //var bindList = _zxdRepository.GetRepository().Query().Select(s => new Appuser { eid = s.eid, resid = s.resid }).ToList(); + //var dto = new UpdateAppusernameDto { UpdateAppusernameList = bindList }; + + await UpdateAppusername(); + Log.Information("绑定数据初始化软件用户数据结束"); + return true; + } + catch (Exception ex) + { + Log.Error("绑定数据初始化软件用户数据失败:" + ex.Message); + return false; + } + } + + public async Task SSOBindDataInit() + { + try + { + //var phoneResids = await _zxdRepository.GetRepository().Query().Where(x => !string.IsNullOrEmpty(x.phone_resid)).Select(x => x.phone_resid).Distinct().ToListAsync(); + + //var softuserList = await _zxdRepository.GetRepository().Query().Where(s => phoneResids.Contains(s.RESID)).ToListAsync(); + + var date = new DateTime(2023, 9, 5, 17, 00, 00); + //todo 把empolyee_phone_bind表的数据拉出来循环调用 更新软件用户名数据接口 + var wx_empower_log = await _zxdRepository.GetRepository().Query() + .Where(w => w.created_time < date) + .GroupBy(g => new { g.to_by_eid, g.softusername, g.appid }) + .Select(x => new { x.Key.to_by_eid, x.Key.softusername, x.Key.appid, x.First().from_by_eid }) + .Select(s => s).ToListAsync(); + + var appDict = new Dictionary() { + {"asset_h5","b+eki574sYoyNaWIsHhJj2j3I0hvqjAsMb3ts3nTxmc="}, + {"cms_dg","2XPMELRrlzH7kOeR/QTJCA8ltRk4kmvTaB/y7WczZe4="}, + {"crm_app_10000","gzymZTnIcdxM2TugT8p00jIvZWP5VneiimYUyIbw5Hk="}, + {"crm_d1d2_dnzz","tXxYuzU3H9Wki0Qh5HhxVnBKg9kbqIYGyxGqgtbPljc="}, + {"crm_d3_dnyy","3gy2vCskdrpPziFykGKNmeTkyKGCitgGPO7q5qIvmfs="}, + {"crm_df_yypt","TYd8USnG3yKFuW/hFigwxfMpzygMEmfZYNewXdJVaU4="}, + {"crm_hq","dgk42zepqMGn0vr5YeHxtSgpc/sAZjow3WYz0ugDHdg="}, + {"crm_pt_ptd2","VQcggIYFw7wAsi4OTRXBn1x9N0f/95ricnCjJbHDys4="}, + {"crm_tg_dnbb","N0e44dEIA0hQwOOATZu/bij55N0fD0CNAA9IsisCZeM="}, + {"crm_tg_dng8","17D4xLHTFQbRrMchTr4Dd5RcUyn4WbJda+MarKTlw78="}, + {"decision_making_system","kegsfgECmohd2Qxq1fojbQ+RkS4THNtVRWeHLXW6ADA="}, + {"dg_tgzt","nboMi57qEqGv95+3W13lSN31YTOBlirG8m0RWlyNi6A="}, + {"qt_compliance","AdC+vVj58wG48swyjyW2WM6aC6CxYNKt8pP0c8sdozs="}, + {"qt_core","uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk="}, + }; + + #region 单例 + + //string AppId = "crm_tg_dng8";//坐席的appid + //string Secret = "+P44LokNo+1mdWxu6V/DhpdlA7z+EvHHEinxZ3WKI24=";//坐席的appid的密钥 + //ApiDockHelper dock = new ApiDockHelper(AppId, Secret); + //Dictionary dic = new Dictionary(); + //dic.Add("employeeId", 132015); + //dic.Add("account", "dn0003774"); + //dic.Add("operator", 132015); + //dic.Add("reason", "初始化数据"); + //var ssoUrl = "https://conf.soft.dn8188.com"; + //ssoUrl = "http://192.168.11.141:24434"; + + //ApiResultTemp model = dock.PostApi(ssoUrl + "/v1/api/open/employee/ip/add", dic); + + #endregion 单例 + + foreach (var log in wx_empower_log) + { + Log.Information($"推送SSO数据:to_by_eid={log.to_by_eid};softusername={log.softusername};from_by_eid={log.from_by_eid};appid={log.appid}"); + string appid = log.appid;//坐席的appid + string secret = appDict[log.appid];//坐席的appid的密钥 + ApiDockHelper dock = new ApiDockHelper(appid, secret); + Dictionary dic = new() + { + { "employeeid", log.to_by_eid }, + { "account", log.softusername }, + { "operator", log.from_by_eid }, + { "reason", "初始化数据" } + }; + var ssourl = "https://conf.soft.dn8188.com"; + //ssourl = "http://192.168.11.141:24434"; + + ApiResultTemp model = dock.PostApi(ssourl + "/v1/api/open/employee/ip/add", dic); + if (model.ret != 0) + { + Log.Error("sso_推送错误:" + model.ToJson()); + } + } + Log.Information("推送SSO数据结束"); + return true; + } + catch (Exception ex) + { + Log.Error("推送SSO数据失败:" + ex.Message); + return false; + } + } + + /// + /// 增加员工软件用户的绑定数据日志 + /// + /// 被操作员工id + /// 资源id + /// 操作类型 bind: 绑定或更新 unbind 解绑 + /// 操作员工id + /// + /// + public async Task> AddSoftEmployeeBindLog(int to_by_eid, string resid, string type, int from_by_eid) + { + #region 绑定日志 + + try + { + var softEmployeeBindLog = _zxdRepository.GetRepository(); + + // 绑定或解绑日志 + await softEmployeeBindLog.InsertAsync(new EMPLOYEE_PHONE_BIND_LOG + { + from_by_eid = from_by_eid, + createtime = DateTime.Now, + type = type, + resid = resid, + to_by_eid = to_by_eid + }); + } + catch (Exception ex) + { + Log.Error("埋点失败" + ex.ToString()); + return new ApiResult { Code = -1, Data = false, Message = "埋点失败" }; + } + + #endregion 绑定日志 + + return new ApiResult { Code = 0, Data = false, Message = "埋点成功" }; + } + + /// + /// 解绑员工软件用户的绑定数据 + /// + /// 被操作员工id + /// 资源id + /// 脱敏后电话 + /// 操作员工id + /// 是否为主账号 + /// + /// + public async Task> DeleteSoftEmployeeBind(int to_by_eid, string resid, string show_phone, int from_by_eid) + { + try + { + var softEmployeeBind = _zxdRepository.GetRepository(); + + var Appuser = await softEmployeeBind.Query().FirstOrDefaultAsync(f => to_by_eid == f.eid && resid == f.resid); + // 删除不存在的数据,或删除主账号,直接返回 + if (Appuser == null) return new ApiResult { Code = -1, Data = false, Message = "不存在该用户,无法解绑" }; + if (Appuser.is_main == 1) return new ApiResult { Code = -1, Data = false, Message = "无法解绑主用户" }; + await softEmployeeBind.DeleteAsync(Appuser); + } + catch (Exception ex) + { + Log.Error("解绑失败" + ex.ToString()); + return new ApiResult { Code = -1, Data = false, Message = "解绑失败" }; + } + var logRes = await AddSoftEmployeeBindLog(to_by_eid, resid, "unbind", from_by_eid); + if (logRes.Code != 0) + { + return new ApiResult { Code = 0, Data = false, Message = "解绑成功,但埋点失败" }; + } + return new ApiResult { Code = 0, Data = false, Message = "解绑成功" }; + } + + /// + /// 增加员工软件用户的绑定数据 + /// + /// 被操作员工id + /// 资源id + /// 脱敏后电话 + /// 操作员工id + /// 是否为主账号 + /// + public async Task> AddSoftEmployeeBind(int to_by_eid, string resid, string show_phone, int from_by_eid, int is_main = 0) + { + try + { + var softEmployeeBind = _zxdRepository.GetRepository(); + var count = await softEmployeeBind.Query().Where(b => b.eid == to_by_eid).CountAsync(); + + var limit = await _cacheDomain.GetValueParameter("EmployeePhoneBindLimit"); + limit = limit == "" || limit == null ? "3" : limit; + // todo 从参数里拿限制个数 + if (count >= int.Parse(limit)) return new ApiResult { Code = -1, Data = false, Message = $"员工绑定电话已经达上限,不能超过{limit}个!" }; + var Appuser = await softEmployeeBind.Query().FirstOrDefaultAsync(f => to_by_eid == f.eid && resid == f.resid); + //if (await softEmployeeBind.Query().FirstOrDefaultAsync(f => resid == f.resid) != null) return new ApiResult { Code = -1, Data = false, Message = "该电话已经被绑定,不能重复绑定" }; + + #region 更新员工的软件账号(目前只有主账号会被更新) + + if (is_main == 1) + { + Appuser = await softEmployeeBind.Query().FirstOrDefaultAsync(f => to_by_eid == f.eid && f.is_main == 1); + } + if (Appuser != null && is_main == 1) + { + Appuser.resid = resid; + Appuser.show_phone = show_phone; + await softEmployeeBind.UpdateAsync(Appuser); + } + + #endregion 更新员工的软件账号(目前只有主账号会被更新) + + else if (Appuser == null) + { + #region 绑定 + + await softEmployeeBind.InsertAsync(new EMPLOYEE_PHONE_BIND + { + eid = to_by_eid, + resid = resid, + show_phone = show_phone, + is_main = is_main + }); + + #endregion 绑定 + } + var softuser = await _zxdRepository.GetRepository().Query().FirstOrDefaultAsync(n=>n.RESID == resid); + if(softuser != null) + { + await SetEmployeeSoftDict(new EMPLOYEE_SOFT_DICT + { + appusername = softuser.USERNAME, + eid = to_by_eid, + resid = resid, + }); + } + + } + catch (Exception ex) + { + Log.Error("绑定失败" + ex.ToString()); + return new ApiResult { Code = -1, Data = false, Message = "绑定失败" }; + } + var logRes = await AddSoftEmployeeBindLog(to_by_eid, resid, "bind", from_by_eid); + if (logRes.Code != 0) + { + return new ApiResult { Code = 0, Data = false, Message = "绑定成功,但埋点失败" }; + } + return new ApiResult { Code = 0, Data = false, Message = "绑定成功" }; + } + + public async Task AsyncEmplyeeData(string eid) + { + var eids = eid.Split(',').Select(x => int.Parse(x)).ToList(); + var users = await _repository.GetRepository().Query().Where(x => eids.Contains(x.employee_id.Value)) + .ToListAsync(); + foreach (var user in users) + { + await AddSoftEmployeeBind((int)user.employee_id, user.phone_resid, user.phone, 10000, 1); + } + } + + // 从SSO同步员工数据到【中心点】的员工表 + public async Task AsyncEmplyeeData() + { + try + { + // 中心点的员工数据 + var employeeList = _zxdRepository.GetRepository().Query().OrderByDescending(o => o.update_time).ToList(); + // 员工电话绑定表 + var softEmployeeBind = _zxdRepository.GetRepository(); + var SSOUserList = new List(); + if (employeeList.Count != 0) + { + var lastFlag = employeeList.FirstOrDefault(); + Log.Information($"同步表最新时间:{lastFlag.update_time}"); + // SSO的员工数据 + SSOUserList = _repository.GetRepository().Query().Where(s => s.update_time > lastFlag.update_time).ToList(); + } + else + { + SSOUserList = _repository.GetRepository().Query().ToList(); + } + + if (SSOUserList.Count == 0) + { + return true; + } + // SSO的部门数据 + var SSODeptsList = _repository.GetRepository().Query().ToList(); + // 软件用户表 + var softuserList = _zxdRepository.GetRepository().Query().ToList(); + // 坐席对应部门表 + var departmap = _repository.GetRepository().Query().ToList(); + // 员工部门关系表 + var employeeDept = _repository.GetRepository().Query().Where(e => e.is_deleted != 1).ToList(); + // 部门id和坐席id对照临时表 + var tempMapForDeptidAppid = new List(); + // 生成对照表数据 + SSODeptsList.ForEach(D => + { + var appid = FindDepartment(D.id, departmap, SSODeptsList); + tempMapForDeptidAppid.Add(new TempMapForDeptidAppid { deptId = D.id, appId = appid }); + }); + + #region 员工备份表同步逻辑 + + // 如果在【中心点】能找到对应员工id,并且更新时间不一致,则更新 + // 如果在【中心点】没找到对应员工id,则新增 + foreach (var SSOUser in SSOUserList) + { + Log.Information($"需要同步的员工:{SSOUser.employee_id}"); + var ZXDUser = employeeList.FirstOrDefault(z => z.employee_id == SSOUser.employee_id); + var ophone = SSOUser != null ? SSOUser.phone : "";// 原始电话号码 + var resid = ""; + var phone = "";// 加密电话号码 + var showPhone = "";// 屏蔽中间五个数字后的电话号码 + var appusername = ""; // 软件用户名 + var currDept = employeeDept.Where(em => em.employee_id == SSOUser.id).OrderByDescending(em2 => em2.department_id).FirstOrDefault(); + + string? appid = null; + if (currDept != null) + { + var tappid = tempMapForDeptidAppid.FirstOrDefault(map => map.deptId == currDept.department_id)?.appId; + appid = tappid; + }; + if (SSOUser.phone_resid != "" && SSOUser.phone_resid != null) + { + resid = SSOUser.phone_resid; + appusername = softuserList.FirstOrDefault(s => s.RESID == resid) is null ? "" : softuserList.FirstOrDefault(s => s.RESID == resid).USERNAME; + } + // 把已经删除的员工账号剔除出绑定表 + if (SSOUser.is_deleted == 1) + { + var Appuser = await softEmployeeBind.Query().Where(f => f.eid == SSOUser.employee_id).ToListAsync(); + if (Appuser.Count != 0) + { + await softEmployeeBind.BatchDeleteAsync(Appuser); + } + } + else + { + // 同步该员工绑定主账号 + await AddSoftEmployeeBind((int)SSOUser.employee_id, resid, ophone, 10000, 1); + await SetEmployeeSoftDict(new EMPLOYEE_SOFT_DICT + { + appusername = appusername, + eid = (int)SSOUser.employee_id, + resid = resid, + }); + } + + if ((ZXDUser != null && ZXDUser.update_time != SSOUser.update_time)) + { + // 更新 + ZXDUser.employee_id = SSOUser.employee_id; + ZXDUser.status = SSOUser.status; + ZXDUser.employee_name = SSOUser.employee_name; + ZXDUser.is_deleted = SSOUser.is_deleted; + ZXDUser.update_time = SSOUser.update_time; + ZXDUser.create_time = SSOUser.create_time; + ZXDUser.phone = ophone; + ZXDUser.showPhone = ophone; + ZXDUser.appid = appid; + ZXDUser.phone_resid = resid; + await _zxdRepository.GetRepository().UpdateAsync(ZXDUser); + } + else if (ZXDUser == null) + { + // 新增 + await _zxdRepository.GetRepository().InsertAsync(new Entity.Zxd.Employee + { + id = SSOUser.id, + employee_id = SSOUser.employee_id, + employee_name = SSOUser.employee_name, + is_deleted = SSOUser.is_deleted, + update_time = SSOUser.update_time, + create_time = SSOUser.create_time, + status = SSOUser.status, + phone = ophone, + showPhone = ophone, + appid = appid, + phone_resid = resid + }); + } + + #endregion 员工备份表同步逻辑 + } + } + catch (Exception ex) + { + Log.Error($"同步报错:{ex.ToString()}"); + //return false; + } + Log.Information("同步成功"); + return true; + } + + /// + /// 替换手机号中间五位为* + /// + /// + /// + public string ReturnPhoneNO(string phoneNo) + { + Regex re = new Regex(@"(\d{3})(\d{5})(\d{3})", RegexOptions.None); //构造手机号的正则表达式 将其分为三组分别为3、4、4个数字 + phoneNo = re.Replace(phoneNo, "$1*****$3");//保留第一组和第三组 用"*****"替换第二组 + return phoneNo; + } + + public async Task> GetDeptmentByEid(string? eidList) + { + List res = new List(); + if (string.IsNullOrWhiteSpace(eidList)) + { + throw new Exception("参数不能为空"); + } + var deptList = await _cacheDomain.GetDeptMapList(); + var filterEid = eidList.Split(",").Where(n => !string.IsNullOrWhiteSpace(n)).ToList(); + var hasValueList = deptList.Where(n => filterEid.Contains(n.Eid)).ToList(); + if (hasValueList.Count > 0) + { + res.AddRange(hasValueList); + } + filterEid = filterEid.Where(n => !hasValueList.Select(s => s.Eid).Contains(n)).ToList(); + if (filterEid.Count == 0) + { + return hasValueList; + } + var userList = _repository.GetRepository().Query().Where(n => filterEid.Contains(Convert.ToString(n.employee_id)) && n.is_deleted == 0).ToList(); + var departmentsList = _repository.GetRepository().Query().Where(n => n.is_deleted == 0).ToList(); + var employeeDept = _repository.GetRepository().Query().Where(p => userList.Select(n => n.id).Contains(p.employee_id.Value) && p.is_deleted == 0).ToList(); + var departments = departmentsList.Where(p => employeeDept.Select(n => n.department_id).Contains(p.id) && p.is_deleted == 0).ToList(); + var departmap = _repository.GetRepository().Query().ToList(); + var mapquery = from n in userList + join b in employeeDept + on n.id equals b.employee_id + join c in departments + on b.department_id equals c.id + select new DeptMentReturnModel + { + Eid = n.employee_id.ToString(), + DeptId = c.id, + DeptName = c.department_name + }; + var mapList = mapquery.ToList(); + var hasChange = false; + foreach (var eid in filterEid) + { + var map = deptList.FirstOrDefault(n => n.Eid == eid); + if (map == null) + { + var item = mapList.FirstOrDefault(n => n.Eid == eid); + if (item != null) + { + var deptItem = departmentsList.FirstOrDefault(n => n.id == item.DeptId); + var config = BuildParentDept(deptItem, departmentsList, departmap); + if (config != null) + { + var mapItem = departmentsList.FirstOrDefault(n => n.id == config.department_id); + hasChange = true; + map = new DeptMentReturnModel + { + Eid = item.Eid, + DeptId = mapItem?.id, + DeptName = mapItem?.department_name, + AppId = config.AppId, + CompanyCode = config.CompanyCode, + SaleDeptId = config.SaleDeptId + }; + res.Add(map); + deptList.Add(map); + } + } + else + { + map = new DeptMentReturnModel + { + Eid = eid, + DeptId = 0, + DeptName = "" + }; + deptList.Add(map); + hasChange = true; + } + } + } + //重新塞进缓存 + if (hasChange) + { + await _cacheDomain.AddDeptMapInfo(deptList); + } + return res; + } + + public async Task RemoveEidCache(string? eidList) + { + if (string.IsNullOrEmpty(eidList)) + { + await _cacheDomain.UpdateDeptMapInfo(new List()); + return true; + } + var deptList = await _cacheDomain.GetDeptMapList(); + var filterEid = eidList.Split(",").ToList(); + var hasValueList = deptList.Where(n => !filterEid.Contains(n.Eid)).ToList(); + await _cacheDomain.UpdateDeptMapInfo(hasValueList); + return true; + } + + /// + /// 通过员工id获取软件用户名 + /// + /// 员工id + /// + /// + public async Task>> GetAppuserByEid(int eid) + { + try + { + // 员工软件账号绑定表 + var softEmployeeBind = _zxdRepository.GetRepository().Query().Where(e => e.eid == eid); + var appuserQuery = await _zxdRepository.GetRepository().Query().Where(e => softEmployeeBind.FirstOrDefault(f => f.resid == e.RESID) != null && e.USERNAME != "" && e.USERNAME != null).Select(s => s.USERNAME).ToListAsync(); + var appuserBind = await _zxdRepository.GetRepository().Query().Where(e => e.eid == eid).Select(s => s.appusername).ToListAsync(); + var res = appuserQuery.Union(appuserBind).ToList(); + return new ApiResult> { Code = 0, Data = res, Message = "获取成功" }; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + Log.Error("通过员工id获取软件用户名获取失败" + ex.ToString()); + return new ApiResult> { Code = -1, Data = new List(), Message = "获取失败" }; + } + } + + // 更新【授权日志】 + // 虽然这里可以批量添加,但是绝大数情况下,都是单个添加 + public async Task> SetEmpowerment(SetEmpowermentDto dto) + { + try + { + //SetEmpowermentDto + var EmployeeList = dto.EmployeeList; + var productIdList = dto.ProductList; + var employeeSoftDict = _zxdRepository.GetRepository().Query(); + + #region 更新最新赋权时间 + + var residList = String.Join(';', EmployeeList.Select(e => e.resid).ToList()); + await UpdateLastEmpowerTime(residList); + + #endregion 更新最新赋权时间 + + for (var eIndex = 0; eIndex < EmployeeList.Count; eIndex++) + { + var curEmployee = EmployeeList[eIndex]; + + #region 判断是否需要增加【员工 软件用户】字典数据 + + if (employeeSoftDict.FirstOrDefault(f => f.eid == curEmployee.employee_id && f.resid == curEmployee.resid && f.appusername == curEmployee.softusername) == null) + { + await SetEmployeeSoftDict(new EMPLOYEE_SOFT_DICT + { + appusername = curEmployee.softusername, + eid = curEmployee.employee_id, + resid = curEmployee.resid, + }); + } + + #endregion 判断是否需要增加【员工 软件用户】字典数据 + + for (var pIndex = 0; pIndex < productIdList.Count; pIndex++) + { + var curPro = productIdList[pIndex]; + var endtime = DateTime.Now.AddDays(dto.duration); + + await _zxdRepository.GetRepository().InsertAsync(new Entity.Zxd.WX_EMPOWER_LOG + { + to_by_resid = curEmployee.resid, + from_by_eid = dto.fromByEid, + to_by_eid = curEmployee.employee_id, + type = 1, + created_time = DateTime.Now, + duration = dto.duration, + product_name = curPro.subproductname, + product_id = curPro.subproductid, + order_id = dto.orderid, + appid = dto.appid, + softusername = curEmployee.softusername, + }); + } + } + } + catch (Exception ex) + { + return new ApiResult { Code = -1, Data = false, Message = "添加失败" }; + } + return new ApiResult { Code = 0, Data = true, Message = "添加成功" }; + } + + // 更新员工电话绑定表的软件用户数据 + public async Task> UpdateAppusername(List UpdateAppusernameList = null) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var zxdRepository = scope.ServiceProvider.GetRequiredService>(); + var list = new List(); + if (UpdateAppusernameList == null) + { + list = await zxdRepository.GetRepository().Query().Where(item => !string.IsNullOrEmpty(item.resid)).ToListAsync(); + } + else + { + var resids = UpdateAppusernameList.Select(x => x.resid); + var eids = UpdateAppusernameList.Select(x => x.eid); + list = await zxdRepository.GetRepository().Query().Where(x => resids.Contains(x.resid) && eids.Contains(x.eid)).Where(item => !string.IsNullOrEmpty(item.resid)).ToListAsync(); + } + using var transaction = await zxdRepository.BeginTransactionAsync(); + try + { + var needUpdateList = new List(); + foreach (var item in list) + { + // 软件用户 + var softuser = await zxdRepository.GetRepository().Query() + .Where(s => s.RESID != null && s.RESID != "" && s.RESID == item.resid) + .OrderByDescending(g => g.CTIME).FirstOrDefaultAsync(); + + // 员工电话绑定 + //var softuser = softuserList.FirstOrDefault(f => f.RESID == item.resid); + //var softEmployee = softEmployeeBind.FirstOrDefault(f => f.resid == item.resid && f.eid == item.eid); + if (softuser != null && item != null && softuser.USERNAME != item.appusername) + { + item.appusername = softuser.USERNAME; + needUpdateList.Add(item); + } + if (softuser != null) + { + await SetEmployeeSoftDict(new EMPLOYEE_SOFT_DICT + { + appusername = item.appusername, + eid = (int)item.eid, + resid = item.resid, + }); + } + } + await zxdRepository.GetRepository().BatchUpdateAsync(needUpdateList, x => new { x.appusername }); + + await transaction.CommitAsync(); + } + catch (Exception ex) + { + await transaction.DisposeAsync(); + await transaction.RollbackAsync(); + Log.Error("更新软件用户数据失败:" + ex.ToString()); + return new ApiResult { Code = -1, Data = "", Message = "更新失败" }; + } + return new ApiResult { Code = 0, Data = "", Message = "更新成功" }; + } + + public class Appuser + { + public int id { get; set; } + public int eid { get; set; } + public string resid { get; set; } + } + + public class UpdateAppusernameDto + { + public List UpdateAppusernameList { get; set; } + } + + // 更新上次赋权时间 + public async Task> UpdateLastEmpowerTime(string residString, long? timestamp = null) + { + var empower_time = DateTime.Now; + try + { + if (timestamp != null) + { + empower_time = Utility.ConvertStringToDateTime(timestamp.ToString()); + } + var residList = residString.Split(";"); + var query = _zxdRepository.GetRepository().Query(); + foreach (var resid in residList) + { + var curBindList = await query.Where(w => w.resid == resid && w.last_empower_time != empower_time).ToListAsync(); + foreach (var curBind in curBindList) + { + curBind.last_empower_time = empower_time; + } + await _zxdRepository.GetRepository().BatchUpdateAsync(curBindList); + } + } + catch (Exception ex) + { + Log.Error("更新上次赋权时间失败:" + ex.ToString()); + return new ApiResult { Code = -1, Data = "", Message = "更新失败" }; + } + return new ApiResult { Code = 0, Data = empower_time.ToString(), Message = "更新成功" }; + } + + public DepartmentCrmConf BuildParentDept(Department dept, List deptList, List mapList) + { + if (dept != null) + { + var map = mapList.FirstOrDefault(n => n.department_id == dept.id); + if (map != null) + { + return map; + } + if (dept.parent_id.HasValue) + { + var parDept = deptList.FirstOrDefault(n => n.id == dept.parent_id); + return BuildParentDept(parDept, deptList, mapList); + } + } + return null; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/UserInfoDomain.cs b/code/Zxd.Crm.Domain/UserInfoDomain.cs new file mode 100644 index 0000000..d6f7dd0 --- /dev/null +++ b/code/Zxd.Crm.Domain/UserInfoDomain.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.UserCenter; + +namespace Zxd.Crm.Domain +{ + internal class UserInfoDomain : IUserInfoDomain + { + private readonly IRedisManager _redisManager; + private readonly IBaseRepository _userCenterRepository; + + public UserInfoDomain(IRedisManager redisManager, + IBaseRepository userCenterRepository) + { + _redisManager = redisManager; + _userCenterRepository = userCenterRepository; + } + + public async Task GetUserInfo(string? appid, string? appuserid) + { + var userinfos = await _userCenterRepository.GetRepository().Query() + .Where(x => x.Appid == appid && x.Appuserid == appuserid) + .ToListAsync(); + if (userinfos == null || !userinfos.Any()) + { + return new UserInfoDto(); + } + var customerid = userinfos[0].Customerid; + userinfos = await _userCenterRepository.GetRepository().Query() + .Where(x => x.Customerid == customerid) + .ToListAsync(); + if (userinfos == null || !userinfos.Any()) + { + return new UserInfoDto(); + } + var data = new UserInfoDto + { + Resid = userinfos.Where(x => !string.IsNullOrEmpty(x.Resid)).Select(x => x.Resid).FirstOrDefault(), + Unionid = userinfos.Where(x => x.Appid == appid && x.Appuserid == appuserid).Select(x => x.Unionid).FirstOrDefault(), + }; + data.Resid ??= data.Unionid; + return data; + } + } +} diff --git a/code/Zxd.Crm.Domain/WarnningDomain.cs b/code/Zxd.Crm.Domain/WarnningDomain.cs new file mode 100644 index 0000000..433c2ec --- /dev/null +++ b/code/Zxd.Crm.Domain/WarnningDomain.cs @@ -0,0 +1,460 @@ +using DG.Core; +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; +using Zxd.Entity.Zxd; +using Zxd.EntityFramework; + +namespace Zxd.Crm.Domain +{ + public class WarnningDomain : IWarnningDomain + { + private readonly IBaseRepository _zxdRepository; + private readonly IMapper _mapper; + + public WarnningDomain(IBaseRepository zxdRepository, + IMapper mapper) + { + _zxdRepository = zxdRepository; + _mapper = mapper; + } + + public async Task AddTemplate(WarnningTemplateCreateDto dto) + { + var query = _zxdRepository.GetRepository(); + try + { + EarlyWarningTemplate template = new EarlyWarningTemplate(); + var postDetail = JsonHelper.FromJson>(dto.PrewarningValue); + if (dto.Id > 0) + { + template = await query.QueryIncluding(x => x.EarlyWarningSettings).FirstOrDefaultAsync(n => n.Id == dto.Id); + if (template != null) + { + var sameTime = dto.PeriodFrom == template.PeriodFrom && dto.PeriodTo == template.PeriodTo; + /* if (!sameTime) + { + await query.DeleteAsync(template); + await CreateNewTemplate(dto); + return true; + }*/ + var dbDetail = JsonHelper.FromJson>(template.PrewarningValue); + List useGuid = new List(); + foreach (var item in postDetail) + { + var setDetail = postDetail.Where(n => n.type == item.type && n.value == item.value && !string.IsNullOrWhiteSpace(n.guid)).ToList(); + var existDetail = dbDetail.FirstOrDefault(n => n.type == item.type && n.value == item.value && !useGuid.Contains(n.guid)); + if (existDetail != null) + { + item.guid = existDetail.guid; + useGuid.Add(existDetail.guid); + } + else + { + item.guid = Guid.NewGuid().ToString(); + } + if (string.IsNullOrWhiteSpace(item.guid) || !sameTime) + { + item.guid = Guid.NewGuid().ToString(); + } + } + dto.PrewarningValue = postDetail.ToJson(); + template.Count = dto.Count; + template.TemplateName = dto.TemplateName; + template.PeriodFrom = dto.PeriodFrom; + template.PeriodTo = dto.PeriodTo; + template.PrewarningValue = dto.PrewarningValue; + template.Deptid = dto.DeptId; + template.Maxnum = dto.Maxnum; + await query.UpdateAsync(template); + if (template.EarlyWarningSettings != null && template.EarlyWarningSettings.Any(x => x.MaxNum != dto.Maxnum)) + { + template.EarlyWarningSettings.ForEach(setting => { setting.MaxNum = dto.Maxnum; }); + await _zxdRepository.GetRepository().BatchUpdateAsync(template.EarlyWarningSettings, x => new { x.MaxNum }); + } + } + } + else + { + await CreateNewTemplate(dto); + } + + return true; + } + catch (Exception ex) + { + throw ex; + } + } + public async Task CreateNewTemplate(WarnningTemplateCreateDto dto) + { + var query = _zxdRepository.GetRepository(); + var postDetail = JsonHelper.FromJson>(dto.PrewarningValue); + foreach (var item in postDetail) + { + item.guid = Guid.NewGuid().ToString(); + } + dto.PrewarningValue = postDetail.ToJson(); + var template = new EarlyWarningTemplate + { + Count = dto.Count, + TemplateName = dto.TemplateName, + PeriodFrom = dto.PeriodFrom, + PeriodTo = dto.PeriodTo, + PrewarningValue = dto.PrewarningValue, + Deptid = dto.DeptId, + Maxnum = dto.Maxnum, + }; + await query.InsertAsync(template); + } + public async Task> GetTemplatePage(GetWarnningTemplateDto dto) + { + var query = _zxdRepository.GetRepository().Query(); + if (!string.IsNullOrWhiteSpace(dto.Name)) + { + query = query.Where(n => n.TemplateName.Contains(dto.Name)); + } + if (dto.Id.HasValue) + { + query = query.Where(n => n.Id == dto.Id); + } + if (!string.IsNullOrWhiteSpace(dto.DeptId)) + { + var deptFilter = dto.DeptId.Split(',').Select(n => Convert.ToInt32(n)).ToList(); + query = query.Where(n => deptFilter.Contains(n.Deptid)); + } + var total = await query.CountAsync(); + query = query.OrderByDescending(n => n.Id); + var res = await query + .Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToListAsync(); + var data = _mapper.Map(res); + return new PageResult(dto.PageIndex, dto.PageSize, total, data); + } + + public async Task GetTemplate(int id) + { + var data = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == id) + .FirstOrDefaultAsync(); + if (data == null) throw new ApiException("模板不存在或已删除!"); + return _mapper.Map(data); + } + + public async Task> GetWarnUserTotal(GetWarnningUserTotalDto dto) + { + var query = _zxdRepository.GetRepository().Query(); + + if (!string.IsNullOrWhiteSpace(dto.DeptId)) + { + var deptFilter = dto.DeptId.Split(',').Select(n => Convert.ToInt32(n)).ToList(); + query = query.Where(n => deptFilter.Contains(n.Deptid)); + } + var res = query.GroupBy(n => new + { + n.Code, + n.Deptid, + n.Participant + }).Select(n => new WarnUserList + { + DeptId = n.Key.Deptid, + Code = n.Key.Code, + Count = n.Count(), + Participant = n.Key.Participant + }).ToList(); + + foreach(var item in res) + { + if (string.IsNullOrEmpty(item.Code)) + { + var code = $"{CreateWarnUserNo()}"; + item.Code = code; + var data = await _zxdRepository.GetRepository().Query() + .Where(n => n.Deptid == item.DeptId && string.IsNullOrEmpty(n.Code)) + .ToListAsync(); + data.ForEach(x => { x.Code = code; }); + await _zxdRepository.GetRepository().BatchUpdateAsync(data); + } + } + + return res; + } + + public async Task GetWarnUser(string? code) + { + var res = await _zxdRepository.GetRepository().Query().Where(n => n.Code == code).ToListAsync(); + if (res == null || !res.Any()) return new EarlyWarningUserModel(); + var data = res.First(); + EarlyWarningUserModel model = new() + { + Deptid = data.Deptid, + WxWorkId = String.Join('\n', res.Select(n => n.WxWorkId)), + Participant = data.Participant, + Code = data.Code + }; + return model; + } + + /// + /// 删除 + /// + /// + /// + public async Task DeleteWarnUser(string? code) + { + var data = await _zxdRepository.GetRepository().Query().Where(n => n.Code == code).ToListAsync(); + if (data.Any()) + { + await _zxdRepository.GetRepository().BatchDeleteAsync(data); + } + else + { + throw new ApiException("数据不存在!"); + } + return true; + } + + /// + /// 新加告警配置 + /// + /// + /// + /// + public async Task AddWarnSetting(CreateOrEditSettingDto dto) + { + if (dto.DeptId == 0) + { + throw new Exception("业务线必填"); + } + if (string.IsNullOrWhiteSpace(dto.Participant)) + { + throw new Exception("人员必填"); + } + var entryOp = _zxdRepository.GetRepository(); + var existList = entryOp.Query().Where(n => dto.WarnUserInfo.Select(n => n.Eid).Contains(n.Eid)).ToList(); + var userlist = dto.Participant.Split(',').ToList(); + var maxnum = dto.MaxNum.HasValue ? dto.MaxNum.Value : 0; + if (dto.templateId.HasValue) + { + var template = await _zxdRepository.GetRepository().Query() + .Where(x => x.Id == dto.templateId.Value) + .FirstOrDefaultAsync(); + if (template != null) maxnum = template.Maxnum; + } + foreach (var user in dto.WarnUserInfo) + { + var existModel = existList.FirstOrDefault(n => n.Eid == user.Eid); + if (!dto.MaxNum.HasValue && dto.templateId.HasValue) + { + throw new Exception("最大数量不能为空!"); + } + if (existModel == null) + { + if (!dto.templateId.HasValue) + { + //throw new Exception("模板不能为空"); + continue; + } + EarlyWarningSetting model = new EarlyWarningSetting + { + Eid = Convert.ToInt32(user.Eid), + Name = user.Name, + TemplateId = dto.templateId.HasValue ? dto.templateId:0, + Deptid = dto.DeptId, + CreateUser = dto.Eid, + CreateTime = DateTime.Now, + MaxNum = maxnum + }; + await entryOp.InsertAsync(model); + } + else + { + if (!dto.templateId.HasValue) + { + await entryOp.DeleteAsync(existModel); + continue; + } + existModel.TemplateId = dto.templateId; + existModel.Deptid = dto.DeptId; + existModel.CreateUser = dto.Eid; + existModel.UpdateTime = DateTime.Now; + existModel.HasChangeNum = maxnum > existModel.MaxNum ? 1 : 0; + existModel.MaxNum = maxnum; + await entryOp.UpdateAsync(existModel); + } + } + return true; + } + + public async Task GetWarnSetting(GetWarnningSettingDto dto) + { + var entryOp = _zxdRepository.GetRepository(); + var templateList = _zxdRepository.GetRepository().Query().Where(n => n.Deptid == dto.DeptId).ToList(); + var template = templateList.Map(); + /*var existList = entryOp.Query().Where(n => n.Deptid == deptId).ToList(); + if (existList.Count == 0) + { + return new WarnningSetting() + { + DeptId = deptId, + Template = template + }; + } + var selTemplate = template.FirstOrDefault(n => n.Id == existList.FirstOrDefault().TemplateId); + if (selTemplate != null) + { + selTemplate.selected = true; + }*/ + WarnningSetting setting = new WarnningSetting() + { + //MaxNum = existList.FirstOrDefault().MaxNum, + //templateId = existList.FirstOrDefault().TemplateId , + DeptId = dto.DeptId, + //ParticipantIds = existList.Select(n => n.Eid.ToString()).ToList() , + Template = template + }; + if (!string.IsNullOrWhiteSpace(dto.EidList)) + { + var eidFilter = dto.EidList.Split(",").Select(n => Convert.ToDecimal(n)).ToList(); + var existList = entryOp.Query().Where(n =>n.Deptid == dto.DeptId && eidFilter.Contains(n.Eid)).GroupBy(n => new { maxNum = n.MaxNum, templateId = n.TemplateId }). + Select(n => new { maxNum = n.Key.maxNum, templateId = n.Key.templateId }).ToList(); + if (existList.Count == 1) + { + setting.MaxNum = existList.FirstOrDefault().maxNum; + setting.templateId = existList.FirstOrDefault().templateId; + var selTemplate = setting.Template.FirstOrDefault(n => n.Id == existList.FirstOrDefault().templateId); + if (selTemplate != null) + { + selTemplate.selected = true; + } + } + } + return setting; + } + + public async Task> GetWarnSettingByEid(string eid) + { + List res = new List(); + var eidFilter = eid.Split(",").Select(n => Convert.ToDecimal(n)).ToList(); + var entryOp = _zxdRepository.GetRepository(); + var existList = entryOp.Query().Where(n => eidFilter.Contains(n.Eid)).ToList(); + var entryTemp = _zxdRepository.GetRepository(); + var tempids = existList.Select(n => n.TemplateId).Distinct().ToList(); + var templateList = entryTemp.Query().Where(n => tempids.Contains(n.Id)).ToList(); + foreach (var eidItem in eidFilter) + { + var set = existList.FirstOrDefault(n => n.Eid == eidItem); + if (set != null) + { + var temp = templateList.FirstOrDefault(n => n.Id == set.TemplateId); + ReportListModel model = new ReportListModel + { + Eid = eidItem, + MaxNum = set.MaxNum, + Name = temp?.TemplateName + }; + res.Add(model); + } + } + return res; + } + + public async Task AddWarnUser(EarlyWarningUserCreateDto dto, int? eid) + { + if (!dto.DeptId.HasValue) + { + throw new Exception("业务线必填"); + } + if (string.IsNullOrWhiteSpace(dto.WxWorkId)) + { + throw new Exception("企微Id必填"); + } + var entryOp = _zxdRepository.GetRepository(); + var code = dto.Code ?? CreateWarnUserNo(); + var existList = await entryOp.Query().Where(n => n.Code == dto.Code).ToListAsync(); + var _ids = dto.WxWorkId.Replace("\r\n", ",").Replace("\r", ",").Replace("\n", ",").Split(',').ToList(); + _ids = _ids.Distinct().ToList(); + if (dto.Type == 1 && existList.Count == 0) + { + code = CreateWarnUserNo(); + var data = await entryOp.Query().Where(x => x.Deptid == dto.DeptId).ToListAsync(); + + foreach (var item in data) + { + if (item.ParticipantIds.Intersect(dto.ParticipantIds).Any()) + { + throw new Exception($"工号[{string.Join(",", item.ParticipantIds.Intersect(dto.ParticipantIds))}]被监视人员已存在,请勿重复创建!"); + } + } + } + else if (dto.Type == 2) + { + var data = await entryOp.Query().Where(x => x.Deptid == dto.DeptId && x.Code != dto.Code).ToListAsync(); + + foreach (var item in data) + { + if (item.ParticipantIds.Intersect(dto.ParticipantIds).Any()) + { + throw new Exception($"工号[{string.Join(",", item.ParticipantIds.Intersect(dto.ParticipantIds))}]被监视人员已存在,请勿重复创建!"); + } + } + } + + await entryOp.BatchDeleteAsync(existList); + + foreach (var item in _ids) + { + if (string.IsNullOrEmpty(item)) { continue; } + EarlyWarningUser model = new EarlyWarningUser + { + WxWorkId = item, + Deptid = dto.DeptId.Value, + CreateUser = eid?.ToString(), + CreateTime = DateTime.Now, + CropId = dto.Cropid, + AppId = dto.AppId, + Participant = dto.Participant, + Code = code + }; + await entryOp.InsertAsync(model); + } + return true; + } + + private string CreateWarnUserNo() + { + var no = $"{DateTimeOffset.Now.ToUnixTimeMilliseconds()}"; + return no; + } + + public async Task GetNewTemplatePeriod(int deptid) + { + return await _zxdRepository.GetRepository().Query() + .Where(x => x.Deptid == deptid) + .OrderByDescending(x => x.Id) + .Select(x => new + { + x.PeriodFrom, + x.PeriodTo + }) + .FirstAsync(); + } + } + + public class EarlyWarningTemplatePrewarningValue + { + [JsonPropertyName("type")] + public int Type { get; set; } + + [JsonPropertyName("value")] + public int Value { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.Domain/WeworkUserWorkerDomain.cs b/code/Zxd.Crm.Domain/WeworkUserWorkerDomain.cs new file mode 100644 index 0000000..d67424b --- /dev/null +++ b/code/Zxd.Crm.Domain/WeworkUserWorkerDomain.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Dncms; + +namespace Zxd.Crm.Domain +{ + public class WeworkUserWorkerDomain : IWeworkUserWorkerDomain + { + private readonly IBaseRepository _dncmsbaseRepository; + + public WeworkUserWorkerDomain(IBaseRepository dncmsbaseRepository) + { + _dncmsbaseRepository = dncmsbaseRepository; + } + public async Task> GetWeworkUserWorkerList(int? deptid, int minId, int limit = 100) + { + var list = await _dncmsbaseRepository.GetRepository().Query() + .Where(m => ((deptid.HasValue && m.deptid == deptid)|| !deptid.HasValue) && m.id > minId).Take(limit).ToListAsync(); + return list; + } + } +} diff --git a/code/Zxd.Crm.Domain/Zxd.Crm.Domain.csproj b/code/Zxd.Crm.Domain/Zxd.Crm.Domain.csproj new file mode 100644 index 0000000..b7eb951 --- /dev/null +++ b/code/Zxd.Crm.Domain/Zxd.Crm.Domain.csproj @@ -0,0 +1,52 @@ + + + + net6.0 + enable + enable + True + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/Zxd.Crm.WebApi/Controllers/AssignRuleController.cs b/code/Zxd.Crm.WebApi/Controllers/AssignRuleController.cs new file mode 100644 index 0000000..c55f90f --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/AssignRuleController.cs @@ -0,0 +1,81 @@ +using Zxd.Crm.Domain.Dto.AssignRule; +using Zxd.Crm.Domain.Impl; +using Zxd.Crm.Domain.Impl.AssignRule; +using Zxd.Entity.Dncms; + +namespace Zxd.Crm.WebApi.Controllers +{ + /// + /// cms 分配规则接口 + /// + [ApiSignatureFilterForbid] + public class AssignRuleController : BaseController + { + private readonly IAssignRuleDomain _assignRuleDomain; + + public AssignRuleController(IAssignRuleDomain assignRuleDomain) + { + _assignRuleDomain = assignRuleDomain; + } + + /// + /// 列表接口 + /// + /// + /// + /// + [HttpGet("GetAssignList")] + public async Task> GetAssignList([FromQuery] AssignRuleQueryDto queryDto) + { + return await _assignRuleDomain.GetList(queryDto); + } + + /// + /// 列表接口 + /// + /// + /// + /// + [HttpGet("GetNotSetAssignList")] + public async Task> GetNotSetAssignList([FromQuery] AssignRuleNotSetQueryDto queryDto) + { + return await _assignRuleDomain.GetNotSetAssignList(queryDto); + } + + /// + /// 创建规则 + /// + /// + /// + /// + [HttpPost("CreateAssignRule")] + public async Task CreateAssignRule([FromBody] List createDto) + { + return await _assignRuleDomain.Create(createDto); + } + + /// + /// 销售组规则上下线 + /// + /// + /// + /// + [HttpPost("UpAssignRule")] + public async Task UpAssignRule([FromBody] AssignRuleUpOrDowmDto upDto) + { + return await _assignRuleDomain.UpOrDowmAssignRule(upDto); + } + + /// + /// 销售组规则上下线 + /// + /// + /// + /// + [HttpPost("DeleteRule")] + public async Task DeleteRule([FromBody] List ids) + { + return await _assignRuleDomain.Delete(ids); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/BaseController.cs b/code/Zxd.Crm.WebApi/Controllers/BaseController.cs new file mode 100644 index 0000000..efe7a8e --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/BaseController.cs @@ -0,0 +1,9 @@ +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiController] + [Route("Api/[controller]")] + [Produces("application/json")] + public class BaseController : Controller + { + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/ExtuserController.cs b/code/Zxd.Crm.WebApi/Controllers/ExtuserController.cs new file mode 100644 index 0000000..eebd17b --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/ExtuserController.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Mvc; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Dto.Extuser; +using Zxd.Crm.Domain.Impl; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class ExtuserController : BaseController + { + private readonly IExtuserDomain _extuserDomain; + + public ExtuserController(IExtuserDomain extuserDomain) + { + _extuserDomain = extuserDomain; + } + + /// + /// 处理企微客户关系绑定 + /// + /// + /// + [HttpPost("BindExtUser")] + public async Task AddTemplate([FromBody] ExtUserCreateDto dto) + { + return await _extuserDomain.BindExtUser(dto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/FieldController.cs b/code/Zxd.Crm.WebApi/Controllers/FieldController.cs new file mode 100644 index 0000000..73343ee --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/FieldController.cs @@ -0,0 +1,75 @@ +using Microsoft.AspNetCore.Mvc; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class FieldController : BaseController + { + private readonly IFieldDomain _fieldDomain; + + public FieldController(IFieldDomain fieldDomain) + { + _fieldDomain = fieldDomain; + } + + /// + /// 获取用户设置 + /// + /// + /// + /// + [HttpGet("UserSettings")] + public async Task> GetTableFieldSettings(string? module, decimal? eid) + { + return await _fieldDomain.GetTableFieldSettings(module, eid); + } + + /// + /// 创建 + /// + /// + /// + [HttpPost("TableField")] + public async Task CreateTableField([FromBody] CreateTableFieldDto createTable) + { + await _fieldDomain.CreateTableField(createTable); + } + + /// + /// 获取用户设置列表 + /// + /// + /// + /// + [HttpGet("UserSettingList")] + public async Task> GetUserTableFieldSettings(string? module, decimal? eid) + { + return await _fieldDomain.GetUserTableFieldSettings(module, eid); + } + + /// + /// 更新用户设置列表 + /// + /// + /// + [HttpPost("UserSetting")] + public async Task CreateOrUpdateUserSetting([FromBody] CreateOrUpdateUserSettingDto dto) + { + await _fieldDomain.CreateOrUpdateUserSetting(dto); + } + + /// + /// 重置用户设置列表 + /// + /// + /// + /// + [HttpGet("ResetSettingList")] + public async Task ResetUserTableFieldSettings(string? module, decimal? eid) + { + await _fieldDomain.ResetUserTableFieldSettings(module, eid); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/ProductController.cs b/code/Zxd.Crm.WebApi/Controllers/ProductController.cs new file mode 100644 index 0000000..ea5c567 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/ProductController.cs @@ -0,0 +1,81 @@ +using Exceptionless.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using System.Text; +using Zxd.Core.Shared; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; +using Zxd.Entity.CompanyBaseConf; + +//using WX.CRM.Common; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class ProductController : BaseController + { + private readonly IConfiguration _configuration; + private readonly IBaseRepository _zxdRepository; + + public ProductController(IConfiguration configuration, IBaseRepository zxdRepository) + { + _configuration = configuration; + _zxdRepository = zxdRepository; + } + + //根据坐席id获取对应可授权产品数据 + [HttpGet("GetProductByAppid")] + public PageResult GetProductByAppid([FromQuery] GetProductByAppidDto dto) + { + try + { + List res = new List(); + //List departmentList = new List(); + // 1 拿到所有本事业部的所有部门数据 + var systemConfig = _configuration.GetSection("SystemConfig").Get(); + var url = systemConfig.GetDeptsUrl(); + var req = HttpHelper.GetData(url, "", Encoding.UTF8); + var resModel = JsonHelper.FromJson>>(req); + if (resModel.code == 0) + { + var departmentList = resModel.data.Where(d => d.appid == dto.appid).ToList(); + var CompanyCodeList = departmentList.Select(d => d.companyCode).ToList(); + // 2 根据部门code,找出所有相关的产品 + //var channelList = _zxdRepository.GetRepository().Query(); + var productList = _zxdRepository.GetRepository().Query(); + var channelQ = _zxdRepository.GetRepository().Query().Where(c => c.isEmpower == 1 && (CompanyCodeList.Contains(c.companycode))); + var channelList = channelQ.Skip((dto.PageIndex - 1) * dto.PageSize) + .Take(dto.PageSize) + .ToList(); + var count = channelQ.Count(); + var productListByCh = channelList.Select(ch => new WxSzzySubproduct + { + subproductid = ch.subproductid, + subproductname = ch.subproductname, + isEmpower = ch.isEmpower, + productcode = productList.FirstOrDefault(p => p.subproductid == ch.subproductid)?.productcode, + price = productList.FirstOrDefault(p => p.subproductid == ch.subproductid)?.price, + producttype = productList.FirstOrDefault(p => p.subproductid == ch.subproductid)?.producttype, + mid = productList.FirstOrDefault(p => p.subproductid == ch.subproductid)?.mid + })?.ToList(); + + //List data = productListByCh.Skip((dto.PageIndex - 1) * dto.PageSize) + // .Take(dto.PageSize) + // .ToList(); + Log.Information("获取可赋权产品数据:" + productListByCh); + return new PageResult(dto.PageIndex, dto.PageSize, count, productListByCh); + } + else + { + Log.Error("获取部门数据失败"); + return new PageResult(dto.PageIndex, dto.PageSize, 0, new List()); + } + } + catch (Exception ex) + { + Log.Error("获取可赋权产品数据失败:" + ex.ToString()); + return new PageResult(dto.PageIndex, dto.PageSize, 0, new List()); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/QwOnlinePayController.cs b/code/Zxd.Crm.WebApi/Controllers/QwOnlinePayController.cs new file mode 100644 index 0000000..bd53571 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/QwOnlinePayController.cs @@ -0,0 +1,99 @@ +using Zxd.Crm.Domain.Dto.AssignRule; +using Zxd.Crm.Domain.Dto.QWOnlinePay; +using Zxd.Crm.Domain.Impl.QwOnlinePay; +using Zxd.Entity.Zxd.QiweiOnlePay; + +namespace Zxd.Crm.WebApi.Controllers +{ + /// + /// 企微侧边栏在线支付 + /// + [ApiSignatureFilterForbid] + public class QwOnlinePayController : BaseController + { + private readonly IQwOnlinePayDomain _onlineDomain; + + public QwOnlinePayController(IQwOnlinePayDomain onlineDomain) + { + _onlineDomain = onlineDomain; + } + + /// + /// 创建活动 + /// + /// + /// + /// + [HttpPost("CreateActivity")] + public async Task CreateActivity([FromBody] ActivityCreateDto createDto) + { + return await _onlineDomain.CreateActivity(createDto); + } + + /// + /// 活动编辑 + /// + /// + /// + /// + [HttpGet("GetEditActivityModel")] + public async Task GetActivityList([FromQuery] int Id) + { + return await _onlineDomain.GetEditActivityModel(Id); + } + + /// + /// 活动列表 + /// + /// + /// + /// + [HttpGet("GetActivityList")] + public async Task> GetActivityList([FromQuery] ActivityQueryDto queryDto) + { + return await _onlineDomain.GetActivityList(queryDto); + } + + /// + /// 创建活动产品 + /// + /// + /// + /// + [HttpPost("CreateActProduct")] + public async Task CreateActProduct([FromBody] ActProductCreateDto createDto) + { + return await _onlineDomain.CreateActProduct(createDto); + } + + /// + /// 活动产品列表 + /// + /// + /// + /// + [HttpGet("GetActProductList")] + public async Task> GetActProductList([FromQuery] ActProductQueryDto queryDto) + { + return await _onlineDomain.GetActProductList(queryDto); + } + + [HttpGet("GetProductEditModel")] + public async Task GetProductEditModel([FromQuery] ProductEditQueryDto queryDto) + { + return await _onlineDomain.GetProductEditModel(queryDto); + } + + [HttpGet("GetProductInfo")] + public async Task GetProductInfo([FromQuery] ProductInfoQueryDto queryDto) + { + return await _onlineDomain.GetProductInfo(queryDto); + } + + [HttpPost("DelActProduct")] + public async Task DelActProduct([FromBody] DelActProductModel queryDto) + { + return await _onlineDomain.DelActProduct(queryDto); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/SSOController.cs b/code/Zxd.Crm.WebApi/Controllers/SSOController.cs new file mode 100644 index 0000000..f0e7dad --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/SSOController.cs @@ -0,0 +1,138 @@ +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using System.Security.Cryptography; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; +using static Zxd.Crm.Domain.SSOEmployeeDomain; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class SSOController : BaseController + { + private readonly ISSOEmployeeDomain _sourceDomain; + + public SSOController(ISSOEmployeeDomain sourceDomain) + { + _sourceDomain = sourceDomain; + } + + /// + /// 通过eid获取事业部名称 + /// + /// + /// + [HttpGet("GetDeptNameByEid")] + public async Task> GetDeptNameByEid(string? eidList) + { + var res = await _sourceDomain.GetDeptmentByEid(eidList); + return res; + } + /// + /// 获取通过坐席id获取对应坐席员工的产品授权情况 + /// + [HttpGet("GetEmpowerment")] + public async Task> GetEmpowerment([FromQuery] GetEmpowermentByAppidDto dto) + { + var res = await _sourceDomain.GetEmpowerment(dto); + return res; + } + [HttpGet("RemoveEidCache")] + public async Task RemoveEidCache(string? activeModel) + { + var res = await _sourceDomain.RemoveEidCache(activeModel); + return res; + } + /// + /// 中心点 添加【授权情况】,和更新【授权日志】 + /// + [HttpPost("SetEmpowerment")] + public async Task> SetEmpowerment(SetEmpowermentDto dto) + { + var res = await _sourceDomain.SetEmpowerment(dto); + return res; + } + + [HttpGet("Async")] + public async Task AsyncEmplyeeData([Required] string eid) + { + await _sourceDomain.AsyncEmplyeeData(eid); + } + + /// + /// 更新员工与手机绑定账号上次赋权的时间 + /// + [HttpPost("UpdateLastEmpowerTime")] + public async Task> UpdateLastEmpowerTime(UpdateLastEmpowerTime dto) + { + var res = await _sourceDomain.UpdateLastEmpowerTime(dto.residString, dto.timestamp != null ? dto.timestamp : null); + return res; + } + /// + /// 更新员工手机绑定的软件用户名 + /// + [HttpPost("UpdateAppusername")] + public async Task> UpdateAppusername(List UpdateAppusernameList) + { + var res = await _sourceDomain.UpdateAppusername(UpdateAppusernameList); + return res; + } + + /// + /// 通过员工id获取软件用户名 + /// + /// 员工id + /// + /// + [HttpGet("GetAppuserByEid")] + public async Task>> GetAppuserByEid(int eid) + { + var res = await _sourceDomain.GetAppuserByEid(eid); + return res; + } + /// + /// 增加员工软件用户的绑定数据 + /// + /// 被操作员工id + /// 资源id + /// 脱敏后电话 + /// 操作类型 bind: 绑定或更新 unbind 解绑 + /// 操作员工id + /// 是否为主账号 + /// + /// + [HttpPost("AddSoftEmployeeBind")] + public async Task> AddSoftEmployeeBind(SoftEmployeeBindChangeDto data) + { + return await _sourceDomain.AddSoftEmployeeBind(data.to_by_eid, data.resid, data.show_phone, data.from_by_eid); + } + + /// + /// 解绑员工软件用户的绑定数据 + /// + /// 被操作员工id + /// 资源id + /// 脱敏后电话 + /// 操作员工id + /// 是否为主账号 + /// + /// + [HttpPost("DeleteSoftEmployeeBind")] + public async Task> DeleteSoftEmployeeBind(SoftEmployeeBindChangeDto data) + { + return await _sourceDomain.DeleteSoftEmployeeBind(data.to_by_eid, data.resid, data.show_phone, data.from_by_eid); + } + + ///// + ///// 记录员工软件用户字典 + ///// + ///// + ///// + //[HttpPost("SetEmployeeSoftDict")] + + //public async Task> SetEmployeeSoftDict(EMPLOYEE_SOFT_DICT data) + //{ + // return await _sourceDomain.SetEmployeeSoftDict(data); + //} + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/UserInfoController.cs b/code/Zxd.Crm.WebApi/Controllers/UserInfoController.cs new file mode 100644 index 0000000..139dcf0 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/UserInfoController.cs @@ -0,0 +1,27 @@ +using Zxd.Crm.Domain.Impl; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class UserInfoController : BaseController + { + private readonly IUserInfoDomain _userInfoDomain; + + public UserInfoController(IUserInfoDomain userInfoDomain) + { + _userInfoDomain = userInfoDomain; + } + + /// + /// 获取客户资料 + /// + /// + /// + /// + [HttpGet] + public async Task GetUserInfo(string? appid, string? appuserid) + { + return await _userInfoDomain.GetUserInfo(appid, appuserid); + } + } +} diff --git a/code/Zxd.Crm.WebApi/Controllers/WarnningController.cs b/code/Zxd.Crm.WebApi/Controllers/WarnningController.cs new file mode 100644 index 0000000..5940bfd --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/WarnningController.cs @@ -0,0 +1,131 @@ +using Microsoft.AspNetCore.Mvc; +using Zxd.Crm.Domain.Dto; +using Zxd.Crm.Domain.Impl; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class WarnningController : BaseController + { + private readonly IWarnningDomain _warnningDomain; + + public WarnningController(IWarnningDomain warnningDomain) + { + _warnningDomain = warnningDomain; + } + + /// + /// 获取模板列表 + /// + /// + /// + [HttpGet("TemplatePage")] + public async Task> GetTemplatePage([FromQuery] GetWarnningTemplateDto dto) + { + return await _warnningDomain.GetTemplatePage(dto); + } + /// + /// 获取模板预警人员列表 + /// + /// + /// + [HttpGet("GetWarnUser")] + public async Task GetWarnUser([FromQuery] string? code) + { + return await _warnningDomain.GetWarnUser(code); + } + /// + /// 获取模板预警人员列表 + /// + /// + /// + [HttpGet("GetWarnUserTotal")] + public async Task> GetWarnUserTotal([FromQuery] GetWarnningUserTotalDto dto) + { + return await _warnningDomain.GetWarnUserTotal(dto); + } + + /// + /// 删除模板预警人员配置 + /// + /// + /// + [HttpDelete("WarnUser")] + public async Task DeleteWarnUser(string? code) + { + return await _warnningDomain.DeleteWarnUser(code); + } + + /// + /// 获取模板列表 + /// + /// + /// + [HttpPost("AddTemplate")] + public async Task AddTemplate([FromBody] WarnningTemplateCreateDto dto) + { + return await _warnningDomain.AddTemplate(dto); + } + /// + /// 创建或修改预警设置 + /// + /// + /// + [HttpPost("AddWarnSetting")] + public async Task CreateOrEditMeeting([FromBody] CreateOrEditSettingDto dto) + { + return await _warnningDomain.AddWarnSetting(dto); + } + /// + /// 根据事业部或者工号获取配置 + /// + /// + /// + [HttpGet("GetWarnSetting")] + public async Task GetWarnSetting([FromQuery] GetWarnningSettingDto dto) + { + return await _warnningDomain.GetWarnSetting(dto); + } + /// + /// 创建通知人员 + /// + /// + /// + [HttpPost("AddWarnUser")] + public async Task AddWarnUser([FromBody] EarlyWarningUserCreateDto dto, [FromQuery] int? eid) + { + return await _warnningDomain.AddWarnUser(dto, eid); + } + /// + /// 列表根据工号获取最大资源数和模板 + /// + /// + /// + [HttpGet("GetWarnSettingByEid")] + public async Task> GetWarnSettingByEid([FromQuery] string eidFilter) + { + return await _warnningDomain.GetWarnSettingByEid(eidFilter); + } + + /// + /// 获取最新建立的预警模板的接粉周期 + /// + /// + [HttpGet("NewTemplatePeriod")] + public async Task GetNewTemplatePeriod(int deptid) + { + return await _warnningDomain.GetNewTemplatePeriod(deptid); + } + + /// + /// 获取模板 + /// + /// + /// + [HttpGet("Template")] + public async Task GetTemplate(int id) + { + return await _warnningDomain.GetTemplate(id); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Controllers/WeworkUserWorkerController.cs b/code/Zxd.Crm.WebApi/Controllers/WeworkUserWorkerController.cs new file mode 100644 index 0000000..1ffa4a5 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Controllers/WeworkUserWorkerController.cs @@ -0,0 +1,28 @@ +using Microsoft.AspNetCore.Mvc; +using Zxd.Crm.Domain.Impl; +using Zxd.Entity.Dncms; + +namespace Zxd.Crm.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class WeworkUserWorkerController : BaseController + { + private readonly IWeworkUserWorkerDomain _weworkUserWorkerDomain; + + public WeworkUserWorkerController(IWeworkUserWorkerDomain weworkUserWorkerDomain) + { + _weworkUserWorkerDomain = weworkUserWorkerDomain; + } + /// + /// 获取各坐席的变更记录 + /// + /// + /// + /// + [HttpGet("GetWeworkUserWorkerList")] + public async Task> GetWeworkUserWorkerList(int? deptid,int minId, int limit=100) + { + return await _weworkUserWorkerDomain.GetWeworkUserWorkerList(deptid, minId, limit); + } + } +} diff --git a/code/Zxd.Crm.WebApi/Dockerfile b/code/Zxd.Crm.WebApi/Dockerfile new file mode 100644 index 0000000..5a11ce4 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Dockerfile @@ -0,0 +1,26 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj", "Zxd.Crm.WebApi/"] +COPY ["Zxd.Crm.Domain/Zxd.Crm.Domain.csproj", "Zxd.Crm.Domain/"] +COPY ["Zxd.Core.Shared/Zxd.Core.Shared.csproj", "Zxd.Core.Shared/"] +COPY ["Zxd.EntityFramework/Zxd.EntityFramework.csproj", "Zxd.EntityFramework/"] +COPY ["Zxd.Entity/Zxd.Entity.csproj", "Zxd.Entity/"] +RUN dotnet restore "Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj" +COPY . . +WORKDIR "/src/Zxd.Crm.WebApi" +RUN dotnet build "Zxd.Crm.WebApi.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Zxd.Crm.WebApi.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Zxd.Crm.WebApi.dll"] \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Program.cs b/code/Zxd.Crm.WebApi/Program.cs new file mode 100644 index 0000000..07c9949 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Program.cs @@ -0,0 +1,119 @@ +using Exceptionless; +using Zxd.WebApi.Workers; + +try +{ + // Add services to the container. + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true) + .Build(); + + var builder = WebApplication.CreateBuilder(args); + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .WriteTo.Exceptionless(builder.Configuration.GetValue("Exceptionless:ApiKey"), builder.Configuration.GetValue("Exceptionless:ServerUrl"), new string[] { "zxd-crm-webapi" }) + .CreateLogger(); + Log.Logger = logger; + builder.Services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(logger); + }); + builder.Services.AddExceptionless(builder.Configuration); + Log.Information("Starting ZXD Service"); + builder.Services.AddControllers() + .AddApiResult() + .AddApiSignature() + .AddJsonOptions(options => + { + options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; + options.JsonSerializerOptions.Converters.Add(new JsonOptionsExtensions()); + }); + builder.Services.AddDGHttpClient(); + var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; + builder.Services.AddHostedService(); + builder.Services.AddHostedService(); + builder.Services.AddHostedService(); + + builder.Services.AddCors(option => + { + option.AddPolicy(MyAllowSpecificOrigins, + policy => + { + policy.SetIsOriginAllowed(_ => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); + }); + builder.Services.AddExceptionless(builder.Configuration); + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo + { + Version = "v1", + Title = "ZXD CORE API", + Description = "ZXD CORE API" + }); + var xmlFilename = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"; + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Zxd.Crm.Domain.xml")); + }); + builder.Services.AddRedis(builder.Configuration); + builder.Services.AddOptions() + .Configure(e => builder.Configuration.GetSection("SystemConfig").Bind(e)) + .Configure(e => builder.Configuration.GetSection("ClientKey").Bind(e)); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("zxdcrm"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("dncms"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("dncms"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("dncmsbase"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("crm"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("crm"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("ssobase"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("ssobase"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("usercenter"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("usercenter"))); + }); + builder.Services.AddAutoIoc(typeof(IScopedDependency), LifeCycle.Scoped) + .AddAutoIoc(typeof(ISingletonDependency), LifeCycle.Singleton) + .AddAutoIoc(typeof(ITransientDependency), LifeCycle.Transient) + .AddMapper(); + var app = builder.Build(); + app.UseCors(MyAllowSpecificOrigins); + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment() || Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "PreProduction") + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseAuthorization(); + app.UseExceptionless(); + app.MapControllers(); + + app.Run(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Properties/launchSettings.json b/code/Zxd.Crm.WebApi/Properties/launchSettings.json new file mode 100644 index 0000000..4e1c5cb --- /dev/null +++ b/code/Zxd.Crm.WebApi/Properties/launchSettings.json @@ -0,0 +1,39 @@ +{ + "profiles": { + "Zxd.Crm.WebApi": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:7163;http://localhost:5050" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true, + "useSSL": true, + "httpPort": 5253, + "sslPort": 5254 + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:49936/", + "sslPort": 44355 + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Readme.md b/code/Zxd.Crm.WebApi/Readme.md new file mode 100644 index 0000000..01859ee --- /dev/null +++ b/code/Zxd.Crm.WebApi/Readme.md @@ -0,0 +1,8 @@ +# 主要供crm程序调用的中心点接口 +# 连接数据库: zxdcrm,dncmsbase,usercenter,db_company_base_conf +# 测试地址:http://192.168.11.81:8090 +# 正式地址:http://120.77.165.155:8090 +# 相关api: 获取客户资料 +# 达量通知 +# 通过eid获取事业部名称 +# 获取用户设置列相关接口 \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Serilog.Production.json b/code/Zxd.Crm.WebApi/Serilog.Production.json new file mode 100644 index 0000000..f0856ca --- /dev/null +++ b/code/Zxd.Crm.WebApi/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.AspNetCore" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/Zxd.Crm.WebApi/Serilog.json b/code/Zxd.Crm.WebApi/Serilog.json new file mode 100644 index 0000000..ab8d2ca --- /dev/null +++ b/code/Zxd.Crm.WebApi/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.AspNetCore" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Information", + "Microsoft.EntityFrameworkCore": "Information", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/Zxd.Crm.WebApi/Workers/AssignRuleWorker.cs b/code/Zxd.Crm.WebApi/Workers/AssignRuleWorker.cs new file mode 100644 index 0000000..ece22f5 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Workers/AssignRuleWorker.cs @@ -0,0 +1,33 @@ +using Zxd.Crm.Domain.Impl; +using Zxd.Crm.Domain.Impl.AssignRule; + +namespace Zxd.WebApi.Workers +{ + public class AssignRuleWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + public AssignRuleWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var assignRuleDomain = scope.ServiceProvider.GetRequiredService(); + while (!stoppingToken.IsCancellationRequested) + { + try + { + await assignRuleDomain.AutoUpAssignRule(); + } + catch (Exception ex) + { + Log.Error(ex, "自动上下线失败!"); + } + await Task.Delay(1 * 60 * 1000, stoppingToken); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Workers/EmployeeSyncWorker.cs b/code/Zxd.Crm.WebApi/Workers/EmployeeSyncWorker.cs new file mode 100644 index 0000000..fd6be1e --- /dev/null +++ b/code/Zxd.Crm.WebApi/Workers/EmployeeSyncWorker.cs @@ -0,0 +1,33 @@ +using Zxd.Crm.Domain.Impl; + +namespace Zxd.WebApi.Workers +{ + public class EmployeeSyncWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + public EmployeeSyncWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + //await ssoemployeedomain.clearzxdempolyee(); + while (true) + { + using var scope = _serviceProvider.CreateAsyncScope(); + var sSOEmployeeDomain = scope.ServiceProvider.GetRequiredService(); + await sSOEmployeeDomain.AsyncEmplyeeData(); + await Task.Delay(2 * 60 * 1000); // 2分钟 + } + } + catch (Exception ex) + { + Log.Error(ex, "员工数据同步任务报错!"); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Workers/SSOTempWorker.cs b/code/Zxd.Crm.WebApi/Workers/SSOTempWorker.cs new file mode 100644 index 0000000..9dfdfbd --- /dev/null +++ b/code/Zxd.Crm.WebApi/Workers/SSOTempWorker.cs @@ -0,0 +1,29 @@ +using Zxd.Crm.Domain.Impl; + +namespace Zxd.WebApi.Workers +{ + public class SSOTempWorker : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + + public SSOTempWorker(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + try + { + using var scope = _serviceProvider.CreateAsyncScope(); + var sSOEmployeeDomain = scope.ServiceProvider.GetRequiredService(); + await sSOEmployeeDomain.SSOBindDataInit(); + //await sSOEmployeeDomain.BindSoftUserInit(); + } + catch (Exception ex) + { + Log.Error(ex, "初始化数据失败!"); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj b/code/Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj new file mode 100644 index 0000000..0336363 --- /dev/null +++ b/code/Zxd.Crm.WebApi/Zxd.Crm.WebApi.csproj @@ -0,0 +1,60 @@ + + + + net6.0 + enable + enable + True + 9eb47424-907f-4df6-80eb-47d3b54a3e31 + Linux + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + true + PreserveNewest + + + diff --git a/code/Zxd.Crm.WebApi/appsettings.Disaster.json b/code/Zxd.Crm.WebApi/appsettings.Disaster.json new file mode 100644 index 0000000..3b112d9 --- /dev/null +++ b/code/Zxd.Crm.WebApi/appsettings.Disaster.json @@ -0,0 +1,76 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Data Source=10.22.15.61;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=10.22.15.68;Port=3306;Initial Catalog=usercenter;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "dncms": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "ssobase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "SgHDowY1cmpy8hQNAtqyimRaGjjjE16HPUTIXEvl" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Appid": "qt_core", + "AppSecret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=", + "SsoUrl": "http://10.22.15.22:15814", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "SalesLeadUrl": "http://10.22.15.22:16549/dev.html", + "ZxdCoreUrl": "http://120.77.165.155:8089", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CrmCoreUrl": "http://api.crm.tcfortune.com:8282", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://qm.dn8188.com:8099/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=" + }, + "Redis": { + "HostName": "10.22.15.65", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/appsettings.Production.json b/code/Zxd.Crm.WebApi/appsettings.Production.json new file mode 100644 index 0000000..e1fab7c --- /dev/null +++ b/code/Zxd.Crm.WebApi/appsettings.Production.json @@ -0,0 +1,76 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "ssobase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=db_company_base_conf;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "SgHDowY1cmpy8hQNAtqyimRaGjjjE16HPUTIXEvl" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Appid": "qt_core", + "AppSecret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=", + "SsoUrl": "http://conf.soft.dn8188.com", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "ZxdCoreUrl": "http://120.77.165.155:8089", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CrmCoreUrl": "http://api.crm.tcfortune.com:8282", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://qm.dn8188.com:8099/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=" + }, + "Redis": { + "HostName": "redis-cngzdnddztrevahsz.redis.ivolces.com", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } +} \ No newline at end of file diff --git a/code/Zxd.Crm.WebApi/appsettings.json b/code/Zxd.Crm.WebApi/appsettings.json new file mode 100644 index 0000000..6006639 --- /dev/null +++ b/code/Zxd.Crm.WebApi/appsettings.json @@ -0,0 +1,79 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "ssobase": "Server=192.168.11.141;Database=db_company_base_conf;UserId=tafadmin;Password=tafadmin2017;port=3306;" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "CFFqizs4c8IiaGoWWKDYMMbfj8OOlLibCc3DLSbw" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "SsoUrl": "http://192.168.11.141:24434", + "SsoTokenUrl": "/v1/api/open/sso/token", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "ZxdCoreUrl": "http://120.77.165.155:8089", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CmsUrl": "http://192.168.111.143:19855/", + "CrmCoreUrl": "http://192.168.11.81:8088", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://192.168.11.46/home/cache" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=" + }, + "Redis": { + "HostName": "192.168.11.81", + "Port": "6379", + "Password": "Abc@123456", + "Defaultdatabase": "1" + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/BasParameterDomain.cs b/code/Zxd.Domain/BasParameterDomain.cs new file mode 100644 index 0000000..bdcc5f8 --- /dev/null +++ b/code/Zxd.Domain/BasParameterDomain.cs @@ -0,0 +1,35 @@ +using DG.EntityFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain +{ + public class BasParameterDomain : IBasParameterDomain + { + private readonly IRepositoryBase _parameterRepository; + private readonly IBaseRepository _repository; + + public BasParameterDomain(IBaseRepository repository) + { + _repository = repository; + _parameterRepository = _repository.GetRepository(); + } + + public string GetParameterValue(string paraKey) + { + BAS_PARAMETER param = _parameterRepository.Query().FirstOrDefault(m => m.PARAKEY == paraKey); + if (param == null) + return ""; + return param.PARAVALUE; + } + + public BAS_PARAMETER GetModel(string paraKey) + { + BAS_PARAMETER param = _parameterRepository.Query().FirstOrDefault(m => m.PARAKEY == paraKey); + return param; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/BaseRoleDomain.cs b/code/Zxd.Domain/BaseRoleDomain.cs new file mode 100644 index 0000000..86eeae9 --- /dev/null +++ b/code/Zxd.Domain/BaseRoleDomain.cs @@ -0,0 +1,28 @@ +using DG.EntityFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain +{ + public class BaseRoleDomain : IBasRoseDomain + { + private readonly IRepositoryBase _BaseRoleRepository; + private readonly IBaseRepository _repository; + private readonly IRepositoryBase _WX_SZZYORDERRepository; + + public BaseRoleDomain(IBaseRepository repository) + { + _repository = repository; + _BaseRoleRepository = _repository.GetRepository(); + _WX_SZZYORDERRepository = _repository.GetRepository(); + } + + public async Task test() + { + var codes = _WX_SZZYORDERRepository.Query().Take(10).ToList(); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Config/CacheKeys.cs b/code/Zxd.Domain/Config/CacheKeys.cs new file mode 100644 index 0000000..9083b78 --- /dev/null +++ b/code/Zxd.Domain/Config/CacheKeys.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Config +{ + internal class CacheKeys + { + public const string ProductModuleList = "product_module_list"; + + public const string ProductGroupList = "product_group_list"; + + public const string ProductTypeList = "product_type_list"; + + public const string ProductTeacherList = "product_teacher_list"; + + public const string ProductList = "product_list"; + + public const string StandardType = "standard_product_type"; + + public const string StandardWay = "standard_product_way"; + + public const string DeptmentList = "deptment_list"; + + public const string ModuleList = "module_list"; + + public const string ParameterList = "cache_parameter_list"; + + public const string TokenList = "cache_token_list"; + } +} diff --git a/code/Zxd.Domain/Config/ClientKey.cs b/code/Zxd.Domain/Config/ClientKey.cs new file mode 100644 index 0000000..a5137a4 --- /dev/null +++ b/code/Zxd.Domain/Config/ClientKey.cs @@ -0,0 +1,13 @@ +namespace Zxd.Domain.Config +{ + public class ClientKey + { + public string Id { get; set; } + + public string Name { get; set; } + + public string AccessKey { get; set; } + public string Vi { get; set; } + public string NewAccessKey { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Config/Enum.cs b/code/Zxd.Domain/Config/Enum.cs new file mode 100644 index 0000000..4f752d4 --- /dev/null +++ b/code/Zxd.Domain/Config/Enum.cs @@ -0,0 +1,191 @@ + +using System.ComponentModel; + +namespace Zxd.Domain.Config +{ + #region 注册,认证码表 + + public enum EnumInterfaceErrcode + { + 调用成功 = 10000, + 调用成功且有数据 = 10001,//新增的code + 用户名已存在 = 10002, + 参数错误 = 10003, + 手机号码错误 = 10004, + 系统错误 = 10005, + 用户已经认证 = 10006, + 验证码过期 = 10007, + 该订单已开通不能撤销 = 10008, + 用户无手机号码 = 10009, + 手机号码已认证 = 10010, + 用户付款失败 = 10011, + 无手机号码不能重置密码 = 10012, + 订单已开通只充值 = 10013, + 订单不存在账户充值成功 = 10014, + 非法请求 = 10015, + 支付金额不足开通失败 = 10016, + 数据不存在 = 10017, + 类型已存在不能重复添加 = 10018, + 非认证用户 = 10019, + 该用户没有手机号码 = 10020, + 十五分钟已连续发送三次 = 10021, + 积分不够业务失败 = 10022, + 验证码错误 = 10023, + 已提交不同身份证开户信息请联系客服处理 = 10024, + 该资源已被他人认领 = 10025, + 资源无须覆盖 = 10026, + 该客户的身份证已存在不能重复提交 = 10027, + 此申请已经授权 = 10028, + 不存在此代理商 = 10029, + 不存在此用户 = 10030, + 平台信息出错请审核数据 = 10031, + 此号码的已被使用 = 10032, + 该渠道禁止申请 = 10033, + 已拥有相同或更高版本 = 10034, + 开通则撤销之前低版本 = 10035, + 正在处理 = 10036, + 交易商号已注册好视通 = 10037, + 好视通用户名不能重复注册 = 10038, + 好视通注册失败 = 10039, + 好视通授权失败 = 10040, + 不能重复提交 = 10041, + 无效产品大类 = 10042, + 无效产品小类 = 10043, + 订单已开通 = 10044, + 订单已取消 = 10045, + 支付步骤出错 = 10046, + 订单未开通 = 10047, + 订单不可取消 = 10048, + 该openID已存在绑定 = 10049, + 密码不正确 = 10050, + 该UP账号已存在绑定 = 10051, + 验证码不能重复使用 = 10052, + 该UP账号已被管理员禁止修改密码 = 10053, + 调用成功但有错误 = 10054, + 找不到订单 = 10055, + 此订单状态不能再开通 = 10056, + 文件路径不能为空 = 10057 + } + + #endregion 注册,认证码表 + + #region 系统参数配置 + + public enum Parameter + { + 资源, 转换, 导出资源, 是否开启加密, + ORD_MemoStatistics_01, //工单统计 + ORD_MemoStatistics_ZhenGu, //诊股资源工单统计 + + Sys_Environment_DeptCode,//当前系统部门编码 + Sys_ExlceImport_PhoneRule,//手机号码生成规则 + Sys_ExcelImport_SkipOran,//是否跳过机构验证导入等于配置的机构数据 + Sys_IsShowFXH,//是否显示渤海信息 + Sys_RetrievePwd_Name,//找回密码短信配置 您好,密码找回短信配置:{0}是密码,{1}是帐号 + Is_ShowCustomerMobileArea,//是否显示号码地区 + Sys_HomeTab_Javascript,//系统home页面的主题框架脚本 主页面的js,Tab打开风格JS + Sys_IsFreeze_Wdzm,//是否冻结我的桌面 默认是不冻结可以关闭的true=冻结,false=可以关闭 + Sys_IsMiniCustomerInfo,//显示简单详细资料 + ISVR_AD_CheckUserNameCompetence, + ISVR_AD_upAgentCreateActiveOrder, + ISVR_AD_upAgentOpenOrder, + ISVR_AD_CancelActiveOrder, + ISVR_AD_HstRegUser, + ISVR_AD_HstDelUserName, + ISVR_AD_HstRoomConfig, + ISVR_AD_HstBatchAddUserRight, + ISVR_AD_HstAddUserPower, + ISVR_AD_TbHstRegUser, + ISVR_AD_TbHstRight, + ISVR_AD_TGHstRoomConfig, + ISVR_AD_HstBlackConfig, + + ISVR_IAD_localhostOpenOrder, + ISVR_IAD_localhostSimpleOpenOrder, + ISVR_IAD_localhostCanclOrder, + ISVR_IAD_localhostHstBatchAddUserRight, + ISVR_IAD_localhostHstRoomConfig, + ISVR_IAD_localhostHstDelUserName, + ISVR_IAD_localhostHstRegUser, + ISVR_IAD_localhostHstAddUserPower, + + HQ_RiaService_ActiveMaunl, + + Sms_TencentResetPwdTid, //腾讯云重置密码模板ID + Sms_TencentHgMsgTid, //腾讯云合规消息模板ID + Sms_TencentOpenOrderTid, + Sms_TencentRegisterTid,//腾讯云用户注册模板ID + Sms_TencentOpenOrderDonateTid, + Sms_TencentSign, //腾讯云短信签名 + Sms_TencentPayMsgTid, //腾讯云在线支付消息模板ID + + CustomerCheckData,//质检抓取时间 + Res_EffectAnalysis_01, //资源效果分析 + ISVR_AD_UpdateManager, + + Sys_Bussiness_Code, //营业部Code + Sys_Environment_LogOn, //当前系统部门编码 + WeiXin_OrderCountShowColumn, //微信订单统计产品小类展示列 + WeiXin_WorkAccountInitCount, //客服工作微信号数量 + WeiXIn_SzzyOrderUnPayDayInterval, //上证综研未支付订单间隔天数 + UserCenter_RiaService_AddOrderOpen,//创建订单 + UserCenter_RiaService_OpenOrder,//开通订单 + UserCenter_RiaService_AddOrderOpenFree,//免费订单 + UserCenter_RiaService_refund,//退款接口 + UserCenter_RiaService_closeFreeOrder,//关闭活动免费订单 + UserCenter_RiaService_ResetPwd,//重置密码接口 + UserCenter_RiaService_ResetMobile,//重置手机号接口 + UserCenter_RiaService_UnBindQW,//软件和企业微信关系解绑 + UserCenter_RiaService_ContractSign,//签订合同 + UserCenter_RiaService_Settlement,//和解协议 + UserCenter_RiaService_CancelComplaint,//撤销投诉协议 + UserCenter_RiaService_SignPdf,//合同pdf地址 + UserCenter_RiaService_OrderGet,//订单信息获取 + UserCenter_RiaService_ForceMerge,//调用Node用户中心进行客户合并 + UserCenter_RiaService_UnBind,//调用Node用户中心进行客户解绑 + UserCenter_RiaService_Risk,//获取风险评测信息 + UserCenter_RiaService_Flag,//获取是否适合信息 + + //UserCenter_RiaService_Riske,//风控URL + Sys_ProjectType, //项目类型,1:证券之星广州 2:南京鼎迈 + + Sys_OrderOpenCountByTimeType, //订单开通统计的时间周期 otime:开通时间 arrivaltime:到账时间 + Sys_ShowMobileStartDate, //为空:就都不显示手机 日期:从该日期之后的资源,显示电话 + Sys_UserComBoxAllShow, //员工分组下拉菜单显示所有员工 0:不显示离职 1:显示全部 + WeiXin_GroupLeaderPasueReceiveRes, //主管是否暂停接收资源 1:暂停 0:接收 + WeiXin_TotalPauseReceiveRes, //微信总资源客户数较多暂停接收资源 1:暂停 0:接收 + Sys_CanExportAllocate, //是否能导出资源 + Sys_OrderClientIdKey, //订单加密客户端ID的键名 + Sys_CanShowResMobile, //是否在资源页面显示手机号 + WeiXin_TotalPauseUserNum, //总资源暂停客服人数 + WeiXin_OrderUserNameRequired, //订单用户微信用户名必填项 + WeiXin_IllegalKewords, //合规关键词词配置 + MonthCommission, //月份提成 + WeiXin_CrossDBSzzyOrder, //跨库订单数据 + Sys_QHData, //期货业务 + WeiXin_OfflineResTypeIds, //线下资源类型id + Sys_IsShowMobileOfContent, //是否显示内容中的手机号 + WeiXin_IsShowOpenOrderTip, //是否显示我的微信客户开通订单提示 + Sys_SaleDeptId_Three, //三部的SaleDeptId + Sys_SaleDeptId_OneAndTwo, //一二部的SaleDeptId + Sys_rpt_json_config,//业绩预测配置 + UserCenter_RiaService_RefundContract, //退款合同 + WeiXin_IllegalKewordsDeptConfig,//合规关键词推送deptcode + UserCenter_UserEnter,//用户中心注册接口 + UserCenter_HandelLabel,//用户中心写标签接口 + HG_Level,//合规类型等级 + AI_CallTaskConfig //回访机器人配置 + } + + public enum ParameterGroup + { + ORD_MemoStatistics, + FavoritesCustType, + SystemConfig,//系统配置 + ExternalInterfaceAddress, + SMS_CONFIG, + OrderPayType + } + + #endregion 系统参数配置 +} \ No newline at end of file diff --git a/code/Zxd.Domain/Config/SystemConfig.cs b/code/Zxd.Domain/Config/SystemConfig.cs new file mode 100644 index 0000000..65071de --- /dev/null +++ b/code/Zxd.Domain/Config/SystemConfig.cs @@ -0,0 +1,78 @@ +namespace Zxd.Domain.Config +{ + /// + /// 系统参数 + /// + public class SystemConfig + { + public string Appid { get; set; } + + public string AppSecret { get; set; } + + public string SsoUrl { get; set; } + + public string SsoOrganizationUrl { get; set; } + public string ZXDCoreUrl { get; set; } + + /// + /// 销售线索URL + /// + public string? SalesLeadUrl { get; set; } + + /// + /// CRM号码加密key(clientKey) + /// + public string? CRMClientKey { get; set; } + + /// + /// 推送部门编码 + /// + + public string? DataClientCode { get; set; } + + /// + /// 深海捷固定坐席 + /// + public string? Shj { get; set; } + + /// + /// 客户端密钥 + /// + public List? ClientKey { get; set; } + + /// + /// + /// + + public string DataSyncApiUrl { get; set; } + + /// + /// 短信注册信息 + /// + public string SoftRegisterMsg { get; set; } + + public string SsoTokenUrl { get; set; } + + public string GetSsoOrganizationUrl() + { + return $"{SsoUrl}{SsoOrganizationUrl}"; + } + + public string GetSsoTokenUrl() + { + return $"{SsoUrl}{SsoTokenUrl}"; + } + + /// + /// 资源系统ip地址 + /// + public string CmsUrl { get; set; } + + public string[] ClearCacheUrls { get; set; } + + public string GetAccessKey(string id) + { + return ClientKey?.First(x => x.Id == id).AccessKey ?? ""; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/DeptmentDomain.cs b/code/Zxd.Domain/DeptmentDomain.cs new file mode 100644 index 0000000..a3ef5c5 --- /dev/null +++ b/code/Zxd.Domain/DeptmentDomain.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain +{ + public class DeptmentDomain : IDeptmentDomain + { + private readonly IBaseRepository _repository; + private readonly IRedisManager _redisManager; + + public DeptmentDomain(IBaseRepository repository, + IRedisManager redisManager) + { + _repository = repository; + _redisManager = redisManager; + } + + public async Task> GetDeptments() + { + var key = CacheKeys.DeptmentList; + if (await _redisManager.ExistsAsync(key)) + { + return await _redisManager.GetListAsync(key); + } + var deptments = await _repository.GetRepository() + .QueryIncluding(x => x.DeptmentCampainIds) + .Where(x => x.DeleteType == 0) + .Where(x => x.Id != 1) + .ToListAsync(); + var data = new List(); + foreach (var deptment in deptments) + { + var item = new DeptmentDto() + { + Id = deptment.Id, + Title = deptment.Title, + DeptmentCampains = new List() + }; + if (deptment.DeptmentCampainIds == null) + { + data.Add(item); + continue; + } + foreach (var deptmentCampain in deptment.DeptmentCampainIds) + { + item.DeptmentCampains.Add(new DeptmentCampainDto + { + EndCampainId = deptmentCampain.EndCampainId, + StartCampainId = deptmentCampain.StartCampainId + }); + } + data.Add(item); + } + + await _redisManager.SetAsync(key, data, TimeSpan.FromDays(1)); + Log.Information("ZXD查询Depts了:"+data.ToJson()); + return data; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/AssignQuery.cs b/code/Zxd.Domain/Dto/AssignQuery.cs new file mode 100644 index 0000000..29edfcb --- /dev/null +++ b/code/Zxd.Domain/Dto/AssignQuery.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class WeworkUserAssignDto + { + public WeworkUserAssignDto() + { + } + + public WeworkUserAssignDto(string appuserid, int channel, int curchannel, string remark) : this(1, "com.dongniu", appuserid, string.Empty, channel, curchannel, 0, string.Empty, remark) + { + this.appuserid = appuserid; + this.channel = channel; + this.curchannel = curchannel; + this.remark = remark; + } + + public WeworkUserAssignDto(int apptype, string appid, string appuserid, string unionid, int channel, int curchannel, int type, string livecode, string remark) + { + this.apptype = apptype; + this.appid = appid; + this.appuserid = appuserid; + this.unionid = unionid; + this.channel = channel; + this.curchannel = curchannel; + this.type = type; + this.livecode = livecode; + this.remark = remark; + } + + public int apptype { get; set; } + public string appid { get; set; } + public string appuserid { get; set; } + public string unionid { get; set; } + public int channel { get; set; } + public int curchannel { get; set; } + public int type { get; set; } + public string livecode { get; set; } + public string remark { get; set; } + } + + public class AssignQuery + { + public AssignQuery(string appid, string appuserid, int channel, int curchannel, string remark) : this(appid, appuserid, string.Empty, channel, curchannel, 0, string.Empty, remark, string.Empty, string.Empty, string.Empty) + { + } + + public AssignQuery(string appid, string appuserid, string unionid, int channel, int curchannel, int type, string livecode, string remark, string remarkext, string memo, string eid) + { + this.appid = appid; + this.appuserid = appuserid; + this.unionid = unionid; + this.channel = channel; + this.curchannel = curchannel; + this.type = type; + this.livecode = livecode; + this.remark = remark; + this.remarkext = remarkext; + this.memo = memo; + this.eid = eid; + } + + public string appid { get; set; } + public string appuserid { get; set; } + public string unionid { get; set; } + public int channel { get; set; } + public int curchannel { get; set; } + public int type { get; set; }//1、返回二维码链接、0、不需要返回二码码链接 + public string livecode { get; set; } //活码标识,30字符以内 + public string remark { get; set; }//标记,30字符以内 + public string remarkext { get; set; }//标记补充,30字符以内 + public string memo { get; set; } + public string eid { get; set; }//工号 + } + + public class WeworkUserAssignMessage + { + public int errcode { get; set; } + public string errmsg { get; set; } + public WeworkUserAssignResult data { get; set; } + } + + public class WeworkUserAssignResult + { + public string eid { get; set; } + public int? groupid { get; set; } + public string qr { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Exents/SYNC_PUSH_DTO.cs b/code/Zxd.Domain/Dto/Exents/SYNC_PUSH_DTO.cs new file mode 100644 index 0000000..79edb62 --- /dev/null +++ b/code/Zxd.Domain/Dto/Exents/SYNC_PUSH_DTO.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class SYNC_PUSH_DTO + { + public string jsontext { get; set; } + public string bidatatype { get; set; } + public string deptcode { get; set; } + public int? isbatch { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Resource/CheckUserDTO.cs b/code/Zxd.Domain/Dto/Resource/CheckUserDTO.cs new file mode 100644 index 0000000..8c44a1e --- /dev/null +++ b/code/Zxd.Domain/Dto/Resource/CheckUserDTO.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Resource +{ + public class CheckUserDTO + { + public string Appid { get; set; } + public string Appuserid { get; set; } + } + + public class CheckResidDTO + { + public string Resid { get; set; } + } + + #region 成交保护期 + + public class UserPassInfo + { + public int? GroupId { get; set; } + public int? DeptId { get; set; } + public string? DeptName { get; set; } + public DateTime? OrderPassTime { get; set; } + public DateTime? ProtectTime { get; set; } + public DateTime? FirstPayTime { get; set; } + public decimal? ArrivePrice { get; set; } + public decimal? RefundPrice { get; set; } + public decimal? InCome { get; set; } + public bool? IsProtect { get; set; } + public decimal? BalancePay { get; set; } + } + + #endregion 成交保护期 + + #region 资源保护期 + + public class resoucePassSetting + { + public List deptids { get; set; } = new List { 16, 29, 23, 36, 30 }; + public int protectday { get; set; } = 30; + } + + public class ResourcePassTime + { + /// + /// 最早注册时间 + /// + public DateTime? Regtime { get; set; } + + /// + /// 最早关注时间 + /// + public DateTime? FirstFollowTime { get; set; } + + /// + /// 仍在关注的最早事业部 + /// + public DateTime? FollowTime { get; set; } + + /// + /// 保护时间 + /// + public DateTime? ProtectTime { get; set; } + + /// + /// 事业部 + /// + public int? DeptId { get; set; } + + /// + /// 事业部名称 + /// + public string? DeptName { get; set; } + + /// + /// 是否保护 + /// + public bool? IsProtect { get; set; } = false; + + public int? channel { get; set; } + public string? content { get; set; } + } + + public class ExternaluserModel + { + public string? externaluserid { get; set; } + public int? deptid { get; set; } + public DateTime? ctime { get; set; } + public DateTime? firsttime { get; set; } + public DateTime? unsubscribe_time { get; set; } + public int? subscribe { get; set; } + public int? campainid { get; set; } + public string? title { get; set; } + } + + public class SoftPassModel + { + public int? deptid { get; set; } + public DateTime? ctime { get; set; } + public string? title { get; set; } + public int? campainid { get; set; } + } + + #endregion 资源保护期 + + #region 用户权限详情 + + public class SoftUserNameDetailModel + { + public List OrderInfo { get; set; } = new List(); + public DateTime? MaxRootTime { get; set; } + public bool? canopen { get; set; } + } + + public class OrderDetail + { + public decimal? OrderId { get; set; } + public string? ProductCode { get; set; } + public string? ProductName { get; set; } + public decimal? SzzyorderId { get; set; } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + public bool? IsFree { get; set; } = false; + public string Remark { get; set; } + } + + public class UserModuleApiModel + { + public int ret { get; set; } + public string? message { get; set; } + public Dictionary> moduelData { get; set; } + } + + public class UserModuleModel + { + public string? orderid { get; set; } + public string? productid { get; set; } + public long? start { get; set; } + public long? end { get; set; } + } + + public class ActiveProduct + { + public string ActiveProductCode { get; set; } + public string ActiveProductName { get; set; } + public string DonateDay { get; set; } + public long SzzyOrderId { get; set; } + } + + #endregion 用户权限详情 +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Resource/CmsRequestDto.cs b/code/Zxd.Domain/Dto/Resource/CmsRequestDto.cs new file mode 100644 index 0000000..4807249 --- /dev/null +++ b/code/Zxd.Domain/Dto/Resource/CmsRequestDto.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Resource +{ + public class CmsRequestDto + { + public string? appId { get; set; } + public string? appUserId { get; set; } + public string? deptId { get; set; } + //public string? RequestId { get; set; } + //public DateTime? RequestTime { get; set; } + } + + public class CmsReturnModel + { + public string? appId { get; set; } + public string? appUserId { get; set; } + public string? unionId { get; set; } + public string? resid { get; set; } + public int? deptId { get; set; } + public decimal? regCampainId { get; set; } + public string? scene { get; set; } + public string? sceneName { get; set; } + public int? sceneType { get; set; } + public string? sceneTypeName { get; set; } + public string? ip { get; set; } + public string? cTime { get; set; } + } + + public class CmsResData + { + public int? ret { get; set; } + public string? msg { get; set; } + public string? requestId { get; set; } + public CmsReturnModel data { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Resource/ReSourceDto.cs b/code/Zxd.Domain/Dto/Resource/ReSourceDto.cs new file mode 100644 index 0000000..b94fcba --- /dev/null +++ b/code/Zxd.Domain/Dto/Resource/ReSourceDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class ReSourceDto + { + public string? Content { get; set; } + public string? Clientid { get; set; } + public string? Sign { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Resource/ResAllocationDto.cs b/code/Zxd.Domain/Dto/Resource/ResAllocationDto.cs new file mode 100644 index 0000000..902a3ba --- /dev/null +++ b/code/Zxd.Domain/Dto/Resource/ResAllocationDto.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Resource +{ + /// + /// 资源分配接收接口 + /// + public class ResAllocationDto + { + public string? Id { get; set; } + + /// + /// 分配时间 + /// + public DateTime? Ctime { get; set; } + + /// + /// 平台id + /// + public string? Appid { get; set; } + + /// + /// 平台账号 + /// + public string? Appuserid { get; set; } + + /// + /// 部门id + /// + public string? Deptid { get; set; } + + /// + /// 公海ID + /// + public string? Seaid { get; set; } + + public string? Groupid { get; set; } + public decimal? Eid { get; set; } + + /// + /// 0、 CRM产生 1、分配系统产生 2、企微产生 + /// + public string? Addway { get; set; } + + /// + /// 0:号码资源 1:企业微信资源 + /// + public int? AssignType { get; set; } + + public string? Hhuserid { get; set; } + } + + public class SyncAllocationModel : ResAllocationDto + { + public string? Unionid { get; set; } + + /// + /// 客户ID + /// + public string? Resid { get; set; } + + /// + /// 渠道 + /// + public decimal? Ch { get; set; } + + /// + /// 标签 + /// + public string? CampaignId { get; set; } + + public string? Scene { get; set; } + public string? SceneName { get; set; } + public int? SceneType { get; set; } + public string? SceneTypeName { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Resource/ScreenRecordDto.cs b/code/Zxd.Domain/Dto/Resource/ScreenRecordDto.cs new file mode 100644 index 0000000..fac8ed0 --- /dev/null +++ b/code/Zxd.Domain/Dto/Resource/ScreenRecordDto.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto.Resource +{ + public enum ScreenRecordType + { + 主控人 = 1, + 被控人 = 2 + } + + public class ScreenRecordRequest : SearchPageBase + { + public string? AppId { get; set; } + public int? Type { get; set; } + public int? Eid { get; set; } + public string? Name { get; set; } + public string? ResId { get; set; } + public string? UserName { get; set; } + public DateTime? InitConnectStartTime { get; set; } + public DateTime? InitConnectEndTime { get; set; } + } + + public class ScreenRecordResponse + { + public int? Id { get; set; } + public int? MasterEid { get; set; } + public string? MasterEidStr { get; set; } + public string? MasterResId { get; set; } + public string? MasterUmid { get; set; } + public string? MasterName { get; set; } + public string? MasterUserName { get; set; } + public int? SlaveEid { get; set; } + public string? SlaveEidStr { get; set; } + public string? SlaveResId { get; set; } + public string? SlaveUmid { get; set; } + public string? SlaveName { get; set; } + public string? SlaveUserName { get; set; } + public DateTime? InitConnectTime { get; set; } + public DateTime? RealStartTime { get; set; } + public DateTime? RealEndTime { get; set; } + public string? RealLongTime { get; set; } + public string? AppId { get; set; } + public string? FileUrl { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/Resource/SyncRegUserDto.cs b/code/Zxd.Domain/Dto/Resource/SyncRegUserDto.cs new file mode 100644 index 0000000..79cb4f5 --- /dev/null +++ b/code/Zxd.Domain/Dto/Resource/SyncRegUserDto.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class SyncRegUserDto + { + public string? username { get; set; } + public string? password { get; set; } + public string? mobile { get; set; } + + /// + /// email + /// + public string? em { get; set; } + + /// + /// 平台 + /// + public string? plat { get; set; } + + /// + /// 前端客户端IP + /// + public string? ip { get; set; } + + /// + /// clientip + /// + public string? clientip { get; set; } + + /// + /// 注册时间 + /// + public long? regDate { get; set; } + + public string? eid { get; set; } + + public string? openid { get; set; } + + public string? openplat { get; set; } + public string? unionId { get; set; } + public string? liveCode { get; set; } + public string? regSource { get; set; } + public string? refeid { get; set; } + public int channel { get; set; } + public int? curChannel { get; set; } + public int? groupid { get; set; } + } + + public class SynInnerModel : SyncRegUserDto + { + /// + /// 渠道号 + /// + public string? ch { get; set; } + } + + public class JionActiveDto + { + public string? username { get; set; } + public string? mobile { get; set; } + public string? campaignId { get; set; } + public string? deptcode { get; set; } + public string? datatype { get; set; } + public string? extxml { get; set; } + public string? kword { get; set; } + public string? jsondata { get; set; } + public string? account { get; set; } + public int accounttype { get; set; } + public int? ch { get; set; } + public int? resourcetype { get; set; } + public int? assigntype { get; set; } + public int? eid { get; set; } + public int? groupid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/SalesLeadDto.cs b/code/Zxd.Domain/Dto/SalesLeadDto.cs new file mode 100644 index 0000000..80a2bab --- /dev/null +++ b/code/Zxd.Domain/Dto/SalesLeadDto.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class SalesLeadDto + { + /// + /// 名称 + /// + public string? Name { get; set; } + + /// + /// 连接 + /// + public string? Url { get; set; } + + /// + /// + /// + public string? Appid { get; set; } + + /// + /// + /// + public string? Appuserid { get; set; } + } +} diff --git a/code/Zxd.Domain/Dto/UserInfoDto.cs b/code/Zxd.Domain/Dto/UserInfoDto.cs new file mode 100644 index 0000000..edb04d5 --- /dev/null +++ b/code/Zxd.Domain/Dto/UserInfoDto.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Dto +{ + public class UserInfoDto + { + public string? Resid { get; set; } + } + + + public class CompanyBussiness + { + public string[] soft { get; set; } + public string[] xinmeiti { get; set; } + public int? ProtectTime { get; set; } = 14; + public decimal limitPrice { get; set; } + } + + public class ScreenRecordFile + { + public string MasterDeviceCode { get; set; } + public string SlaveDeviceCode { get; set; } + public DateTime? InitConnectTime { get; set; } + public string FileUrl { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Dto/retMsg.cs b/code/Zxd.Domain/Dto/retMsg.cs new file mode 100644 index 0000000..9d15bf7 --- /dev/null +++ b/code/Zxd.Domain/Dto/retMsg.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain +{ + public class retMsg + { + public bool result { get; set; } + public int retcode { get; set; } + public string retmsg { get; set; } + } + + public class retMsg + { + public bool result { get; set; } + public int retcode { get; set; } + public T retmsg { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/EventBuses/Events/JoinActiveAllDeptEvent.cs b/code/Zxd.Domain/EventBuses/Events/JoinActiveAllDeptEvent.cs new file mode 100644 index 0000000..36fa354 --- /dev/null +++ b/code/Zxd.Domain/EventBuses/Events/JoinActiveAllDeptEvent.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.EventBuses.Events +{ + public class JoinActiveAllDeptEvent + { + public JoinActiveAllDeptEvent(string content, string clientid, string sign, string resid, string resourcetag) + { + this.content = content; + this.clientid = clientid; + this.sign = sign; + this.resid = resid; + this.resourcetag = resourcetag; + } + + public string content { get; set; } + public string clientid { get; set; } + public string sign { get; set; } + public string resid { get; set; } + public string resourcetag { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/EventBuses/Events/JoinActiveEvent.cs b/code/Zxd.Domain/EventBuses/Events/JoinActiveEvent.cs new file mode 100644 index 0000000..f403e04 --- /dev/null +++ b/code/Zxd.Domain/EventBuses/Events/JoinActiveEvent.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.EventBuses.Events +{ + public class JoinActiveEvent + { + public JoinActiveEvent(string content, string clientid, string sign, string deptcode) + { + this.content = content; + this.clientid = clientid; + this.sign = sign; + this.deptcode = deptcode; + } + + public string content { get; set; } + public string clientid { get; set; } + public string sign { get; set; } + public string deptcode { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/EventBuses/Events/SoftUserRegisterEvent.cs b/code/Zxd.Domain/EventBuses/Events/SoftUserRegisterEvent.cs new file mode 100644 index 0000000..7de0a26 --- /dev/null +++ b/code/Zxd.Domain/EventBuses/Events/SoftUserRegisterEvent.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.EventBuses.Events +{ + public class SoftUserRegisterEvent + { + public SoftUserRegisterEvent(string content, string clientid, string sign, string deptcode) + { + this.content = content; + this.clientid = clientid; + this.sign = sign; + this.deptcode = deptcode; + } + + public string content { get; set; } + public string clientid { get; set; } + public string sign { get; set; } + public string deptcode { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IBasParameterDomain.cs b/code/Zxd.Domain/Impl/IBasParameterDomain.cs new file mode 100644 index 0000000..1768d32 --- /dev/null +++ b/code/Zxd.Domain/Impl/IBasParameterDomain.cs @@ -0,0 +1,16 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Impl +{ + public interface IBasParameterDomain : IScopedDependency + { + string GetParameterValue(string paraKey); + + BAS_PARAMETER GetModel(string paraKey); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IBasRoseDomain.cs b/code/Zxd.Domain/Impl/IBasRoseDomain.cs new file mode 100644 index 0000000..06a05cd --- /dev/null +++ b/code/Zxd.Domain/Impl/IBasRoseDomain.cs @@ -0,0 +1,14 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Impl +{ + public interface IBasRoseDomain : IScopedDependency + { + Task test(); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IDeptmentDomain.cs b/code/Zxd.Domain/Impl/IDeptmentDomain.cs new file mode 100644 index 0000000..14e99e8 --- /dev/null +++ b/code/Zxd.Domain/Impl/IDeptmentDomain.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Impl +{ + public interface IDeptmentDomain : IScopedDependency + { + Task> GetDeptments(); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IReSourceDomain.cs b/code/Zxd.Domain/Impl/IReSourceDomain.cs new file mode 100644 index 0000000..e25972d --- /dev/null +++ b/code/Zxd.Domain/Impl/IReSourceDomain.cs @@ -0,0 +1,36 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Domain.Dto; +using Zxd.Domain.Dto.Resource; + +namespace Zxd.Domain.Impl +{ + public interface IReSourceDomain : IScopedDependency + { + Task SyncRegUser(SyncRegUserDto activeModel, string clientid); + + Task Join(JionActiveDto postData, string clientid); + + Task Allocation(ResAllocationDto resAllocationDto, string clientid); + + Task GetUserCanOpenOrder(CheckUserDTO dto); + + Task GetUserCanOpenOrderByResid(string? umid); + + Task> GetUserProtectInfo(CheckUserDTO dto); + + Task InitUserProtect(int type); + + Task> GetSoftUserByResid(string resid); + + Task GetResoucePassTime(CheckUserDTO resid); + + Task GetResoucePassTimeBySql(CheckUserDTO dto); + + Task GetSoftUserDetail(string softUserName); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IRegUserDomain.cs b/code/Zxd.Domain/Impl/IRegUserDomain.cs new file mode 100644 index 0000000..a5a941c --- /dev/null +++ b/code/Zxd.Domain/Impl/IRegUserDomain.cs @@ -0,0 +1,17 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Domain.Dto; + +namespace Zxd.Domain.Impl +{ + public interface IRegUserDomain : IScopedDependency + { + Task RegUser(SynInnerModel dto); + + void SetQuantity(int ch, int eid, int gid, string resid); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IResCustomerDomain.cs b/code/Zxd.Domain/Impl/IResCustomerDomain.cs new file mode 100644 index 0000000..3762e17 --- /dev/null +++ b/code/Zxd.Domain/Impl/IResCustomerDomain.cs @@ -0,0 +1,18 @@ +using DG.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Impl +{ + public interface IResCustomerDomain : IScopedDependency + { + Task ResgisterCustomer(string CNumber, string ResId, string CustomerFrom, string customerDetailXml = null); + + Task SetQuantity(int ch, int eid, int salegroupid); + + Task ContractUser(string resid, string userName); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IScreenRecordDomain.cs b/code/Zxd.Domain/Impl/IScreenRecordDomain.cs new file mode 100644 index 0000000..69de0ad --- /dev/null +++ b/code/Zxd.Domain/Impl/IScreenRecordDomain.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Domain.Dto.Resource; + +namespace Zxd.Domain.Impl +{ + public interface IScreenRecordDomain : IScopedDependency + { + Task ScreenRecord(ScreenRecord postData); + Task FileRecord(ScreenRecordFile postData); + Task> GetScreenRecordList(ScreenRecordRequest postData); + } +} diff --git a/code/Zxd.Domain/Impl/ISystemConfigDomain.cs b/code/Zxd.Domain/Impl/ISystemConfigDomain.cs new file mode 100644 index 0000000..d903635 --- /dev/null +++ b/code/Zxd.Domain/Impl/ISystemConfigDomain.cs @@ -0,0 +1,9 @@ +namespace Zxd.Domain.Impl +{ + public interface ISystemConfigDomain : IScopedDependency + { + SystemConfig GetSystemConfig(); + + ClientKey GetClientKey(string clientId); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Impl/IUserInfoDomain.cs b/code/Zxd.Domain/Impl/IUserInfoDomain.cs new file mode 100644 index 0000000..a7d088d --- /dev/null +++ b/code/Zxd.Domain/Impl/IUserInfoDomain.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.UserCenter; + +namespace Zxd.Domain.Impl +{ + public interface IUserInfoDomain : IScopedDependency + { + Task> GetUserInfoByApi(string? appid, string? userid); + + Task> GetUserInfoByApi(string? resid); + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/ReSourceDomain.cs b/code/Zxd.Domain/ReSourceDomain.cs new file mode 100644 index 0000000..9bf7777 --- /dev/null +++ b/code/Zxd.Domain/ReSourceDomain.cs @@ -0,0 +1,922 @@ +using System.Text; +using System.Web; +using Zxd.Domain.Dto.Resource; +using Serilog; +using Zxd.Domain.Impl; +using Zxd.Entity.Zxd.Order; +using MySqlConnector; +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using Zxd.EntityFramework; + +namespace Zxd.Domain +{ + public class ReSourceDomain : IReSourceDomain + { + private readonly IRegUserDomain _reguserService; + private readonly IRepositoryBase _companyChannelRepository; + private readonly IBaseRepository _repository; + private readonly IRepositoryBase _resourcemobileRepository; + private readonly IRepositoryBase _customeruserRepository; + private readonly IRepositoryBase _cmsLogRepository; + private readonly IRepositoryBase _customerRepository; + private readonly IBaseRepository _cmsrepository; + private readonly IRepositoryBase _resPassRepository; + private readonly ISystemConfigDomain _systemConfigService; + private readonly IBasParameterDomain _basParameterService; + private readonly IResCustomerDomain _resCustomerService; + private readonly IServiceProvider _serviceProvider; + private readonly IMapper _mapper; + private readonly IHttpClient _httpClient; + + public ReSourceDomain(IServiceProvider serviceProvider, + IBaseRepository repository, IBaseRepository crmrepository, IRegUserDomain reguserService, + IBasParameterDomain basParameterService, ISystemConfigDomain systemConfigService, IBaseRepository cmsrepository, + IBaseRepository dbcmsrepository, + IResCustomerDomain resCustomerService, IMapper mapper, IUserInfoDomain userInfoDomain, IHttpClient httpClient) + { + _httpClient = httpClient; + _serviceProvider = serviceProvider; + _reguserService = reguserService; + _repository = repository; + _cmsrepository = cmsrepository; + _companyChannelRepository = _repository.GetRepository(); + _resourcemobileRepository = _repository.GetRepository(); + _customeruserRepository = _repository.GetRepository(); + _cmsLogRepository = _repository.GetRepository(); + _basParameterService = basParameterService; + _customerRepository = _repository.GetRepository(); + _resPassRepository = _cmsrepository.GetRepository(); + _mapper = mapper; + _systemConfigService = systemConfigService; + _resCustomerService = resCustomerService; + _httpClient = httpClient; + } + + #region 注册同步 + + public async Task SyncRegUser(SyncRegUserDto activeModel, string clientid) + { + bool isTrue = true; + string retMsg = string.Empty; + var client = _systemConfigService.GetClientKey(clientid); + try + { + if (string.IsNullOrEmpty(activeModel.username)) + { + retMsg = (new { result = false, retcode = (int)EnumInterfaceErrcode.参数错误 }).ToJson(); + retMsg = SecurityHelper.EncyptData(retMsg, client.AccessKey); + return retMsg; + } + } + catch (Exception ex) + { + retMsg = (new { result = false, retcode = (int)EnumInterfaceErrcode.参数错误 }).ToJson(); + isTrue = false; + Log.Error(string.Concat("当前请求" + activeModel.ToJson() + "|", ex.ToString())); + } + var innerModel = _mapper.Map(activeModel); + if (isTrue) + { + try + { + if (innerModel.curChannel.HasValue) + { + innerModel.ch = innerModel.curChannel.ToString(); + } + await _reguserService.RegUser(innerModel); + + retMsg = (new { result = true, retcode = (int)EnumInterfaceErrcode.调用成功 }).ToJson(); + + #region 发布用户注册事件 + + try + { + //根据渠道号获取部门编码 + var ch = int.Parse(innerModel.ch); + var company = await _companyChannelRepository.FirstOrDefaultAsync(p => p.Min <= ch && p.Max >= ch); + + var c = SecurityHelper.EncyptData(innerModel.ToJson(), client.AccessKey); + var s = SecurityHelper.SignData(c, client.AccessKey); + + HandleRegUser(new SoftUserRegisterEvent(c, client.Id, s, company != null ? company.CompanyCode : "DNZZ")); + } + catch (Exception exx) + { + Log.Error("发布注册用户事件错误:" + exx.ToString()); + } + + #endregion 发布用户注册事件 + } + catch (Exception ex) + { + Log.Error("同步注册用户出现异常" + ex); + retMsg = (new + { + result = false, + retcode = (int)EnumInterfaceErrcode.系统错误 + }).ToJson(); + } + finally + { + //CacheHelper.RemoveRegCache(activeModel.username); + } + } + return retMsg; + } + + /// + /// + /// + /// + public void HandleRegUser(SoftUserRegisterEvent @event) + { + try + { + Log.Error($"注册用户事件执行:" + @event.ToJson()); + var host = _systemConfigService.GetSystemConfig().DataSyncApiUrl; + var url = host + "/api/DataSync"; + + var para = new SYNC_PUSH_DTO() + { + bidatatype = "Client_Soft_User", + deptcode = @event.deptcode, + jsontext = new { @event.content, @event.clientid, @event.sign }.ToJson() + }; + //LogHelper.Info("para:" + para.ToJson()); + var rep = HttpHelper.PostAjaxData(url, para.ToJson(), Encoding.UTF8); + //LogHelper.Info("rep:" + rep); + var ret = JsonHelper.FromJson(rep); + if (!ret.result) + Log.Error("接口 SoftUserRegisterEventHandler 写入失败!"); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + + #endregion 注册同步 + + #region 活动报名 + + /// + /// 用户活动申请 + /// + /// + /// + /// + /// + public async Task Join(JionActiveDto activeModel, string clientid) + { + string retMsg = string.Empty; + var clientKey = _systemConfigService.GetSystemConfig().CRMClientKey; + var client = _systemConfigService.GetClientKey(clientid); + try + { + string resid = string.Empty; + Log.Information("活动资源进入:" + activeModel.ToJson()); + + if (string.IsNullOrWhiteSpace(activeModel.campaignId) && string.IsNullOrWhiteSpace(activeModel.account)) + { + retMsg = (new { result = false, retcode = (int)EnumInterfaceErrcode.参数错误 }).ToJson(); + retMsg = SecurityHelper.EncyptData(retMsg, client.AccessKey); + return HttpUtility.UrlEncode(retMsg); + } + if (activeModel.accounttype == 0) + { + //手机号 + activeModel.mobile = activeModel.account; + } + else if (activeModel.accounttype == 1) + { + //用户名 + activeModel.username = activeModel.account; + } + else if (activeModel.accounttype == 2) + { + //客户ID + resid = activeModel.account; + } + else + { + return SecurityHelper.EncyptData((new { result = false, retcode = (int)EnumInterfaceErrcode.参数错误 }).ToJson(), client.AccessKey); + } + + if (!string.IsNullOrEmpty(activeModel.mobile)) + { + resid = ResUtil.CreateResId(activeModel.mobile); + await _resCustomerService.ResgisterCustomer(activeModel.mobile, resid, activeModel.campaignId); + } + else + { + if (!string.IsNullOrEmpty(resid)) + { + var m = _resourcemobileRepository.Query().FirstOrDefault(p => p.RESID == resid); + activeModel.mobile = SecurityHelper.DecyptData(m.MOBILE, client.AccessKey); + } + else + { + var cust = _customeruserRepository.Query().FirstOrDefault(p => p.USERNAME == activeModel.username); + if (cust == null) + { + retMsg = SecurityHelper.EncyptData((new { result = false, retcode = (int)EnumInterfaceErrcode.不存在此用户 }).ToJson(), client.AccessKey); + return retMsg; + } + else + { + resid = cust.RESID; + var m = _resourcemobileRepository.Query().FirstOrDefault(p => p.RESID == resid); + activeModel.mobile = SecurityHelper.DecyptData(m.MOBILE, client.AccessKey); + } + } + } + + if (activeModel.campaignId == "TNB26001") + { + activeModel.deptcode = "QBJZ"; + } + + if (activeModel.ch.HasValue) + { + var ch = activeModel.ch.GetValueOrDefault(); + var company = await _companyChannelRepository.FirstOrDefaultAsync(p => p.Min <= ch && p.Max >= ch); + //LogHelper.Info("根据渠道获取推送码:" + company.ToJson()); + if (company != null) + { + activeModel.deptcode = company.CompanyCode; + } + } + ///传过来的aes加密 需要按照之前加密 + var c = SecurityHelper.EncyptData(activeModel.ToJson(), client.AccessKey); + var s = SecurityHelper.SignData(c, client.AccessKey); + if (!string.IsNullOrEmpty(activeModel.deptcode)) + { + //推送到分部 + if (activeModel.assigntype.HasValue && activeModel.assigntype.Value == 1 && activeModel.eid.HasValue) + { + HandleJoinActive(new JoinActiveEvent(c, clientid, s, activeModel.deptcode)); + } + else + { + HandleJoinActive(new JoinActiveEvent(c, clientid, s, activeModel.deptcode)); + } + } + else + { + //如果没有部门编码 + HandleJoinAllDeptActive(new JoinActiveAllDeptEvent(c, clientid, s, resid, activeModel.campaignId)); + } + + retMsg = (new { result = true, retcode = (int)EnumInterfaceErrcode.调用成功, ResId = resid }).ToJson(); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + retMsg = (new { result = false, retcode = (int)EnumInterfaceErrcode.系统错误, ResId = "" }).ToJson(); + } + return HttpUtility.UrlEncode(SecurityHelper.EncyptData(retMsg, client.AccessKey)); + } + + public void HandleJoinActive(JoinActiveEvent @event) + { + try + { + Log.Information("活动事件执行:" + @event.ToJson()); + + var host = _systemConfigService.GetSystemConfig().DataSyncApiUrl; + var url = host + "/api/DataSync"; + + var para = new SYNC_PUSH_DTO() + { + bidatatype = "Client_Active", + deptcode = @event.deptcode, + jsontext = new { @event.content, @event.clientid, @event.sign }.ToJson(), + isbatch = 1 + }; + //LogHelper.Info("para:" + para.ToJson()); + //LogHelper.Info("url:" + url); + var rep = HttpHelper.PostAjaxData(url, para.ToJson(), Encoding.UTF8); + //LogHelper.Info("rep:" + rep); + var ret = JsonHelper.FromJson(rep); + if (!ret.result) + Log.Error("接口 ApplyResEventHandler 写入失败!"); + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + + public void HandleJoinAllDeptActive(JoinActiveAllDeptEvent @event) + { + try + { + Log.Information("推送开通订单事件执行:" + @event.ToJson()); + + var host = _systemConfigService.GetSystemConfig().DataSyncApiUrl; + var url = host + "/api/DataSync"; + + var list = new List() { "QBJZ", "QBJX", "DNZZ" }; + //var list = _cache.GetList_innerCompany().Where(p => p.SYSTEMCODE != null).Select(p => p.SYSTEMCODE); + + foreach (var item in list) + { + var para = new SYNC_PUSH_DTO() + { + bidatatype = "Client_ActiveAllDept", + deptcode = item, + jsontext = new { @event.content, @event.clientid, @event.sign, @event.resid, @event.resourcetag }.ToJson() + }; + + var rep = HttpHelper.PostAjaxData(url, para.ToJson(), Encoding.UTF8); + var ret = JsonHelper.FromJson(rep); + if (!ret.result) + Log.Error("接口 JoinActiveAllDeptEventHandler 写入失败!"); + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + } + + /// + /// 资源分配接口 + /// + /// + /// + public async Task Allocation(ResAllocationDto activeModel, string clientid) + { + try + { + CMS_QIWEI_POSTLOG cmslog = new CMS_QIWEI_POSTLOG() + { + Appid = activeModel?.Appid, + Appuserid = activeModel?.Appuserid, + jsondata = activeModel?.ToJson(), + Deptid = activeModel?.Deptid, + ctime = DateTime.Now, + STATUS = 0 + }; + retMsg retMsg = new retMsg() + { + result = true, + }; + var client = _systemConfigService.GetClientKey(clientid); + Log.Information("资源分配执行:" + activeModel.ToJson()); + //不是企微资源 先拦截 + if (activeModel.AssignType != 1) + { + Log.Error("非企微资源,先拦截"); + /* cmslog.Reason = "非企微资源,先拦截"; + await _cmsLogRepository.InsertAsync(cmslog);*/ + return retMsg.ToJson(); + //throw new Exception($"非企微资源,先拦截"); + } + CmsRequestDto cmsRequestDto = new CmsRequestDto() + { + appId = activeModel.Appid, + appUserId = activeModel.Appuserid, + deptId = activeModel.Deptid, + }; + var cmsUrl = $"{_systemConfigService.GetSystemConfig().CmsUrl}resource/query/i"; + var cmsData = HttpHelper.PostAjaxData(cmsUrl, cmsRequestDto.ToJson(), Encoding.UTF8); + cmslog.CmsData = cmsData; + var cmsModel = JsonHelper.FromJson(cmsData); + var innerModel = _mapper.Map(activeModel); + if (cmsModel == null || cmsModel.ret != 0 || cmsModel.data == null) + { + // Log.Error($"参数错误,获取不到资源系统信息【{cmsRequestDto.ToJson()}】"); + cmslog.Reason = "参数错误,获取不到资源系统信息"; + await _cmsLogRepository.InsertAsync(cmslog); + return retMsg.ToJson(); + //throw new Exception($"参数错误,获取不到资源系统信息"); + } + innerModel.Ch = cmsModel.data.regCampainId; + innerModel.Unionid = cmsModel.data.unionId; + innerModel.Resid = cmsModel.data.resid; + innerModel.CampaignId = cmsModel.data.scene; + innerModel.Ctime = string.IsNullOrEmpty(cmsModel.data.cTime) ? null : Convert.ToDateTime(cmsModel.data.cTime); + innerModel.Scene = cmsModel.data.scene; + innerModel.SceneName = cmsModel.data.sceneName; + innerModel.SceneType = cmsModel.data.sceneType; + innerModel.SceneTypeName = cmsModel.data.sceneTypeName; + var company = await _companyChannelRepository.FirstOrDefaultAsync(p => p.Min <= Convert.ToInt32(innerModel.Ch) && p.Max >= Convert.ToInt32(innerModel.Ch)); + if (company == null) + { + cmslog.Reason = $"找不到对应的渠道号{innerModel.Ch}"; + await _cmsLogRepository.InsertAsync(cmslog); + return retMsg.ToJson(); + //throw new Exception($"找不到对应的渠道号{innerModel.Ch}"); + } + var syncCode = _basParameterService.GetParameterValue("QiWeiSyncCode"); + if (string.IsNullOrWhiteSpace(syncCode) || !syncCode.Split(',').ToList().Contains(company?.CompanyCode)) + { + cmslog.Reason = $"没有配置syncCode,【{company.CompanyCode}】已跳过"; + await _cmsLogRepository.InsertAsync(cmslog); + return retMsg.ToJson(); + } + var host = _systemConfigService.GetSystemConfig().DataSyncApiUrl; + var url = host + "/api/DataSync"; + var newcontent = SecurityHelper.EncyptData(innerModel.ToJson(), client.AccessKey); + var newsign = SecurityHelper.SignData(newcontent, client.AccessKey); + var para = new SYNC_PUSH_DTO() + { + bidatatype = "Client_Res_Allocation", + deptcode = company?.CompanyCode, + jsontext = new { content = newcontent, clientid, sign = newsign }.ToJson(), + isbatch = 1 + }; + var rep = HttpHelper.PostAjaxData(url, para.ToJson(), Encoding.UTF8); + Log.Information($"请求中心点接口:【{url}】【{para.ToJson()}】返回【{rep}】"); + var ret = JsonHelper.FromJson(rep); + if (!ret.result) + { + Log.Error($"接口 DataSync 写入失败!{ret.retmsg}"); + throw new Exception($"接口 DataSync 写入失败!{ret.retmsg}"); + } + cmslog.STATUS = 1; + await _cmsLogRepository.InsertAsync(cmslog); + return ret.ToJson(); + } + catch (Exception ex) + { + Log.Error($"分配资源出错{ex.Message}"); + throw new Exception(ex.Message); + } + } + + #endregion 活动报名 + + public async Task GetUserCanOpenOrder(CheckUserDTO dto) + { + await using var scope = _serviceProvider.CreateAsyncScope(); + var userInfoDomain = scope.ServiceProvider.GetRequiredService(); + var zxdRepository = scope.ServiceProvider.GetRequiredService>(); + var userInfoList = await userInfoDomain.GetUserInfoByApi(dto.Appid, dto.Appuserid); + var canopenorder = false; + var usernames = userInfoList.Where(x => x.appid == "com.dongniu").Select(x => x.appuserid).ToList(); + if (await zxdRepository.GetRepository().Query() + .AnyAsync(x => usernames.Contains(x.Username) && x.Status == 1)) + { + canopenorder = true; + } + + return canopenorder; + } + + public async Task GetUserCanOpenOrderByResid(string? resid) + { + if (string.IsNullOrEmpty(resid)) + { + throw new ApiException("客户id不能为空"); + } + await using var scope = _serviceProvider.CreateAsyncScope(); + var userInfoDomain = scope.ServiceProvider.GetRequiredService(); + var zxdRepository = scope.ServiceProvider.GetRequiredService>(); + var userInfoList = await userInfoDomain.GetUserInfoByApi(resid); + var canopenorder = false; + var usernames = userInfoList.Where(x => x.appid == "com.dongniu").Select(x => x.appuserid).ToList(); + if (await zxdRepository.GetRepository().Query() + .AnyAsync(x => usernames.Contains(x.Username) && x.Status == 1)) + { + canopenorder = true; + } + + return canopenorder; + } + + public async Task> GetUserProtectInfo(CheckUserDTO dto) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var res = new List(); + using var scope = _serviceProvider.CreateAsyncScope(); + var userInfoDomain = scope.ServiceProvider.GetRequiredService(); + var resPassRepository = scope.ServiceProvider.GetRequiredService>(); + var userInfoList = await userInfoDomain.GetUserInfoByApi(dto.Appid, dto.Appuserid); + var resids = userInfoList.Where(n => !string.IsNullOrWhiteSpace(n.resid)).Select(n => n.resid).Distinct().ToList(); + if (resids.Count == 0) + { + return res; + } + var passTimeInfoList = await resPassRepository.Query().Where(n => resids.Contains(n.RESID)).ToListAsync(); + var deptCodes = passTimeInfoList.GroupBy(n => new { n.Deptid, n.GroupId, n.DeptName }).ToList(); + foreach (var code in deptCodes) + { + var passInfo = passTimeInfoList.Where(n => n.Deptid == code.Key.Deptid).ToList(); + var info = new UserPassInfo + { + DeptId = code.Key.Deptid, + GroupId = code.Key.GroupId, + DeptName = code.Key.DeptName, + OrderPassTime = passInfo.Max(n => n.orderpasstime), + ProtectTime = passInfo.Max(n => n.protecttime), + FirstPayTime = passInfo.Min(n => n.firstPayTime), + ArrivePrice = passInfo.Sum(n => n.arrivalpay), + RefundPrice = passInfo.Sum(n => n.refundpay), + InCome = passInfo.Sum(n => n.inpay), + BalancePay = passInfo.Sum(n => n.balancepay) + }; + info.IsProtect = info.ProtectTime == null || info.ProtectTime < DateTime.Now ? false : true; + res.Add(info); + } + + stopwatch.Stop(); + Log.Warning($"GetUserProtectInfo:{stopwatch.ElapsedMilliseconds}"); + return res; + } + + /// + /// + /// java长整型日期,毫秒为单位 + /// + private DateTime JavaLongToDateTime(long timeJavaLong) + { + var dt1970 = new DateTime(1970, 1, 1, 0, 0, 0); + var tricks1970 = dt1970.Ticks;//1970年1月1日刻度 + var timeTricks = tricks1970 + timeJavaLong * 10000;//日志日期刻度 + return new DateTime(timeTricks).AddHours(8);//转化为DateTime + } + + /// + /// + /// + /// + public async Task InitUserProtect(int type) + { + //var orderList = await _repository.GetRepository().Query().Where(n => !string.IsNullOrWhiteSpace(n.activeproductext)).ToListAsync(); + + var passTimeInfoList = await _resPassRepository.Query().Select(n => n.RESID).Distinct().ToListAsync(); + foreach (var passInfo in passTimeInfoList) + { + Log.Information($"更新订单【{passInfo}】"); + var url = "http://120.77.165.155:8089/Api/Customer/initCustomerPasstime"; + var postData = new + { + resId = string.Join(",", passInfo) + }; + Log.Information($"初始化【{postData.ToJson()}】条数据"); + var sss = HttpHelper.PostAjaxData(url, postData.ToJson(), Encoding.UTF8); + } + + /*Log.Information($"L2_SOFT_ORDER开始处理"); + var orderList = await _repository.GetRepository().Query().Where(n => !string.IsNullOrWhiteSpace(n.activeproductext)).ToListAsync(); + Log.Information($"orderList {orderList.Count}"); + var resids = orderList.Select(n => n.RESID).Distinct().ToList(); + var freeList = await _repository.GetRepository().Query().Where(n => (!string.IsNullOrWhiteSpace(n.WEBORDERID) && !n.MainOrderId.HasValue && resids.Contains(n.RESID)) || n.ORDERTYPE == 4).ToListAsync(); + Log.Information($"L2_SOFT_ORDER {freeList.Count}"); + foreach (var order in freeList) + { + Log.Information($"找到免费订单 【{order.ORDERID}】【{order.WEBORDERID}】"); + var ss = orderList.FirstOrDefault(n => n.activeproductext.Contains(order.WEBORDERID)); + if (ss != null) + { + Log.Information($"刷新订单【{order.ORDERID}】【{ss.ORDERID}】"); + order.MainOrderId = ss.ORDERID; + order.sourcetype = 4; + order.ORDERTYPE = 1; + order.deptid = ss.Deptid; + order.deptName = ss.DeptName; + order.groupid = ss.GroupId; + await _repository.GetRepository().UpdateAsync(order); + Log.Information($"更新订单【{order.ORDERID}】【{ss.ORDERID}】"); + var url = "http://120.77.165.155:8089/Api/Customer/initCustomerPasstime"; + var postData = new + { + resId = string.Join(",", order.RESID) + }; + Log.Information($"初始化【{postData.ToJson()}】条数据"); + var sss = HttpHelper.PostAjaxData(url, postData.ToJson(), Encoding.UTF8); + } + }*/ + } + + public async Task> GetSoftUserByResid(string resid) + { + List res = new List(); + var resids = resid.Split(",").ToList(); + if (resids.Count == 0) + { + return res; + } + var customerQuery = _customerRepository.Query(); + var allresid = (from a in customerQuery + join b in customerQuery on a.CUSTOMERID equals b.CUSTOMERID + where resids.Contains(b.RESID) + select a.RESID).ToList(); + var passTimeInfoList = await _resPassRepository.Query().Where(n => allresid.Contains(n.RESID)).ToListAsync(); + var deptCodes = passTimeInfoList.GroupBy(n => new { n.Deptid, n.GroupId, n.DeptName }).ToList(); + foreach (var code in deptCodes) + { + var passInfo = passTimeInfoList.Where(n => n.Deptid == code.Key.Deptid).ToList(); + UserPassInfo info = new UserPassInfo + { + DeptId = code.Key.Deptid, + GroupId = code.Key.GroupId, + DeptName = code.Key.DeptName, + OrderPassTime = passInfo.Max(n => n.orderpasstime), + ProtectTime = passInfo.Max(n => n.protecttime), + FirstPayTime = passInfo.Min(n => n.firstPayTime), + ArrivePrice = passInfo.Sum(n => n.arrivalpay), + RefundPrice = passInfo.Sum(n => n.refundpay), + InCome = passInfo.Sum(n => n.inpay), + BalancePay = passInfo.Sum(n => n.balancepay) + }; + info.IsProtect = info.ProtectTime == null || info.ProtectTime < DateTime.Now ? false : true; + res.Add(info); + } + return res; + } + + public async Task GetResoucePassTime(CheckUserDTO dto) + { + ResourcePassTime res = new ResourcePassTime(); + using var scope = _serviceProvider.CreateAsyncScope(); + var userInfoDomain = scope.ServiceProvider.GetRequiredService(); + var sourcePassRepository = scope.ServiceProvider.GetRequiredService>(); + var basParameterService = scope.ServiceProvider.GetRequiredService(); + + var userInfoList = await userInfoDomain.GetUserInfoByApi(dto.Appid, dto.Appuserid); + var uidfilter = userInfoList.Where(n => !string.IsNullOrWhiteSpace(n.uid)).Select(n => Convert.ToInt32(n.uid)).Distinct().ToList(); + var sourcepassList = await sourcePassRepository.Query().Where(n => uidfilter.Contains(n.uid)).ToListAsync(); + var parakey = basParameterService.GetParameterValue("InComeResourceSetting"); + if (string.IsNullOrWhiteSpace(parakey)) + { + throw new Exception("没找到相关的资源保护期过期配置InComeResourceSetting"); + } + var setting = JsonHelper.FromJson(parakey); + sourcepassList = sourcepassList.Where(n => n.deptid.HasValue && setting.deptids.Contains(n.deptid.Value)).ToList(); + if (sourcepassList.Count == 0) + { + return res; + } + //最早注册时间 + var regData = sourcepassList.Where(n => n.regtime.HasValue).OrderBy(n => n.regtime).FirstOrDefault(); + res.Regtime = regData?.regtime; + //最早关注事业部 + var firstFollow = sourcepassList.Where(n => n.firstfollowtime.HasValue).OrderBy(n => n.firstfollowtime).FirstOrDefault(); + res.FirstFollowTime = firstFollow?.firstfollowtime; + //仍在关注的最早事业部 + var nowFollow = sourcepassList.Where(n => n.followtime.HasValue).OrderBy(n => n.followtime).FirstOrDefault(); + res.FollowTime = nowFollow?.firstfollowtime; + //判断最早加好友时间 是否大于注册时间 + var type = "follow"; + if (res.Regtime.HasValue) + { + type = !res.FirstFollowTime.HasValue ? "reg" : res.Regtime < res.FirstFollowTime ? "reg" : "follow"; + } + if (type == "reg") + { + res.ProtectTime = res.Regtime.Value.AddDays(setting.protectday); + } + else + { + res.ProtectTime = res.FirstFollowTime.Value.AddDays(setting.protectday); + } + //有关注 取 还在关注状态下的部门 否则不保护 + if (nowFollow != null) + { + res.DeptId = nowFollow.deptid; + res.DeptName = nowFollow.deptname; + res.IsProtect = res.ProtectTime == null || res.ProtectTime < DateTime.Now ? false : true; + } + return res; + } + + public async Task GetResoucePassTimeBySql(CheckUserDTO dto) + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + ResourcePassTime res = new ResourcePassTime(); + using var scope = _serviceProvider.CreateAsyncScope(); + var userInfoDomain = scope.ServiceProvider.GetRequiredService(); + var cmsrepository = scope.ServiceProvider.GetRequiredService>(); + var dbcmsrepository = scope.ServiceProvider.GetRequiredService>(); + var setting = new resoucePassSetting(); //写死保护期30 和对应部门 + + var deptidFilter = string.Join(",", setting.deptids); + var userInfoList = await userInfoDomain.GetUserInfoByApi(dto.Appid, dto.Appuserid); + var externaluserid = userInfoList.Select(n => $"'{n.appuserid}'").Distinct().ToList(); + if (externaluserid.Count == 0) + { + res.content = $"用户中心找不到对应的用户{dto.Appid}【{dto.Appuserid}】"; + Log.Error($"{res.content}"); + return res; + } + var exteruserfilter = string.Join(",", externaluserid); + MySqlParameter[] param = new MySqlParameter[] { }; + //取所有的好友关系 按照事业部分组 + var sql = $@"SELECT a.deptid,regdate as ctime,ctime as firsttime,a.subscribe,a.first_unsubscribe_time as unsubscribe_time,d.title,d.campainid,a.externaluserid FROM dncms.weworkexternaluser AS a + JOIN dncmsbase.Deptment d on a.deptid = d.id + WHERE a.`deptid` IN ({deptidFilter}) and a.externaluserid in ({exteruserfilter})"; + var extUserList = await dbcmsrepository.ExecuteSqlToListAsync(sql, param); + extUserList = extUserList.OrderBy(n => n.firsttime).ToList(); + //首次关注时间 + var firstFollow = extUserList.FirstOrDefault(); + res.FirstFollowTime = firstFollow?.firsttime; + //取当前仍在关注状态的最早的事业部作为保护事业部 + var follow = extUserList.Where(n => n.subscribe == 1).GroupBy(n => new { n.deptid, n.title, n.campainid }).Select(n => new { deptid = n.Key.deptid, deptname = n.Key.title, channel = n.Key.campainid, ctime = n.Min(x => x.ctime) }).OrderBy(n => n.ctime).FirstOrDefault(); + res.FollowTime = follow?.ctime; + //取软件注册时间 + var softusersql = $@" select a.*,d.title,d.campainid from (SELECT a.deptid,MIN(a.regdate) as ctime FROM dncmsbase.accountsoftuser AS a where + a.userid in ({exteruserfilter}) AND a.`deptid` IN ({deptidFilter}) + GROUP BY a.deptid)a + JOIN dncmsbase.Deptment d on a.deptid = d.id "; + var softPassModel = await cmsrepository.ExecuteSqlToListAsync(softusersql, param); + var register = softPassModel.OrderBy(n => n.ctime).FirstOrDefault(); + res.Regtime = register?.ctime; + var type = "follow"; + var content = ""; + if (res.Regtime.HasValue) + { + type = !res.FirstFollowTime.HasValue ? "reg" : res.Regtime < res.FirstFollowTime ? "reg" : "follow"; + } + if (type == "reg") + { + res.ProtectTime = res.Regtime.Value.AddDays(setting.protectday); + content += $"最早注册时间【{res.Regtime}】"; + //有关注 取 还在关注状态下的部门 否则不保护 + res.IsProtect = res.ProtectTime == null || res.ProtectTime < DateTime.Now ? false : true; + if (res.IsProtect.Value) + { + var nowDept = extUserList.Where(n => n.deptid == register.deptid).OrderBy(n => n.ctime).FirstOrDefault(); + //该客户只注册这个渠道未加该渠道对应销售的企微好友,保护期依然是该渠道的 + if (nowDept == null) + { + content += $"未加本事业部【{register?.title}】好友"; + res.DeptId = register.deptid; + res.DeptName = register.title; + res.channel = register.campainid; + } + content += $"=>初步确认归属【{register?.ctime}】【{register?.title}】"; + res.DeptId = register.deptid; + res.DeptName = register.title; + res.channel = register.campainid; + List extuserpass = new List(); + while (nowDept != null) + { + extuserpass.Add(nowDept.externaluserid); + if (nowDept.subscribe == 1) + { + content += $"=>再次确认归属【{nowDept.ctime}】【{nowDept.title}】"; + res.DeptId = nowDept.deptid; + res.DeptName = nowDept.title; + res.channel = nowDept.campainid; + break; + } + content += $"=>寻找好友关系【{nowDept.ctime}】【{nowDept.title}】"; + if (nowDept.subscribe != 1) + { + content += $"【{nowDept.unsubscribe_time}取关】"; + nowDept = extUserList.FirstOrDefault(n => n.ctime >= nowDept.unsubscribe_time && !extuserpass.Contains(n.externaluserid)); + } + } + } + } + else if (res.FirstFollowTime.HasValue) + { + res.ProtectTime = res.FirstFollowTime.Value.AddDays(setting.protectday); + content += $"最早关注时间【{res.FirstFollowTime}】"; + //有关注 取 还在关注状态下的部门 否则不保护 + res.IsProtect = res.ProtectTime == null || res.ProtectTime < DateTime.Now ? false : true; + if (res.IsProtect.Value) + { + var nowDept = firstFollow; + content += $"=>初步确认归属【{nowDept.ctime}】【{nowDept.title}】"; + res.DeptId = nowDept?.deptid; + res.DeptName = nowDept?.title; + res.channel = nowDept?.campainid; + List extuserpass = new List(); + while (nowDept != null) + { + extuserpass.Add(nowDept.externaluserid); + if (nowDept.subscribe == 1) + { + content += $"=>再次确认归属【{nowDept.ctime}】【{nowDept.title}】"; + res.DeptId = nowDept.deptid; + res.DeptName = nowDept.title; + res.channel = nowDept.campainid; + break; + } + content += $"=>寻找好友关系【{nowDept.ctime}】【{nowDept.title}】"; + if (nowDept.subscribe != 1) + { + content += $"【{nowDept.unsubscribe_time}】取关"; + nowDept = extUserList.FirstOrDefault(n => n.ctime >= nowDept.unsubscribe_time && !extuserpass.Contains(n.externaluserid)); + } + } + } + } + res.content = content; + stopWatch.Stop(); + Log.Warning($"GetResoucePassTimeBySql:{stopWatch.ElapsedMilliseconds}"); + return res; + } + + private async Task> GetRootPassTime(string username) + { + List res = new List(); + var url = $"https://r2.soft.dn8188.com/order/doGetUserPerssion"; + var postJson = new + { + username = username + }; + try + { + var data = await _httpClient.PostAsync(url, postJson); + if (data.ret == 0) + { + foreach (var item in data.moduelData) + { + try + { + res.AddRange(item.Value); + } + catch (Exception ex) + { + Log.Error($"【{username}】接口获取权限数据失败{ex.Message}【{item.Value}】"); + } + } + } + } + catch (Exception ex) + { + Log.Error($"【{username}】接口获取权限数据失败{ex.Message}"); + } + return res; + } + + public async Task GetSoftUserDetail(string softUserName) + { + SoftUserNameDetailModel model = new SoftUserNameDetailModel(); + var orderList = _repository.GetRepository().Query().Where(n => n.SOFTUSERNAME == softUserName).ToList(); + var passList = await GetRootPassTime(softUserName); + foreach (var order in orderList) + { + var pass = passList.Where(n => n.orderid == order.SZZYORDERID.ToString()).ToList(); + if (pass != null) + { + var longStartTime = pass.Min(n => n.start); + var longEndTime = pass.Max(n => n.end); + + OrderDetail orderDetail = new OrderDetail() + { + OrderId = order.ORDERID, + SzzyorderId = order.SZZYORDERID, + ProductCode = order.PRODUCTCODE, + ProductName = order.PRODUCTNAME, + Remark = "正价单" + }; + if (longStartTime.HasValue) + { + orderDetail.StartTime = JavaLongToDateTime(longStartTime.Value); + } + if (longEndTime.HasValue) + { + orderDetail.EndTime = JavaLongToDateTime(longEndTime.Value); + } + model.OrderInfo.Add(orderDetail); + if (!string.IsNullOrEmpty(order.activeproductext)) + { + var activeProductExt = JsonHelper.FromJson>(order.activeproductext); + foreach (var product in activeProductExt) + { + pass = passList.Where(n => n.orderid == product.SzzyOrderId.ToString()).ToList(); + if (pass != null) + { + longStartTime = pass.Min(n => n.start); + longEndTime = pass.Max(n => n.end); + OrderDetail chDetail = new OrderDetail() + { + OrderId = order.ORDERID, + SzzyorderId = product.SzzyOrderId, + ProductCode = product.ActiveProductCode, + ProductName = product.ActiveProductName, + Remark = "正价单(赠送)" + }; + if (longStartTime.HasValue) + { + chDetail.StartTime = JavaLongToDateTime(longStartTime.Value); + } + if (longEndTime.HasValue) + { + chDetail.EndTime = JavaLongToDateTime(longEndTime.Value); + } + model.OrderInfo.Add(chDetail); + } + } + } + } + } + model.MaxRootTime = model.OrderInfo.Max(n => n.EndTime); + if (model.MaxRootTime.HasValue) + { + model.canopen = model.MaxRootTime.Value > Convert.ToDateTime("2023-11-09"); + } + + return model; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/RegUserDomain.cs b/code/Zxd.Domain/RegUserDomain.cs new file mode 100644 index 0000000..2b22a63 --- /dev/null +++ b/code/Zxd.Domain/RegUserDomain.cs @@ -0,0 +1,216 @@ +namespace Zxd.Domain +{ + public class RegUserDomain : IRegUserDomain + { + private readonly IRepositoryBase _softUserRepository; + private readonly IRepositoryBase _softUserChRepository; + private readonly IRepositoryBase _companyChannelRepository; + private readonly IRepositoryBase _resApplyRepository; + private readonly IBaseRepository _repository; + private readonly IResCustomerDomain _resCustomerService; + private readonly ISystemConfigDomain _systemConfigService; + + public RegUserDomain(IBaseRepository repository, IResCustomerDomain resCustomerService + , IRepositoryBase softUserChRepository, + IRepositoryBase resApplyRepository + , ISystemConfigDomain systemConfigService) + { + _repository = repository; + _softUserRepository = _repository.GetRepository(); + _resCustomerService = resCustomerService; + _softUserChRepository = softUserChRepository; + _companyChannelRepository = _repository.GetRepository(); + _resApplyRepository = resApplyRepository; + _systemConfigService = systemConfigService; + } + + /*接口返回的字符串:18696548545,5001,6201075,5001,2013-8-7 13:54:16【手机号,标签,卡号,用户名,注册时间】*/ + + /// + /// 从接口抓取到的注册用户,旧系统名称为jmdUser + /// + /// 手机号 + /// 注册渠道 + /// 卡号 + /// 用户名 + /// 注册时间 + //public void RegUser(string mobile, string tag, string cardNo, string userName, DateTime? regDate, int companyId, string emial, string ip, string activeMobile = null, string platform = null, string jsonData = null, string dataType = null, string extXML = null, string kWord = null, string eid = null,string openid=null,string openplat=null, string unionid=null) + public async Task RegUser(SynInnerModel dto) + { + //88888888888,5001,6299377,565,2013/9/9 14:44:54,600 + List errors = new List(); + try + { + //注册customer + string v_resid = string.Empty; + if (!string.IsNullOrEmpty(dto.mobile)) + { + v_resid = ResUtil.CreateResId(dto.mobile); + await _resCustomerService.ResgisterCustomer(dto.mobile, v_resid, dto.ch); + } + DateTime? rgd = null; + if (dto.regDate.HasValue) + { + rgd = TimeHelper.GetTimeFromLinuxTime(dto.regDate.Value); + } + var ch = Convert.ToInt32(dto.ch); + var regUser = _softUserRepository.Query().FirstOrDefault(p => p.USERNAME == dto.username); + if (regUser == null) + { + var softUser = new SOFT_USER + { + USERNAME = dto.username, + USERPASS = "string.Empty", + CTIME = DateTime.Now, + COMPANYID = 0, + REGCAMPAINID = ch, + REGDATE = rgd, + RESID = v_resid, + REGPLATFORM = dto.plat, + EMAIL = dto.em, + IP = dto.ip, + OPENID = dto.openid,// ***第三方用户ID * ** + OPENPLAT = dto.openplat,//***第三方平台*** + LIVECODE = dto.liveCode, + REGSOURCE = dto.regSource + }; + if (!string.IsNullOrWhiteSpace(dto.refeid)) + { + softUser.EID = Convert.ToInt32(dto.refeid); + dto.eid = dto.refeid; + } + if (!string.IsNullOrEmpty(dto.mobile)) + { + softUser.ISACTIVE = 1; + softUser.ACTIVERESID = v_resid; + softUser.ACTIVETIME = rgd; + } + softUser.UNIONID = dto.unionId; + await _softUserRepository.InsertAsync(softUser); + + var softUserCH = new Soft_User_CH() { UserName = softUser.USERNAME, CH = Convert.ToInt32(dto.ch), CTime = DateTime.Now }; + + if (!string.IsNullOrEmpty(dto.eid)) + { + softUserCH.Eid = int.Parse(dto.eid); + } + await _softUserChRepository.InsertAsync(softUserCH); + if (!string.IsNullOrWhiteSpace(dto.eid) && !string.IsNullOrEmpty(dto.mobile)) + { + var eid = int.Parse(dto.eid); + SetQuantity(ch, eid, dto.groupid ?? 0, v_resid); + } + } + else + { + if (!string.IsNullOrWhiteSpace(dto.refeid)) + { + regUser.EID = Convert.ToInt32(dto.refeid); + } + if (!string.IsNullOrEmpty(dto.unionId)) + { + regUser.UNIONID = dto.unionId; + } + + var softUserExists = _softUserChRepository.Query().Any(p => p.UserName == dto.username && p.CH == ch); + + if (!softUserExists) + { + var softUserCH = new Soft_User_CH() { UserName = dto.username, CH = Convert.ToInt32(dto.ch), CTime = DateTime.Now }; + + if (!string.IsNullOrEmpty(dto.eid)) + { + softUserCH.Eid = int.Parse(dto.eid); + } + await _softUserChRepository.InsertAsync(softUserCH); + + if (!string.IsNullOrWhiteSpace(dto.eid) && !string.IsNullOrEmpty(dto.mobile)) + { + var eid = int.Parse(dto.eid); + SetQuantity(ch, eid, dto.groupid ?? 0, v_resid); + } + } + //LogHelper.Info("regUser.EID:" + regUser.EID.ToString() + ",regUser.UNIONID:" + regUser.UNIONID); + } + Log.Information($"日志打印 regUser{v_resid}"); + if (!string.IsNullOrEmpty(v_resid)) + { + await _resCustomerService.ContractUser(v_resid, dto.username); + } + Log.Information($"日志打印 ContractUser{v_resid}"); + //进入资源系统 + bool r = ImportResApply(errors, dto.mobile, dto.ch, string.Empty, dto.username, rgd, null, null, null, null); + if (r == false) + throw new Exception(string.Join(",", errors)); + Log.Information($"日志打印 ImportResApply{v_resid}"); + } + catch (Exception ex) + { + Log.Error($"日志错误{ex.Message}"); + throw ex; + } + } + + /// + /// (当手机号不为空时时进入资源系统,等清洗)从接口抓取到的注册用户,旧系统名称为jmdUser + /// + /// 手机号 + /// 注册标签 + /// 卡号 + /// 用户名 + /// 注册时间 + public bool ImportResApply(List errors, string mobile, string tag, string cardNo, string userName, DateTime? regDate, string jsonData = null, string dataType = null, string extXML = null, string kWord = null) + { + try + { + string clientid = _systemConfigService.GetSystemConfig().CRMClientKey; + var client = _systemConfigService.GetClientKey(clientid); + if (string.IsNullOrEmpty(mobile)) + return true; + + var model = new RES_APPLY + { + RESOURCETAG = tag, + RESID = ResUtil.CreateResId(mobile), + USERNAME = userName, + JSONDATA = jsonData, + RTIME = regDate, + JSONTYPE = 1, + STATUS = 0, + DATATYPE = dataType, + EXTXML = extXML, + KWORD = kWord, + CTIME = DateTime.Now, + ENMOBILE = ResUtil.NumberFormat(mobile.Trim()), + MOBILE = SecurityHelper.EncyptData(mobile.Trim(), client.AccessKey), + }; + _resApplyRepository.InsertAsync(model); + return true; + } + catch (Exception ex) + { + errors.Add(ex.Message + ex.StackTrace); + //CRM.Core.Common.LogHelper.Error("----------"+ex.Message + ex.StackTrace); + return false; + } + } + + public void SetQuantity(int ch, int eid, int gid, string resid) + { + try + { + //478361560401673707-1001-60974-27 + Log.Information("SetQuantity-1:" + resid + "-" + ch.ToString() + "-" + eid.ToString() + "-" + gid.ToString()); + + var company = _companyChannelRepository.Query().FirstOrDefault(p => p.Min <= ch && p.Max >= ch); + + Log.Information("SetQuantity-2:" + company.Defult); + _resCustomerService.SetQuantity(company.Defult, eid, gid); + } + catch (Exception ex) + { + Log.Error($"SetQuantity" + ex.Message); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/ResCustomerDomain.cs b/code/Zxd.Domain/ResCustomerDomain.cs new file mode 100644 index 0000000..1e7fc40 --- /dev/null +++ b/code/Zxd.Domain/ResCustomerDomain.cs @@ -0,0 +1,105 @@ +using DG.EntityFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Data; +using MySqlConnector; +using DG.Tool; +using Serilog; +using Microsoft.EntityFrameworkCore; +using Zxd.Domain.Impl; + +namespace Zxd.Domain +{ + public class ResCustomerDomain : IResCustomerDomain + { + private readonly IBaseRepository _repository; + private readonly ISystemConfigDomain _systemConfigService; + + public ResCustomerDomain(IBaseRepository repository, + ISystemConfigDomain systemConfigService) + { + _repository = repository; + _systemConfigService = systemConfigService; + } + + public async Task ResgisterCustomer(string CNumber, string ResId, string CustomerFrom, string customerDetailXml = null) + { + try + { + var mobile = await _repository.GetRepository().Query().FirstOrDefaultAsync(p => p.ResId == ResId); + if (mobile == null) + { + var md5 = ResUtil.UserMd5(CNumber); + await _repository.GetRepository().InsertAsync(new RES_MOBILE_MD5() { ResId = ResId, Md5 = md5 }); + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + + return await ResgisterCustomerByProcedure(CNumber, ResId, CustomerFrom, customerDetailXml); + } + + public async Task ResgisterCustomerByProcedure(string CNumber, string ResId, string CustomerFrom, string customerDetailXml = null) + { + try + { + CNumber = CNumber.Replace("+86", ""); + if (CNumber.StartsWith("01") && CNumber.Length == 12) + { + CNumber = CNumber.Substring(1); + } + string enkey = _systemConfigService.GetSystemConfig().CRMClientKey; + ClientKey clientid = _systemConfigService.GetClientKey(enkey); + var param = new List + { + new MySqlParameter() { ParameterName = "p_CNumber", DbType = DbType.String, Value =SecurityHelper.EncyptData(CNumber,clientid.AccessKey)}, + new MySqlParameter() { ParameterName = "p_ResId", DbType = DbType.String, Value = ResId }, + new MySqlParameter() { ParameterName = "p_CustomerFrom", DbType = DbType.String, Value = CustomerFrom } + }; + //param.Add(!string.IsNullOrEmpty(customerDetailXml) ? new MySqlParameter() { ParameterName = "p_customerDetailXml", DbType = DbType.String, Value = customerDetailXml } : new MySqlParameter() { ParameterName = "p_customerDetailXml", DbType = DbType.String, Value = DBNull.Value }); + param.Add(!string.IsNullOrEmpty(CNumber) ? new MySqlParameter() { ParameterName = "p_ECNumber", DbType = DbType.String, Value = ResUtil.NumberFormat(CNumber) } : new MySqlParameter() { ParameterName = "p_ECNumber", DbType = DbType.String, Value = DBNull.Value }); + return await _repository.ExecuteSqlCommandNonQueryAsync(CommandType.StoredProcedure, "res_ResgisterCustomer", param.ToArray()); + } + catch (Exception e) + { + Log.Error(string.Concat("【ResgisterCustomer】---CNumber=" + CNumber + "-----ResId=" + ResId + "-----CustomerFrom=" + CustomerFrom)); + Log.Error(string.Concat("ResgisterCustomer", e.Message, e.StackTrace)); + throw; + } + } + + public async Task SetQuantity(int ch, int eid, int salegroupid) + { + var param = new List + { + new MySqlParameter("@arg_ch", ch), + new MySqlParameter("@arg_eid", eid), + new MySqlParameter("@arg_salegroupid", salegroupid) + }; + await _repository.ExecuteSqlCommandNonQueryAsync(CommandType.StoredProcedure, "assign_setquantity", param.ToArray()); + } + + public async Task ContractUser(string resid, string userName) + { + try + { + var param = new List + { + new MySqlParameter() { ParameterName = "v_Resid", DbType = DbType.String, Value = resid }, + new MySqlParameter() { ParameterName = "v_UserName", DbType = DbType.String, Value = userName } + }; + + return await _repository.ExecuteSqlCommandNonQueryAsync(CommandType.StoredProcedure, "res_ContractSoftUser", param.ToArray()); + } + catch + { + throw; + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Response/SaleClusResult.cs b/code/Zxd.Domain/Response/SaleClusResult.cs new file mode 100644 index 0000000..d92871f --- /dev/null +++ b/code/Zxd.Domain/Response/SaleClusResult.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Response +{ + public class SaleClusResult + { + [JsonPropertyName("list")] + public List? List { get; set; } + + [JsonPropertyName("ret")] + public int Ret { get; set; } + + [JsonPropertyName("msg")] + public string? Msg { get; set; } + } +} diff --git a/code/Zxd.Domain/Response/SaleRelation.cs b/code/Zxd.Domain/Response/SaleRelation.cs new file mode 100644 index 0000000..4e2be52 --- /dev/null +++ b/code/Zxd.Domain/Response/SaleRelation.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Response +{ + public class SaleRelation + { + [JsonPropertyName("appid")] + public string? Appid { get; set; } + + [JsonPropertyName("appuserid")] + public string? Appuserid { get; set; } + + [JsonPropertyName("uid")] + public int? Uid { get; set; } + + [JsonPropertyName("mobile")] + public string? Mobile { get; set; } + } +} diff --git a/code/Zxd.Domain/ScreenRecordDomain.cs b/code/Zxd.Domain/ScreenRecordDomain.cs new file mode 100644 index 0000000..4ee3718 --- /dev/null +++ b/code/Zxd.Domain/ScreenRecordDomain.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Domain.Dto.Resource; + +namespace Zxd.Domain +{ + public class ScreenRecordDomain : IScreenRecordDomain + { + private readonly IBaseRepository _repository; + + public ScreenRecordDomain(IBaseRepository repository) + { + _repository = repository; + } + + public async Task ScreenRecord(ScreenRecord postData) + { + Log.Information("ScreenRecord:" + postData.ToJson()); + if (string.IsNullOrWhiteSpace(postData.MasterId)) + throw new Exception("主控ID不能为空"); + if (string.IsNullOrWhiteSpace(postData.MasterIP)) + throw new Exception("主控IP不能为空"); + if (string.IsNullOrWhiteSpace(postData.SlaveId)) + throw new Exception("被控ID不能为空"); + if (string.IsNullOrWhiteSpace(postData.SlaveIP)) + throw new Exception("被控IP不能为空"); + + postData.CTime = DateTime.Now; + + int maxRetryCount = 3; + int retryCount = 0; + + try + { + var screenRecord = await _repository.GetRepository().FirstOrDefaultAsync(x => x.MasterDeviceCode == postData.MasterDeviceCode && x.SlaveDeviceCode == postData.SlaveDeviceCode && x.InitConnectTime == postData.InitConnectTime); + if (screenRecord != null) + { + screenRecord.RealEndTime = postData.RealEndTime; + await _repository.GetRepository().UpdateAsync(screenRecord, x => new { x.RealEndTime }); + } + else + { + var result = await _repository.GetRepository().InsertAsync(postData); + } + + return true; + } + catch (Exception ex) + { + Log.Error($"ScreenRecordERR:{postData.ToJson()}reason:{ex.Message}"); + return false; + //await Task.Delay(500); + } + return true; + /*while (retryCount < maxRetryCount) + { + try + { + var screenRecord = await _repository.GetRepository().FirstOrDefaultAsync(x => x.MasterDeviceCode == postData.MasterDeviceCode && x.SlaveDeviceCode == postData.SlaveDeviceCode && x.InitConnectTime == postData.InitConnectTime); + if (screenRecord != null) + { + screenRecord.RealEndTime = postData.RealEndTime; + await _repository.GetRepository().UpdateAsync(screenRecord, x => new { x.RealEndTime }); + } + else + { + var result = await _repository.GetRepository().InsertAsync(postData); + } + + return true; + } + catch (Exception ex) + { + Log.Information($"录屏数据传入出错。参数:{postData.ToJson()}。原因:{ex.Message}"); + retryCount++; + await Task.Delay(500); + } + } + throw new Exception("存储失败");*/ + } + + public async Task FileRecord(ScreenRecordFile postData) + { + if (string.IsNullOrWhiteSpace(postData.MasterDeviceCode)) + throw new Exception("主控Code不能为空"); + if (string.IsNullOrWhiteSpace(postData.SlaveDeviceCode)) + throw new Exception("被控Code不能为空"); + if (!postData.InitConnectTime.HasValue) + throw new Exception("连接时长不能为空"); + if (string.IsNullOrWhiteSpace(postData.FileUrl)) + throw new Exception("文件路径不能为空"); + + var screenRecord = await _repository.GetRepository().FirstOrDefaultAsync(x => x.MasterDeviceCode == postData.MasterDeviceCode && x.SlaveDeviceCode == postData.SlaveDeviceCode && x.InitConnectTime == postData.InitConnectTime); + if (screenRecord == null) + throw new Exception("录屏数据不存在"); + + screenRecord.FileUrl = postData.FileUrl; + screenRecord.UTime = DateTime.Now; + + await _repository.GetRepository().UpdateAsync(screenRecord); + return true; + } + + /// + /// 获取录屏列表接口 + /// + /// + /// + public async Task> GetScreenRecordList(ScreenRecordRequest postData) + { + var result = new List(); + var query = _repository.GetRepository().Query() + .Select(x => new ScreenRecordResponse + { + Id = x.id, + MasterUserName = x.MasterId, + SlaveUserName = x.SlaveId, + InitConnectTime = x.InitConnectTime, + RealStartTime = x.RealStartTime, + RealEndTime = x.RealEndTime, + FileUrl = x.FileUrl + }); + + var employees = from a in _repository.GetRepository().Query() + join b in _repository.GetRepository().Query() on a.employee_id equals b.eid + select new + { + Eid = a.employee_id, + Name = a.employee_name, + UserName = b.appusername, + AppId = a.appid + }; + + query = query.If(postData.InitConnectStartTime.HasValue, x => x.Where(y => y.InitConnectTime >= postData.InitConnectStartTime.Value)) + .If(postData.InitConnectEndTime.HasValue, x => x.Where(y => y.InitConnectTime <= postData.InitConnectEndTime.Value.AddDays(1))); + + //录屏主控人或被控人都可以是员工或客户 + //因此筛选条件需要判断主控人与被控人一起判断 + if (!string.IsNullOrWhiteSpace(postData.AppId)) + { + var userNames = employees.Where(x => x.AppId == postData.AppId).Select(x => x.UserName).ToList(); + query = query.Where(x => userNames.Contains(x.MasterUserName) || userNames.Contains(x.SlaveUserName)); + } + + if (postData.Eid.HasValue) + { + var userNames = employees.Where(x => x.Eid == postData.Eid).Select(x => x.UserName).ToList(); + + query = query.If(postData.Type == (int)ScreenRecordType.主控人, x => x.Where(y => userNames.Contains(y.MasterUserName))) + .If(postData.Type == (int)ScreenRecordType.被控人, x => x.Where(y => userNames.Contains(y.SlaveUserName))) + .If(!postData.Type.HasValue, x => x.Where(y => userNames.Contains(y.MasterUserName) || userNames.Contains(y.SlaveUserName))); + } + + if (!string.IsNullOrWhiteSpace(postData.Name)) + { + var userNames = await _repository.GetRepository().Query().Where(x => x.CNAME == postData.Name).Select(x => x.SOFTUSERNAME).ToListAsync(); + + query = query.If(postData.Type == (int)ScreenRecordType.主控人, x => x.Where(y => userNames.Contains(y.MasterUserName))) + .If(postData.Type == (int)ScreenRecordType.被控人, x => x.Where(y => userNames.Contains(y.SlaveUserName))) + .If(!postData.Type.HasValue, x => x.Where(y => userNames.Contains(y.MasterUserName) || userNames.Contains(y.SlaveUserName))); + } + + if (!string.IsNullOrWhiteSpace(postData.UserName)) + { + query = query.If(postData.Type == (int)ScreenRecordType.主控人, x => x.Where(y => y.MasterUserName == postData.UserName)) + .If(postData.Type == (int)ScreenRecordType.被控人, x => x.Where(y => y.SlaveUserName == postData.UserName)) + .If(!postData.Type.HasValue, x => x.Where(y => y.MasterUserName == postData.UserName || y.SlaveUserName == postData.UserName)); + } + + if (!string.IsNullOrWhiteSpace(postData.ResId)) + { + var userNames = await _repository.GetRepository().Query().Where(x => x.RESID == postData.ResId).Select(x => x.USERNAME).ToListAsync(); + + query = query.If(postData.Type == (int)ScreenRecordType.主控人, x => x.Where(y => userNames.Contains(y.MasterUserName))) + .If(postData.Type == (int)ScreenRecordType.被控人, x => x.Where(y => userNames.Contains(y.SlaveUserName))) + .If(!postData.Type.HasValue, x => x.Where(y => userNames.Contains(y.MasterUserName) || userNames.Contains(y.SlaveUserName))); + } + + var total = await query.CountAsync(); + result = await query + .OrderByDescending(x => x.Id) + .Skip((postData.PageIndex - 1) * postData.PageSize) + .Take(postData.PageSize) + .ToListAsync(); + + if (result != null && result.Any()) + { + var userNames = result.Select(x => x.MasterUserName).ToList(); + userNames.AddRange(result.Select(x => x.SlaveUserName).ToList()); + userNames = userNames.Distinct().ToList(); + + var softUsers = await _repository.GetRepository().Query().Where(x => userNames.Contains(x.USERNAME)).ToListAsync(); + + var employee = employees.Where(x => userNames.Contains(x.UserName)).ToList(); + + var orders = await _repository.GetRepository().Query().Where(x => userNames.Contains(x.SOFTUSERNAME) && x.ISTEST == 0 && !string.IsNullOrWhiteSpace(x.CNAME)) + .OrderByDescending(x => x.CTIME).Select(x => new { Cname = x.CNAME, USERNAME = x.SOFTUSERNAME }).ToListAsync(); + + foreach (var item in result) + { + item.MasterResId = softUsers.FirstOrDefault(x => x.USERNAME == item.MasterUserName)?.RESID; + item.SlaveResId = softUsers.FirstOrDefault(x => x.USERNAME == item.SlaveUserName)?.RESID; + + item.MasterUmid = softUsers.FirstOrDefault(x => x.USERNAME == item.MasterUserName)?.UMID; + item.SlaveUmid = softUsers.FirstOrDefault(x => x.USERNAME == item.SlaveUserName)?.UMID; + + item.MasterName = orders.FirstOrDefault(x => x.USERNAME == item.MasterUserName)?.Cname; + item.SlaveName = orders.FirstOrDefault(x => x.USERNAME == item.SlaveUserName)?.Cname; + + var time = item.RealEndTime - item.RealStartTime; + item.RealLongTime = time.HasValue ? $"{(int)time.Value.TotalMinutes}min{time.Value.TotalSeconds % 60}ss" : string.Empty; + + var masterEmployee = employee.FirstOrDefault(x => x.UserName == item.MasterUserName); + var slaveEmployee = employee.FirstOrDefault(x => x.UserName == item.SlaveUserName); + + item.MasterEid = masterEmployee?.Eid; + item.MasterEidStr = masterEmployee != null ? $"{masterEmployee?.Eid}-{masterEmployee?.Name}" : string.Empty; + //item.MasterName = masterEmployee?.Name; + item.SlaveEid = slaveEmployee?.Eid; + item.SlaveEidStr = slaveEmployee != null ? $"{slaveEmployee?.Eid}-{slaveEmployee?.Name}" : string.Empty; + //item.SlaveName = slaveEmployee?.Name; + } + } + return new PageResult(postData.PageIndex, postData.PageSize, total, result); + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Sso/SsoDepartment.cs b/code/Zxd.Domain/Sso/SsoDepartment.cs new file mode 100644 index 0000000..64f3ff6 --- /dev/null +++ b/code/Zxd.Domain/Sso/SsoDepartment.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoDepartment + { + public int id { get; set; } + public string remark { get; set; } + public int status { get; set; } + public int? parent_id { get; set; } + public string department_name { get; set; } + public int department_sort { get; set; } + public int department_type { get; set; } + public string department_code { get; set; } + public int is_deleted { get; set; } + public string create_time { get; set; } + public string update_time { get; set; } + public bool is_checked { get; set; } + } + + public class SsoDepartmentExtend : SsoDepartment + { + public decimal? IS_PROFESSION { get; set; } = 0; + } +} diff --git a/code/Zxd.Domain/Sso/SsoEmployee.cs b/code/Zxd.Domain/Sso/SsoEmployee.cs new file mode 100644 index 0000000..a87c55e --- /dev/null +++ b/code/Zxd.Domain/Sso/SsoEmployee.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoEmployee + { + public int id { get; set; } + public int status { get; set; } + public int? sex { get; set; } + public string phone { get; set; } + public int employee_id { get; set; } + public string employee_name { get; set; } + public string employee_position { get; set; } + public DateTime? entry_date { get; set; } + public DateTime? leave_date { get; set; } + public int is_change_password { get; set; } + public int is_deleted { get; set; } + public DateTime? create_time { get; set; } + public DateTime? update_time { get; set; } + } +} diff --git a/code/Zxd.Domain/Sso/SsoEmployeeDepartment.cs b/code/Zxd.Domain/Sso/SsoEmployeeDepartment.cs new file mode 100644 index 0000000..c7bf95e --- /dev/null +++ b/code/Zxd.Domain/Sso/SsoEmployeeDepartment.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoEmployeeDepartment + { + public int id { get; set; } + public int employee_id { get; set; } + public int department_id { get; set; } + public int is_deleted { get; set; } + public DateTime? create_time { get; set; } + public DateTime? update_time { get; set; } + } +} diff --git a/code/Zxd.Domain/Sso/SsoOrganization.cs b/code/Zxd.Domain/Sso/SsoOrganization.cs new file mode 100644 index 0000000..4c44c27 --- /dev/null +++ b/code/Zxd.Domain/Sso/SsoOrganization.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + public class SsoOrganization + { + public SsoOrganization(List profession_departments, List other_departments, List employees, List employee_departments) + { + this.profession_departments = profession_departments; + this.other_departments = other_departments; + this.employees = employees; + this.employee_departments = employee_departments; + } + + /// + /// 业务部门 + /// + public List profession_departments { get; set; } + /// + /// 其他部门 + /// + public List other_departments { get; set; } + /// + /// 员工信息 + /// + public List employees { get; set; } + /// + /// 员工部门关系 + /// + public List employee_departments { get; set; } + } +} diff --git a/code/Zxd.Domain/Sso/SsoResult.cs b/code/Zxd.Domain/Sso/SsoResult.cs new file mode 100644 index 0000000..371921f --- /dev/null +++ b/code/Zxd.Domain/Sso/SsoResult.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace Zxd.Domain.Sso +{ + internal class SsoResult + { + /// + /// -1 未知异常 + /// -1001 签名不合法 + /// -1002 签名验证失败 + /// -1003 请求内容不合法 + /// -1004 AppID不合法 + // -1005 签名已过期 + /// + [JsonPropertyName("ret")] + public int Ret { get; set; } + + [JsonPropertyName("data")] + public T Data { get; set; } + + [JsonPropertyName("msg")] + public string? Msg { get; set; } + } +} diff --git a/code/Zxd.Domain/Sso/SsoUserTokenInfo.cs b/code/Zxd.Domain/Sso/SsoUserTokenInfo.cs new file mode 100644 index 0000000..ca46b0e --- /dev/null +++ b/code/Zxd.Domain/Sso/SsoUserTokenInfo.cs @@ -0,0 +1,18 @@ +using System; +namespace Zxd.Domain.Sso +{ + public class SsoUserTokenInfo + { + public SsoUserTokenInfo() + { + + } + + public decimal Eid { get; set; } + + public DateTime ExpirationTime { get; set; } + + public string? Token { get; set; } + } +} + diff --git a/code/Zxd.Domain/SystemConfigDomain.cs b/code/Zxd.Domain/SystemConfigDomain.cs new file mode 100644 index 0000000..36a7a83 --- /dev/null +++ b/code/Zxd.Domain/SystemConfigDomain.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.Options; + +namespace Zxd.Domain +{ + public class SystemConfigDomain : ISystemConfigDomain + { + private readonly IOptionsSnapshot _systemConfig; + + public SystemConfigDomain(IOptionsSnapshot systemConfig) + { + _systemConfig = systemConfig; + } + + /// + /// 获取配置文件 + /// + /// + public SystemConfig GetSystemConfig() + { + return _systemConfig.Value; + } + + public ClientKey GetClientKey(string clientId) + { + var client = _systemConfig.Value.ClientKey.FirstOrDefault(x => x.Id == clientId); + if (client == null) + throw new Exception("非法客户端访问"); + return client; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/UserInfoDomain.cs b/code/Zxd.Domain/UserInfoDomain.cs new file mode 100644 index 0000000..0c9d4ad --- /dev/null +++ b/code/Zxd.Domain/UserInfoDomain.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Core.Shared; +using Zxd.Entity.UserCenter; + +namespace Zxd.Domain +{ + public class UserInfoDomain : IUserInfoDomain + { + private readonly IHttpClient _httpClient; + private readonly SystemConfig _systemConfig; + + public UserInfoDomain( + IConfiguration configuration, IHttpClient httpClient) + { + _systemConfig = configuration.GetSection("SystemConfig").Get(); + _httpClient = httpClient; + } + + /* public async Task> GetUserInfo(string? appid, string? appuserid) + { + List res = new List(); + var userinfos = await _userCenterRepository.GetRepository().Query() + .Where(x => x.Appid == appid && x.Appuserid == appuserid) + .ToListAsync(); + if (userinfos == null || !userinfos.Any()) + { + return res; + } + var customerid = userinfos[0].Customerid; + userinfos = await _userCenterRepository.GetRepository().Query() + .Where(x => x.Customerid == customerid) + .ToListAsync(); + if (userinfos == null || !userinfos.Any()) + { + return res; + } + foreach (var userinfo in userinfos) + { + if (!string.IsNullOrWhiteSpace(userinfo.Resid)) + { + UserInfoDto newModel = new UserInfoDto + { + Resid = userinfo.Resid, + }; + res.Add(newModel); + } + } + return res; + }*/ + + public async Task> GetUserInfoByApi(string? appid, string? userid) + { + Stopwatch stopWatch = Stopwatch.StartNew(); + stopWatch.Start(); + var res = new List(); + var url = _systemConfig.ZXDCoreUrl; // _basParameterService.GetParameterValue("Zxd_CoreApiUrl"); + url = $"{url}Api/UserInfo/list"; + var resModel = await _httpClient.GetAsync>>($"{url}?appid={appid}&appuserid={userid}", timeout: 2000); + res = resModel.data; + stopWatch.Stop(); + Log.Warning($"GetUserInfoByApi:{stopWatch.ElapsedMilliseconds}"); + return res; + } + + public async Task> GetUserInfoByApi(string? resid) + { + Stopwatch stopWatch = Stopwatch.StartNew(); + stopWatch.Start(); + var res = new List(); + var url = _systemConfig.ZXDCoreUrl; // _basParameterService.GetParameterValue("Zxd_CoreApiUrl"); + url = $"{url}Api/UserInfo/list"; + var resModel = await _httpClient.GetAsync>>($"{url}?resid={resid}", timeout: 2000); + res = resModel.data; + stopWatch.Stop(); + Log.Warning($"GetUserInfoByApi:{stopWatch.ElapsedMilliseconds}"); + return res; + } + } +} \ No newline at end of file diff --git a/code/Zxd.Domain/Zxd.Domain.csproj b/code/Zxd.Domain/Zxd.Domain.csproj new file mode 100644 index 0000000..e67b683 --- /dev/null +++ b/code/Zxd.Domain/Zxd.Domain.csproj @@ -0,0 +1,61 @@ + + + + net6.0 + enable + enable + True + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/Zxd.Entity/Action/CustomerBehaviorLog.cs b/code/Zxd.Entity/Action/CustomerBehaviorLog.cs new file mode 100644 index 0000000..d27b36c --- /dev/null +++ b/code/Zxd.Entity/Action/CustomerBehaviorLog.cs @@ -0,0 +1,80 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Action +{ + [Table("ac_customer_behavior_log")] + public class CustomerBehaviorLog + { + public CustomerBehaviorLog() + { + } + + [Key] + public int id { get; set; } + + public DateTime? act_date { get; set; } + + public DateTime? act_time { get; set; } + + public string? appid { get; set; } + public string? appuserid { get; set; } + + public string? resid { get; set; } + public string? umid { get; set; } + + public string? unionid { get; set; } + + public int? uid { get; set; } + + public int? customerid { get; set; } + + public int? user_type { get; set; } + + public int eventid { get; set; } + + public string? eventname { get; set; } + public string? eventtypename { get; set; } + + public string? eventmemo { get; set; } + + public string? others { get; set; } + + public int? scenetype { get; set; } + + public string? scenetypename { get; set; } + + public string? sceneid { get; set; } + + public string? sceneidname { get; set; } + + public string? scenename { get; set; } + + public string? sceneext { get; set; } + public string? ip { get; set; } + + public int? channel { get; set; } + + public int deptid { get; set; } + + public string? productplat { get; set; } + + public string? productplatname { get; set; } + + public string? sinkClickhouseTable { get; set; } + + public DateTime? leavetime { get; set; } + + public DateTime? updatetime { get; set; } + + public DateTime? ctime { get; set; } + + public string? Content { get; set; } + public int? neweventid { get; set; } + public string? neweventname { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Action/EmployeeDepartmentDetail.cs b/code/Zxd.Entity/Action/EmployeeDepartmentDetail.cs new file mode 100644 index 0000000..e6aaa22 --- /dev/null +++ b/code/Zxd.Entity/Action/EmployeeDepartmentDetail.cs @@ -0,0 +1,25 @@ +namespace Zxd.Entity.Action +{ + [Table("employee_department_detail")] + public class EmployeeDepartmentDetail + { + [Key] + public int? id { get; set; } + + public int? eid { get; set; } + + public int? department_id { get; set; } + + public string? department_name { get; set; } + + public int? department_type { get; set; } + + public int? level { get; set; } + + public int? is_deleted { get; set; } + + public DateTime? create_time { get; set; } + + public DateTime? update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/Action/EmployeeTodoitem.cs b/code/Zxd.Entity/Action/EmployeeTodoitem.cs new file mode 100644 index 0000000..c5c18b7 --- /dev/null +++ b/code/Zxd.Entity/Action/EmployeeTodoitem.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Action +{ + [Table("ac_employee_todoitem")] + public class EmployeeTodoitem + { + [Key] + public int? id { get; set; } + + public int logid { get; set; } + public int? eid { get; set; } + public string? ename { get; set; } + public string? content { get; set; } + public bool? done { get; set; } + public DateTime? ctime { get; set; } + public DateTime? utime { get; set; } + public string? Nickname { get; set; } + + public string? Headimgurl { get; set; } + + public int? isread { get; set; } = 0; + + public DateTime? readtime { get; set; } + + #region 缓存主表数据 + + public DateTime? act_date { get; set; } + + public DateTime? act_time { get; set; } + + public string? appid { get; set; } + public string? appuserid { get; set; } + + public string? resid { get; set; } + public string? umid { get; set; } + public string? unionid { get; set; } + + public int? uid { get; set; } + + public int? customerid { get; set; } + + public int? user_type { get; set; } + + public int eventid { get; set; } + + public string? eventname { get; set; } + public string? eventtypename { get; set; } + + public string? eventmemo { get; set; } + + public string? others { get; set; } + + public int? scenetype { get; set; } + + public string? scenetypename { get; set; } + + public string? sceneid { get; set; } + + public string? sceneidname { get; set; } + + public string? scenename { get; set; } + + public string? sceneext { get; set; } + public string? ip { get; set; } + + public int? channel { get; set; } + + public int deptid { get; set; } + + public string? productplat { get; set; } + + public string? productplatname { get; set; } + + public DateTime? leavetime { get; set; } + + public int? neweventid { get; set; } + public string? neweventname { get; set; } + + #endregion 缓存主表数据 + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Action/Eventdwd.cs b/code/Zxd.Entity/Action/Eventdwd.cs new file mode 100644 index 0000000..976d39d --- /dev/null +++ b/code/Zxd.Entity/Action/Eventdwd.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Action +{ + public class Eventdwd + { + public DateTime? act_date { get; set; } + + [Key] + public DateTime? act_time { get; set; } + + public string? appid { get; set; } + public string? appuserid { get; set; } + + public string? resid { get; set; } + + public string? unionid { get; set; } + + [Key] + public int? uid { get; set; } + + public int? customerid { get; set; } + + public int? user_type { get; set; } + + [Key] + public int eventid { get; set; } + + public string? eventname { get; set; } + + public string? eventmemo { get; set; } + + public string? others { get; set; } + + public int? scenetype { get; set; } + + public string? scenetypename { get; set; } + + public string? sceneid { get; set; } + + public string? sceneidname { get; set; } + + public string? scenename { get; set; } + + public string? sceneext { get; set; } + public string? ip { get; set; } + + public int? channel { get; set; } + + public int deptid { get; set; } + + public string? productplat { get; set; } + + public string? productplatname { get; set; } + + public DateTime? leavetime { get; set; } + + public int? with_eid { get; set; } + public int? with_groupid { get; set; } + public int? with_orgid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/CompanyBaseConf/Application.cs b/code/Zxd.Entity/CompanyBaseConf/Application.cs new file mode 100644 index 0000000..8eedf03 --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/Application.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + [Table("application")] + public class Application + { + public int id { get; set; } + public string application_name { get; set; } + public string redirect_url { get; set; } + public string app_id { get; set; } + public string app_secret { get; set; } + public int app_type { get; set; } + public int status { get; set;} + public int is_deleted { get; set; } + public DateTime? create_time { get; set; } + public DateTime? update_time { get; set;} + + } +} diff --git a/code/Zxd.Entity/CompanyBaseConf/ApplicationDepartment.cs b/code/Zxd.Entity/CompanyBaseConf/ApplicationDepartment.cs new file mode 100644 index 0000000..69ace2b --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/ApplicationDepartment.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + [Table("application_department")] + public class ApplicationDepartment + { + public int id { get; set; } + public int application_id { get; set; } + public int department_id { get; set; } + public int is_proression { get; set; } + public int is_deleted { get;set; } + public DateTime? create_time { get; set; } + public DateTime? update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/CompanyBaseConf/Department.cs b/code/Zxd.Entity/CompanyBaseConf/Department.cs new file mode 100644 index 0000000..686131c --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/Department.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + public class Department + { + [Key] + public int Id { get; set; } + + [Column("parent_id")] + public int? ParentId { get; set; } + + [Column("department_name")] + public string? DepartmentName { get; set; } + + [Column("department_type")] + public int? DepartmentType { get; set; } + + [Column("status")] + public int? Status { get; set; } + [Column("department_code")] + public string? DepartmentCode { get; set; } + + [Column("is_deleted")] + public bool IsDeleted { get; set; } + [Column("create_time")] + public DateTime Create_Time { get; set; } + + [Column("update_time")] + public DateTime Update_Time { get; set; } + } +} diff --git a/code/Zxd.Entity/CompanyBaseConf/DepartmentCrmconf.cs b/code/Zxd.Entity/CompanyBaseConf/DepartmentCrmconf.cs new file mode 100644 index 0000000..9414a06 --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/DepartmentCrmconf.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + [Table("department_crmconf")] + public class DepartmentCrmconf + { + [Key] + [Column("department_id")] + public int DepartmentId { get; set; } + + + public string? Title { get; set; } + + public string? Appid { get; set; } + + public string? CompanyCode { get; set; } + + public int? Saledeptid { get; set; } + + [Column("is_dept")] + public bool? IsDept { get; set; } + + public int? SortNo { get; set; } + } +} diff --git a/code/Zxd.Entity/CompanyBaseConf/Employee.cs b/code/Zxd.Entity/CompanyBaseConf/Employee.cs new file mode 100644 index 0000000..c987575 --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/Employee.cs @@ -0,0 +1,22 @@ +using Microsoft.VisualBasic; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + [Table("employee")] + public class Employee + { + [Key] + public int id { get; set; } + public int employee_id { get; set; } + //public string employee_name { get; set; } + //public string login_password { get; set; } + //public string job_grade { get; set; } + //public string? employee_position { get; set; } + public int? status { get; set; } + } +} diff --git a/code/Zxd.Entity/CompanyBaseConf/EmployeeDepartment.cs b/code/Zxd.Entity/CompanyBaseConf/EmployeeDepartment.cs new file mode 100644 index 0000000..a0c6278 --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/EmployeeDepartment.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + [Table("employee_department")] + public class EmployeeDepartment + { + + [Key] + public int id { get; set; } + public int employee_id { get; set; } + public int department_id { get; set; } + public int is_deleted { get; set; } + public DateTime create_time { get; set; } + public DateTime update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/CompanyBaseConf/EmployeeDepartmentDetail.cs b/code/Zxd.Entity/CompanyBaseConf/EmployeeDepartmentDetail.cs new file mode 100644 index 0000000..d39e868 --- /dev/null +++ b/code/Zxd.Entity/CompanyBaseConf/EmployeeDepartmentDetail.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.CompanyBaseConf +{ + [Table("employee_department_detail")] + public class EmployeeDepartmentDetail + { + [Key] + public int id { get; set; } + public int emp_id { get; set; } + public int department_id { get; set; } + public int department_type { get; set; } + + public int level { get; set; } + public int is_deleted { get; set; } + public DateTime create_time { get; set; } + public DateTime update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/Crm/Module.cs b/code/Zxd.Entity/Crm/Module.cs new file mode 100644 index 0000000..b0f9595 --- /dev/null +++ b/code/Zxd.Entity/Crm/Module.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Crm +{ + [Table("t_module")] + public class Module + { + [Key] + public string? Id { get; set; } + + public string? Name { get; set; } + + public bool? Flag { get; set; } + + [Column("appimgurl")] + public string? AppImgUrl { get; set; } + + public DateTime? Ctime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + [Column("risklevel")] + public int RiskLevel { get; set; } + + [Column("investtime")] + public int InvestTime { get; set; } + + [Column("investtype")] + public int InvestType { get; set; } + + [Column("compliance")] + public bool Compliance { get; set; } + + public int Type { get; set; } + + public virtual List? Product { get; set; } + } +} diff --git a/code/Zxd.Entity/Crm/Product.cs b/code/Zxd.Entity/Crm/Product.cs new file mode 100644 index 0000000..335ea64 --- /dev/null +++ b/code/Zxd.Entity/Crm/Product.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Crm +{ + [Table("t_product")] + public class Product + { + [Key] + public int Pk { get; set; } + + public string Id { get; set; } + + public string? Name { get; set; } + + public decimal Price { get; set; } + + public int? Day { get; set; } + + public string? Moduleid { get; set; } + + public string? Remark { get; set; } + + public string? Extinfo { get; set; } + + public string? Appextinfo { get; set; } + + public string? Appext { get; set; } + + [Column("webimgurl")] + public string? WebImgUrl { get; set; } + + [Column("appimgurl")] + public string? AppImgUrl { get; set; } + + public int Active { get; set; } + + public bool? Old { get; set; } + + public int? Groupid { get; set; } + + public DateTime Ctime { get; set; } + + [Column("update_time")] + public DateTime UpdateTime { get; set; } + + public int? BusinessType { get; set; } + + public string? Ext { get; set; } + + public bool? Compliance { get; set; } + + [Column("effective_immediately")] + public bool? EffectiveImmediately { get; set; } + + public virtual ProductGroup? ProductGroup { get; set; } + + public virtual Module? Module { get; set; } + + public virtual List? ProductTeachers { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Crm/ProductGroup.cs b/code/Zxd.Entity/Crm/ProductGroup.cs new file mode 100644 index 0000000..d777cf1 --- /dev/null +++ b/code/Zxd.Entity/Crm/ProductGroup.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Crm +{ + [Table("t_product_group")] + public class ProductGroup + { + [Key] + public int Id { get; set; } + + public string? Name { get; set; } + + public string? Remark { get; set; } + + public virtual List? Product { get; set; } + + public virtual List? ProductPackage { get; set; } + } +} diff --git a/code/Zxd.Entity/Crm/ProductPackage.cs b/code/Zxd.Entity/Crm/ProductPackage.cs new file mode 100644 index 0000000..f75af79 --- /dev/null +++ b/code/Zxd.Entity/Crm/ProductPackage.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Crm +{ + [Table("t_product_package")] + public class ProductPackage + { + [Key] + public int Pk { get; set; } + + public string Id { get; set; } + + public string? Name { get; set; } + + public decimal Price { get; set; } + + [Column("subproducts")] + public string? SubProducts { get; set; } + + public string? Remark { get; set; } + + [Column("subproductsinfo")] + public string? SubProductsInfo { get; set; } + + public string? Extinfo { get; set; } + + public string? Appextinfo { get; set; } + + public string? Appext { get; set; } + + [Column("webimgurl")] + public string? WebImgUrl { get; set; } + + [Column("appimgurl")] + public string? AppImgUrl { get; set; } + + public int? Active { get; set; } + + public bool? Old { get; set; } + + public int Groupid { get; set; } + + public DateTime Ctime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + public int? BusinessType { get; set; } + + [Column("effective_immediately")] + public bool? EffectiveImmediately { get; set; } + + public virtual ProductGroup? ProductGroup { get; set; } + + [NotMapped] + public List? SubProductCodes + { + get + { + return string.IsNullOrEmpty(SubProducts) ? new List() + : SubProducts.Split('|').ToList(); + } + } + + [NotMapped] + public List? SubProductsInfos + { + get + { + return string.IsNullOrEmpty(SubProductsInfo) ? new List() + : JsonSerializer.Deserialize>(SubProductsInfo); + } + } + } + + public class SubProductJson + { + [JsonPropertyName("subproductid")] + public string? SubProductId { get; set; } + + [JsonPropertyName("subprice")] + public string? SubPrice { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Crm/ProductTeacher.cs b/code/Zxd.Entity/Crm/ProductTeacher.cs new file mode 100644 index 0000000..fa40623 --- /dev/null +++ b/code/Zxd.Entity/Crm/ProductTeacher.cs @@ -0,0 +1,36 @@ +using System; +namespace Zxd.Entity.Crm +{ + [Table("t_product_teacher")] + public class ProductTeacher + { + public ProductTeacher() + { + } + + [Key] + public int Id { get; set; } + + public int Deptid { get; set; } + + [Column("product_id")] + public string? ProductId { get; set; } + + [Column("teacher_code")] + public string? TeacherCode { get; set; } + + [Column("is_packs")] + public bool? IsPacks { get; set; } + + [Column("create_time")] + public DateTime? CreateTime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + public virtual Product? Product { get; set; } + + public virtual Teacher? Teacher { get; set; } + } +} + diff --git a/code/Zxd.Entity/Crm/Teacher.cs b/code/Zxd.Entity/Crm/Teacher.cs new file mode 100644 index 0000000..207808d --- /dev/null +++ b/code/Zxd.Entity/Crm/Teacher.cs @@ -0,0 +1,25 @@ +using System; +namespace Zxd.Entity.Crm +{ + [Table("t_teacher")] + public class Teacher + { + public Teacher() + { + } + + [Key] + public string? Code { get; set; } + + public string? Name { get; set; } + + [Column("create_time")] + public DateTime? CreateTime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + public virtual List? ProductTeachers { get; set; } + } +} + diff --git a/code/Zxd.Entity/Crm/UserModule.cs b/code/Zxd.Entity/Crm/UserModule.cs new file mode 100644 index 0000000..3f06ee5 --- /dev/null +++ b/code/Zxd.Entity/Crm/UserModule.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Crm +{ + [Table("t_user_module")] + public class UserModule + { + [Key] + public string? moduleid { get; set; } + + [Key] + public string? orderid { get; set; } + + public string? username { get; set; } + public string? productid { get; set; } + public long? starttime { get; set; } + public long endtime { get; set; } + public DateTime? auto_updateTime { get; set; } + public DateTime? update_time { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/DbEnums.cs b/code/Zxd.Entity/DbEnums.cs new file mode 100644 index 0000000..94cfae9 --- /dev/null +++ b/code/Zxd.Entity/DbEnums.cs @@ -0,0 +1,116 @@ +using System; +using System.ComponentModel; + +namespace Zxd.Entity +{ + public enum StandardType : int + { + [Description("软件类")] + 软件类 = 1 << 0, + + [Description("投顾类")] + 投顾类 = 1 << 1, + + [Description("投教类")] + 投教类 = 1 << 2 + } + + public enum StandardWay + { + [Description("分期")] + 分期 = 1 << 0, + + [Description("开通费 + 分期")] + 开通费_分期 = 1 << 1, + + [Description("当期")] + 当期 = 1 << 2 + } + + public enum ProductServerType + { + [Description("长期交付")] + 长期交付 = 1 << 0, + + [Description("当期交付")] + 当期交付 = 1 << 1, + } + + public enum ProductStatus + { + [Description("未上线")] + 未上线 = 1 << 0, + + [Description("已上线")] + 已上线 = 1 << 1, + } + + public enum MeetingType + { + [Description("线上会议")] + 线上会议 = 1 << 0, + + [Description("线下会议")] + 线下会议 = 1 << 1 + } + + public enum EarlyWaningLogStatus + { + [Description("未处理")] + 未处理 = 1 << 0, + + [Description("已处理")] + 已处理 = 1 << 1, + + [Description("暂不处理")] + 暂不处理 = 1 << 2, + } + + public enum EarlyWarningType + { + [Description("百分比")] + 百分比 = 1 << 0, + + [Description("数量")] + 数量 = 1 << 1, + } + + public enum ResourceFlowStatus + { + [Description("待转移")] + 待转移 = 0, + + [Description("转移中")] + 转移中 = 1, + + [Description("转移成功")] + 转移成功 = 100, + + [Description("转移失败")] + 转移失败 = -1, + + [Description("用户拒绝")] + 用户拒绝 = -2, + + [Description("无好友关系")] + 无好友关系 = -3, + + [Description("成员禁用")] + 成员禁用 = -4, + } + + public enum ResourceConfigStatus + { + [Description("待执行")] + 待执行 = 0, + + [Description("执行中")] + 执行中 = 1, + + [Description("待重启")] + 待重启 = 2, + + [Description("执行完成")] + 执行完成 = 100, + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/Assign.cs b/code/Zxd.Entity/Dncms/Assign.cs new file mode 100644 index 0000000..f8eadef --- /dev/null +++ b/code/Zxd.Entity/Dncms/Assign.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + public class Assign + { + /// + /// 工号 + /// + [Key] + public int? eid { get; set; } + + /// + /// 组id + /// + [Key] + public int? salegroupid { get; set; } + + /// + /// 分配次数 + /// + public int? allocations { get; set; } = 0; + + /// + /// 今天分配量(次数) + /// + public int? todayallocations { get; set; } = 0; + + /// + /// 分配资源量 + /// + public int? quantity { get; set; } = 0; + + /// + /// 今天分配资源量 + /// + public int? todayquantity { get; set; } = 0; + + /// + /// 最后分配时间 + /// + public DateTime? lasttime { get; set; } + + /// + /// 推广分配量(次数) + /// + public int? tgallocations { get; set; } = 0; + + /// + /// 推广今天分配量(次数) + /// + public int? tgtodayallocations { get; set; } = 0; + + /// + /// 推广最后分配时间 + /// + public DateTime? tglasttime { get; set; } + + /// + /// 推广资源量 + /// + public int? tgquantity { get; set; } = 0; + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/AssignRules.cs b/code/Zxd.Entity/Dncms/AssignRules.cs new file mode 100644 index 0000000..0f80295 --- /dev/null +++ b/code/Zxd.Entity/Dncms/AssignRules.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + /// + /// 分配规则表 + /// + public class AssignRules + { + [Key] + public int id { get; set; } + + public int? eid { get; set; } + public int? salegroupid { get; set; } + public string? appid { get; set; } + public string? userid { get; set; } + public string? uname { get; set; } + + /// + /// 最终比例 + /// + public decimal? rate { get; set; } + + /// + /// 档位 + /// + public int? num { get; set; } + + /// + /// 是否限制 + /// + public int? islimit { get; set; } + + /// + /// 是否有效 + /// + public int? isvalid { get; set; } + + /// + /// 档位 + /// + public int? levelno { get; set; } + + /// + /// Crm部门ID + /// + public int? crmdeptid { get; set; } + + /// + /// 部门比例 + /// + public decimal? deptrate { get; set; } + + /// + /// 客服ID + /// + public int? inneruserid { get; set; } + + /// + /// 创建时间 + /// + public DateTime? ctime { get; set; } + + /// + /// 更新时间 + /// + public DateTime? utime { get; set; } + + public DateTime? startTime { get; set; } + public DateTime? endTime { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/Department.cs b/code/Zxd.Entity/Dncms/Department.cs new file mode 100644 index 0000000..24a38be --- /dev/null +++ b/code/Zxd.Entity/Dncms/Department.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("department")] + public class Department + { + [Key] + public int Id { get; set; } + + [Column("parent_id")] + public int? ParentId { get; set; } + + [Column("department_name")] + public string? DepartmentName { get; set; } + + [Column("department_type")] + public int? DepartmentType { get; set; } + + [Column("status")] + public int? Status { get; set; } + + [Column("department_code")] + public string? DepartmentCode { get; set; } + + [Column("is_deleted")] + public bool IsDeleted { get; set; } + [Column("create_time")] + public DateTime Create_Time { get; set; } + + [Column("update_time")] + public DateTime Update_Time { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/Deptment.cs b/code/Zxd.Entity/Dncms/Deptment.cs new file mode 100644 index 0000000..5224407 --- /dev/null +++ b/code/Zxd.Entity/Dncms/Deptment.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("Deptment")] + public class Deptment + { + [Key] + public int Id { get; set; } + + public string? Title { get; set; } + + public string? Code { get; set; } + + public string? Url { get; set; } + + public int? Status { get; set; } + + public int? ExtendType { get; set; } + + public string? Tel { get; set; } + + public string? Conptel { get; set; } + + public string? Viptel { get; set; } + + public int? CampainId { get; set; } + + public int? DeleteType { get; set; } + + public int? FriendTagId { get; set; } + + public int? ActivityStatus { get; set; } + + public string? Appid { get; set; } + + public int? RootId { get; set; } + public int? Groupid { get; set; } + + public List? DeptmentCampainIds { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/DeptmentCampainId.cs b/code/Zxd.Entity/Dncms/DeptmentCampainId.cs new file mode 100644 index 0000000..903dfe0 --- /dev/null +++ b/code/Zxd.Entity/Dncms/DeptmentCampainId.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("DeptmentCampainId")] + public class DeptmentCampainId + { + [Key] + public int Id { get; set; } + + public int StartCampainId { get; set; } + + public int EndCampainId { get; set; } + + public int DeptId { get; set; } + + public int Status { get; set; } + + public string? Appid { get; set; } + + public string? Memo { get; set; } + + public int? PlatformId { get; set; } + + public int? BusinessId { get; set; } + + public string? Name { get; set; } + + public Deptment? Deptment { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/EmployeeDepartmentDetail.cs b/code/Zxd.Entity/Dncms/EmployeeDepartmentDetail.cs new file mode 100644 index 0000000..3ad71ba --- /dev/null +++ b/code/Zxd.Entity/Dncms/EmployeeDepartmentDetail.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("employee_department_detail")] + public class EmployeeDepartmentDetail + { + [Key] + public int id { get; set; } + public int? eid { get; set; } + public int department_id { get; set; } + public string department_name { get; set; } + public int department_type { get; set; } + + [Column("emp_status")] + public int empStatus { get; set; } + public int level { get; set; } + public int is_deleted { get; set; } + public DateTime create_time { get; set; } + public DateTime update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/EmployeeDepartmentFull.cs b/code/Zxd.Entity/Dncms/EmployeeDepartmentFull.cs new file mode 100644 index 0000000..d04046f --- /dev/null +++ b/code/Zxd.Entity/Dncms/EmployeeDepartmentFull.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("employee_department_full")] + public class EmployeeDepartmentFull + { + + [Key] + public int id { get; set; } + public int eid { get; set; } + public string appid { get; set; } + public string app_name { get; set; } + public DateTime create_time { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/ResCutomerPassTime.cs b/code/Zxd.Entity/Dncms/ResCutomerPassTime.cs new file mode 100644 index 0000000..6177e66 --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResCutomerPassTime.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("res_passtimeinto")] + public class ResCutomerPassTime + { + [Key] + public int? PKID { get; set; } + + public string? RESID { get; set; } + public string? UMID { get; set; } + + /// + /// 事业部id + /// + public int? Deptid { get; set; } + + public string? DeptName { get; set; } + + /// + /// 群id + /// + public int? GroupId { get; set; } + + public DateTime? Ctime { get; set; } + + public DateTime? orderpasstime { get; set; } + + public DateTime? protecttime { get; set; } + + public DateTime? utime { get; set; } + public decimal? arrivalpay { get; set; } + public decimal? refundpay { get; set; } + public decimal? inpay { get; set; } + public decimal? balancepay { get; set; } + public DateTime? firstPayTime { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/ResResidWeworkEventLog.cs b/code/Zxd.Entity/Dncms/ResResidWeworkEventLog.cs new file mode 100644 index 0000000..4124069 --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResResidWeworkEventLog.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("res_resid_weworkuser_eventlog")] + public class ResResidWeworkEventLog + { + [Key] + public int id { get; set; } + public string type { get; set; } + public string cid { get; set; } + public string appid { get; set; } + public string appuserid { get; set; } + public string userid { get; set; } + public int? deptid { get; set; } + public int? olddeptid { get; set; } + public string eventJson { get; set; } + public DateTime ctime { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/ResResidWeworkUser.cs b/code/Zxd.Entity/Dncms/ResResidWeworkUser.cs new file mode 100644 index 0000000..c68d091 --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResResidWeworkUser.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + + [Table("res_resid_weworkuser")] + public class ResResidWeworkUser + { + [Key] + public int id { get; set; } + public int uid { get; set; } + public int deptid { get; set; } + public string resid { get; set; } + public string appid { get; set; } + public string appuserid { get; set; } + public string? unionid { get; set; } + public DateTime? first_subscribetime { get; set; } + public DateTime? last_subscribetime { get; set; } + public int status { get; set; } + public DateTime ctime { get; set; } + public int isdelete { get; set; } + public DateTime utime { get; set; } + } + [Table("res_resid_weworkuser_log")] + public class ResResidWeworkUserLog + { + [Key] + public int id { get; set; } + public int mainid { get; set; } + public int uid { get; set; } + public int deptid { get; set; } + public string resid { get; set; } + public string appid { get; set; } + public string appuserid { get; set; } + public string? unionid { get; set; } + public DateTime? first_subscribetime { get; set; } + public DateTime? last_subscribetime { get; set; } + public int status { get; set; } + public DateTime ctime { get; set; } + public int isdelete { get; set; } + public DateTime utime { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/ResourceFlowConfig.cs b/code/Zxd.Entity/Dncms/ResourceFlowConfig.cs new file mode 100644 index 0000000..2da17c3 --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResourceFlowConfig.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + /// + /// 资源流转设置 + /// + [Table("t_resource_flow_config")] + public class ResourceFlowConfig + { + [Key] + public int Id { get; set; } + + /// + /// 人群包id + /// + [Column("group_id")] + public int GroupId { get; set; } + + /// + /// 企微id + /// + public string? Appid { get; set; } + + /// + /// 操作人id + /// + public int Eid { get; set; } + + /// + /// 操作人 + /// + public string? Ename { get; set; } + + /// + /// 人群包名称 + /// + [Column("group_name")] + public string? GroupName { get; set; } + + public DateTime Ctime { get; set; } + + public DateTime Utime { get; set; } + + /// + /// 流转数量 + /// + [Column("flow_count")] + public int FlowCount { get; set; } + + /// + /// 事业线ID + /// + public int Deptid { get; set; } + + public ResourceConfigStatus Status { get; set; } + + public virtual ICollection ResourceFlowConfigFrom { get; set; } + public virtual ICollection ResourceFlowConfigTo { get; set; } + public virtual ICollection ResourceFlowLog { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/ResourceFlowConfigFrom.cs b/code/Zxd.Entity/Dncms/ResourceFlowConfigFrom.cs new file mode 100644 index 0000000..69de404 --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResourceFlowConfigFrom.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("t_resource_flow_config_from")] + public class ResourceFlowConfigFrom + { + [Key] + public int Id { get; set; } + + /// + /// 流转设置id + /// + [Column("config_id")] + public int ConfigId { get; set; } + /// + /// 人群包id + /// + [Column("group_id")] + public int GroupId { get; set; } + /// + /// 人员id + /// + public int? Eid { get; set; } + + /// + /// 人员名称 + /// + public string? Ename { get; set; } + + /// + /// 联系人 + /// + public string? Userid { get; set; } + + /// + /// 转移数量 + /// + [Column("transfer_count")] + public int TransferCount { get; set; } + + public DateTime Ctime { get; set; } + + public virtual ResourceFlowConfig? ResourceFlowConfig { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/ResourceFlowConfigTo.cs b/code/Zxd.Entity/Dncms/ResourceFlowConfigTo.cs new file mode 100644 index 0000000..a7caecd --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResourceFlowConfigTo.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("t_resource_flow_config_to")] + public class ResourceFlowConfigTo + { + [Key] + public int Id { get; set; } + + /// + /// 流转设置id + /// + [Column("config_id")] + public int ConfigId { get; set; } + /// + /// 人群包id + /// + [Column("group_id")] + public int GroupId { get; set; } + /// + /// 人员id + /// + public int Eid { get; set; } + + /// + /// 人员名称 + /// + public string? Ename { get; set; } + + /// + /// 联系人 + /// + public string? Userid { get; set; } + + /// + /// 分配数量 + /// + [Column("flow_count")] + public int FlowCount { get; set; } + + public DateTime Ctime { get; set; } + public virtual ResourceFlowConfig? ResourceFlowConfig { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/ResourceFlowDimission.cs b/code/Zxd.Entity/Dncms/ResourceFlowDimission.cs new file mode 100644 index 0000000..3ceccf3 --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResourceFlowDimission.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("t_resource_flow_dimission")] + public class ResourceFlowDimission + { + [Key] + public int Id { get; set; } + + /// + /// 企微id + /// + public string? Appid { get; set; } + + /// + /// 用户id + /// + public string? Appuserid { get; set; } + + /// + /// 目标成员id + /// + [Column("from_userid")] + public string? FromUserid { get; set; } + + /// + /// 创建时间 + /// + public DateTime? CTime { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/ResourceFlowLog.cs b/code/Zxd.Entity/Dncms/ResourceFlowLog.cs new file mode 100644 index 0000000..1d5419e --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResourceFlowLog.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("t_resource_flow_log")] + public class ResourceFlowLog + { + [Key] + public int Id { get; set; } + + /// + /// 流转设置id + /// + [Column("config_id")] + public int ConfigId { get; set; } + + /// + /// 人群包id + /// + [Column("group_id")] + public int GroupId { get; set; } + /// + /// 企微id + /// + public string? Appid { get; set; } + + /// + /// 用户id + /// + public string? Appuserid { get; set; } + + /// + /// 原联成员id + /// + [Column("to_userid")] + public string? ToUserid { get; set; } + + /// + /// 目标成员id + /// + [Column("from_userid")] + public string? FromUserid { get; set; } + + /// + /// 转移时间 + /// + [Column("flow_time")] + public DateTime FlowTime { get; set; } + + /// + /// 状态:0.转移中,1.转移成功,-1转移失败 + /// + public ResourceFlowStatus Status { get; set; } + + /// + /// 是否离职客服 + /// + [Column("is_dimission")] + public bool? IsDimission { get; set; } + + /// + /// 事业线ID + /// + public int Deptid { get; set; } + + public virtual ResourceFlowConfig? ResourceFlowConfig { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/ResourceProtectInfo.cs b/code/Zxd.Entity/Dncms/ResourceProtectInfo.cs new file mode 100644 index 0000000..119395e --- /dev/null +++ b/code/Zxd.Entity/Dncms/ResourceProtectInfo.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("resource_protectinfo")] + public class ResourceProtectInfo + { + [Key] + public int? id { get; set; } + + public int uid { get; set; } + public string? appid { get; set; } + public string? appuserid { get; set; } + public string? resid { get; set; } + public string? unionid { get; set; } + public int? customerid { get; set; } + public int? deptid { get; set; } + public string? deptname { get; set; } + public int? groupid { get; set; } + public DateTime? regtime { get; set; } + public int? ch { get; set; } + public DateTime? firstfollowtime { get; set; } + public DateTime? followtime { get; set; } + public DateTime? protecttime { get; set; } + public DateTime? ctime { get; set; } + public DateTime? utime { get; set; } + public int? isdelete { get; set; } = 0; + public string? eventtype { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/WeworkAgent.cs b/code/Zxd.Entity/Dncms/WeworkAgent.cs new file mode 100644 index 0000000..e77d5f8 --- /dev/null +++ b/code/Zxd.Entity/Dncms/WeworkAgent.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("WeworkAgent")] + public class WeworkAgent + { + [Key] + public int? id { get; set; } + public string? appid { get; set; } + public int? agentid { get; set; } + public string? name { get; set; } + public string? secret { get; set; } + public int? close { get; set; } + public int? deptid { get; set; } + public string? partyid { get; set; } + public int? isdefault { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/WeworkExternalUser.cs b/code/Zxd.Entity/Dncms/WeworkExternalUser.cs new file mode 100644 index 0000000..bed3221 --- /dev/null +++ b/code/Zxd.Entity/Dncms/WeworkExternalUser.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("WeworkExternalUser")] + public class WeworkExternalUser + { + public string Appid { get; set; } + public string Userid { get; set; } + public string Appid_ext { get; set; } + public string Externaluserid { get; set; } + public int deptid { get; set; } + public string unionid { get; set; } + public int subscribe { get; set; } + public DateTime? subscribetime { get; set; } + public DateTime? regdate { get; set; } + + } +} diff --git a/code/Zxd.Entity/Dncms/WeworkExternalUserTotal.cs b/code/Zxd.Entity/Dncms/WeworkExternalUserTotal.cs new file mode 100644 index 0000000..eb6d0e5 --- /dev/null +++ b/code/Zxd.Entity/Dncms/WeworkExternalUserTotal.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("weworkexternalusertotal")] + public class WeworkExternalUserTotal + { + public DateTime Ctime { get; set; } + + public int Deptid { get; set; } + + public int Eid { get; set; } + + public string? Appid { get; set; } + + public string? Userid { get; set; } + + /// + /// 总好友数 + /// + public int? Total { get; set; } + + /// + /// 新加微数 + /// + public int? Newsubscribe { get; set; } + + /// + /// 工号去重 + /// + public int? Eidrepeattypenew { get; set; } + + /// + /// 部门去重加微数 + /// + public int? Eidrepeattype1deptnew { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/Wx_Szzyorder_log.cs b/code/Zxd.Entity/Dncms/Wx_Szzyorder_log.cs new file mode 100644 index 0000000..9d487ad --- /dev/null +++ b/code/Zxd.Entity/Dncms/Wx_Szzyorder_log.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Dncms +{ + [Table("WX_SZZYORDER_LOG")] + public class Wx_Szzyorder_log + { + [Key] + public int? PKID { get; set; } + + public decimal OrderId { get; set; } + public string? RESID { get; set; } + + public decimal? FINALPAY { get; set; } + + /// + /// 订单原价 + /// + public decimal? ORIGINPAY { get; set; } + + public decimal? NEEDPAY { get; set; } + public decimal? ARRIVALPAY { get; set; } + public long? SZZYORDERID { get; set; } + + /// + /// 订单状态:新订单180、已支付200、已开通220、已停用/已退款90、已过期80、已取消70,去掉"已支付200、暂缓开通210"状态 + /// + public string? ORDERSTATUS { get; set; } + + public string? ORDERSTATUSNAME { get; set; } + + /// + /// 事业部id + /// + public int? Deptid { get; set; } + + /// + /// 事业部id + /// + public string? DeptName { get; set; } + + /// + /// 群id + /// + public int? GroupId { get; set; } + + public DateTime? Ctime { get; set; } = DateTime.Now; + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Dncms/resourcetag.cs b/code/Zxd.Entity/Dncms/resourcetag.cs new file mode 100644 index 0000000..4412d44 --- /dev/null +++ b/code/Zxd.Entity/Dncms/resourcetag.cs @@ -0,0 +1,27 @@ +namespace Zxd.Entity.Dncms +{ + [Table("resourcetag")] + public class resourcetag + { + [Key] + public int? id { get; set; } + + public string remark { get; set; } + + public string name { get; set; } + + public int? type { get; set; } + + public int? status { get; set; } + + public DateTime? ctime { get; set; } + + public int? oldid { get; set; } + + public DateTime? starttime { get; set; } + + public DateTime? endtime { get; set; } + + public int? addway { get; set; } + } +} diff --git a/code/Zxd.Entity/Dncms/weworkuser2eid.cs b/code/Zxd.Entity/Dncms/weworkuser2eid.cs new file mode 100644 index 0000000..50e3568 --- /dev/null +++ b/code/Zxd.Entity/Dncms/weworkuser2eid.cs @@ -0,0 +1,100 @@ +using System.ComponentModel; + +namespace Zxd.Entity.Dncms +{ + /// + /// + /// + [Description("")] + [Table("weworkuser2eid")] + public class weworkuser2eid + { + /// + /// + /// + [Key] + [Required(ErrorMessage ="必填")] + [Description("")] + public int? id { get; set; } + + /// + /// + /// + [Required(ErrorMessage ="必填")] + [Description("")] + public string appid { get; set; } + + /// + /// + /// + [Required(ErrorMessage ="必填")] + [Description("")] + public string userid { get; set; } + + /// + /// + /// + [Description("")] + public int? eid { get; set; } + + /// + /// 未审核 = 0, 参与分配 = 1, 暂停分配 = 2, 永久下线 = + /// + [Description("未审核 = 0, 参与分配 = 1, 暂停分配 = 2, 永久下线 =")] + public int? status { get; set; } + + /// + /// + /// + [Description("")] + public int? deptid { get; set; } + + /// + /// + /// + [Description("")] + public int? ch { get; set; } + + /// + /// 参与分配状态 0、不分配 1、分配 + /// + [Description("参与分配状态 0、不分配 1、分配")] + public int? assignstatus { get; set; } + + /// + /// + /// + [Description("")] + public int? errcode { get; set; } + + /// + /// + /// + [Description("")] + public DateTime? ctime { get; set; } + + /// + /// + /// + [Description("")] + public DateTime? utime { get; set; } + + /// + /// + /// + [Description("")] + public DateTime? synchrotime { get; set; } + + /// + /// + /// + [Description("")] + public int? waycodes { get; set; } + + /// + /// + /// + [Description("")] + public int? totalwaycodes { get; set; } + } +} diff --git a/code/Zxd.Entity/HgAction/Department.cs b/code/Zxd.Entity/HgAction/Department.cs new file mode 100644 index 0000000..63f08b0 --- /dev/null +++ b/code/Zxd.Entity/HgAction/Department.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.HgAction +{ + + [Table("department")] + public class HGDepartment + { + [Key] + public int Id { get; set; } + + [Column("parent_id")] + public int? ParentId { get; set; } + + [Column("department_name")] + public string? DepartmentName { get; set; } + + [Column("department_type")] + public int? DepartmentType { get; set; } + + [Column("status")] + public int? Status { get; set; } + + [Column("department_code")] + public string? DepartmentCode { get; set; } + + [Column("is_deleted")] + public bool IsDeleted { get; set; } + [Column("create_time")] + public DateTime Create_Time { get; set; } + + [Column("update_time")] + public DateTime Update_Time { get; set; } + } +} diff --git a/code/Zxd.Entity/HgAction/EmployeeDepartment.cs b/code/Zxd.Entity/HgAction/EmployeeDepartment.cs new file mode 100644 index 0000000..4684e39 --- /dev/null +++ b/code/Zxd.Entity/HgAction/EmployeeDepartment.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.HgAction +{ + [Table("employee_department")] + public class EmployeeDepartment + { + [Key] + public int id { get; set; } + public int eid { get; set; } + public int department_id { get; set; } + public string department_code { get; set; } + + public int is_deleted { get; set; } + public DateTime create_time { get; set; } + public DateTime update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/HgAction/EmployeeDepartmentDetail.cs b/code/Zxd.Entity/HgAction/EmployeeDepartmentDetail.cs new file mode 100644 index 0000000..3f4fa32 --- /dev/null +++ b/code/Zxd.Entity/HgAction/EmployeeDepartmentDetail.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.HgAction +{ + [Table("employee_department_detail")] + public class EmployeeDepartmentDetail + { + [Key] + public int id { get; set; } + public int? eid { get; set; } + public int department_id { get; set; } + public string department_name { get; set; } + public int department_type { get; set; } + + [Column("emp_status")] + public int empStatus { get; set; } + public int level { get; set; } + public int is_deleted { get; set; } + public DateTime create_time { get; set; } + public DateTime update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/HgAction/EmployeeDepartmentFull.cs b/code/Zxd.Entity/HgAction/EmployeeDepartmentFull.cs new file mode 100644 index 0000000..cfd97a4 --- /dev/null +++ b/code/Zxd.Entity/HgAction/EmployeeDepartmentFull.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.HgAction +{ + [Table("employee_department_full")] + public class EmployeeDepartmentFull + { + + [Key] + public int id { get; set; } + public int eid { get; set; } + public string appid { get; set; } + public string app_name { get; set; } + public DateTime create_time { get; set; } + } +} diff --git a/code/Zxd.Entity/SSO/Department.cs b/code/Zxd.Entity/SSO/Department.cs new file mode 100644 index 0000000..bad19a3 --- /dev/null +++ b/code/Zxd.Entity/SSO/Department.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.SSO +{ + [Table("department")] + public class Department + { + [Key] + public int id { get; set; } + + public int? parent_id { get; set; } + public string? department_name { get; set; } + public int? department_sort { get; set; } + public int? department_type { get; set; } + public string? department_code { get; set; } + public int? is_deleted { get; set; } + public DateTime? create_time { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/SSO/DepartmentCrmConf.cs b/code/Zxd.Entity/SSO/DepartmentCrmConf.cs new file mode 100644 index 0000000..f1952e2 --- /dev/null +++ b/code/Zxd.Entity/SSO/DepartmentCrmConf.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.SSO +{ + [Table("department_crmconf")] + public class DepartmentCrmConf + { + [Key] + public int department_id { get; set; } + + public string? title { get; set; } + public string? CompanyCode { get; set; } + public string? AppId { get; set; } + public int? SaleDeptId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/SSO/Employee.cs b/code/Zxd.Entity/SSO/Employee.cs new file mode 100644 index 0000000..03519f8 --- /dev/null +++ b/code/Zxd.Entity/SSO/Employee.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.SSO +{ + [Table("employee")] + public class Employee + { + [Key] + public int id { get; set; } + + public int? employee_id { get; set; } + public string? employee_name { get; set; } + public string? phone { get; set; } + public int? is_deleted { get; set; } + public int? status { get; set; } + public DateTime? update_time { get; set; } + + public DateTime? create_time { get; set; } + public string? phone_resid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/SSO/EmployeeDepartment.cs b/code/Zxd.Entity/SSO/EmployeeDepartment.cs new file mode 100644 index 0000000..b84eb0a --- /dev/null +++ b/code/Zxd.Entity/SSO/EmployeeDepartment.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.SSO +{ + [Table("employee_department")] + public class EmployeeDepartment + { + [Key] + public int id { get; set; } + + public int? employee_id { get; set; } + public int? department_id { get; set; } + public int? is_deleted { get; set; } + public DateTime? create_time { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Sql/20221111.txt b/code/Zxd.Entity/Sql/20221111.txt new file mode 100644 index 0000000..f38188b --- /dev/null +++ b/code/Zxd.Entity/Sql/20221111.txt @@ -0,0 +1,14 @@ +CREATE TABLE `CMS_QIWEI_POSTLOG` ( + pkid int(11) NOT NULL AUTO_INCREMENT COMMENT 'PKID', + Appid varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '΢appid', + Appuserid varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'û', + Deptid varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'id', + jsondata varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'jsonչ', + ctime datetime NULL DEFAULT NULL COMMENT 'ʱ', + status int(11) NOT NULL DEFAULT 0 COMMENT 'Ʊʶ', + Reason varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'ʧԭ', + CmsData varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cmsӿڷ', + PRIMARY KEY (`pkid`) USING BTREE +)ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'Դϴ' ROW_FORMAT = Dynamic; + +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/code/Zxd.Entity/UserCenter/UserInfo.cs b/code/Zxd.Entity/UserCenter/UserInfo.cs new file mode 100644 index 0000000..73a8fff --- /dev/null +++ b/code/Zxd.Entity/UserCenter/UserInfo.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.UserCenter +{ + [Table("userinfo")] + public class UserInfo + { + [Key] + [JsonPropertyName("uid")] + public int Uid { get; set; } + + [JsonPropertyName("appid")] + public string? Appid { get; set; } + + [JsonPropertyName("appuserid")] + public string? Appuserid { get; set; } + + [JsonPropertyName("customerid")] + public int Customerid { get; set; } + + [JsonPropertyName("resid")] + public string? Resid { get; set; } + + [JsonPropertyName("mobile")] + public string? Mobile { get; set; } + + [JsonPropertyName("unionid")] + public string? Unionid { get; set;} + + } + + public class UserInfoReq { + public string uid { get; set; } + + public string? appid { get; set; } + + public string? appuserid { get; set; } + + public string customerid { get; set; } + + public string? resid { get; set; } + public string? unionid { get; set; } + } + +} diff --git a/code/Zxd.Entity/Wework/WwUserExtuser.cs b/code/Zxd.Entity/Wework/WwUserExtuser.cs new file mode 100644 index 0000000..29b840a --- /dev/null +++ b/code/Zxd.Entity/Wework/WwUserExtuser.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Wework +{ + [Table("ww_user_extuser")] + public class WwUserExtuser + { + public string USERID { get; set; } + public string CORPID { get; set; } + public string Extuserid { get; set; } + public DateTime Ctime { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd.Entity.csproj b/code/Zxd.Entity/Zxd.Entity.csproj new file mode 100644 index 0000000..b42a441 --- /dev/null +++ b/code/Zxd.Entity/Zxd.Entity.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + diff --git a/code/Zxd.Entity/Zxd/BAS_INNERUSER.cs b/code/Zxd.Entity/Zxd/BAS_INNERUSER.cs new file mode 100644 index 0000000..3d5fdcc --- /dev/null +++ b/code/Zxd.Entity/Zxd/BAS_INNERUSER.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("BAS_INNERUSER")] + public class BAS_INNERUSER + { + [Key] + public int PKID { get; set; } + + public string UNAME { get; set; } + + public int EID { get; set; } + + public string GENDER { get; set; } + + public DateTime? BIRTHDAY { get; set; } + + public string PASSWORD { get; set; } + + public short ISDISMISS { get; set; } + + public DateTime? DISMISSTIME { get; set; } + + public int? DISMISSTYPE { get; set; } + + public DateTime? ENTRYDATE { get; set; } + + public DateTime? CTIME { get; set; } + + public int? CREATEUSER { get; set; } + + public DateTime? UTIME { get; set; } + + public int? UPDATEUSER { get; set; } + + //public DateTime? POSITIVETIME { get; set; } + + //[StringLength(50)] + //public string TRUENAME { get; set; } + + public short ISHIDE { get; set; } + + /// + /// 分机号 + /// + [NotMapped] + public int? map_FJH { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/BAS_INNERUSERSALT.cs b/code/Zxd.Entity/Zxd/BAS_INNERUSERSALT.cs new file mode 100644 index 0000000..04330a1 --- /dev/null +++ b/code/Zxd.Entity/Zxd/BAS_INNERUSERSALT.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("BAS_INNERUSERSALT")] + public class BAS_INNERUSERSALT + { + [Key] + public int PKID { get; set; } + + public int INNERUSERID { get; set; } + + public int EID { get; set; } + + public string? PWDSALT { get; set; } + + public DateTime? CTIME { get; set; } + + public int? CREATEUSER { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/BAS_PARAMETER.cs b/code/Zxd.Entity/Zxd/BAS_PARAMETER.cs new file mode 100644 index 0000000..47552c3 --- /dev/null +++ b/code/Zxd.Entity/Zxd/BAS_PARAMETER.cs @@ -0,0 +1,35 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("BAS_PARAMETER")] + public partial class BAS_PARAMETER + { + [Key] + public string? PARAKEY { get; set; } + + public string? GROUPID { get; set; } + + public string? PARAVALUE { get; set; } + + public string? PARATYPE { get; set; } + + public string? REMARK { get; set; } + + public DateTime? CTIME { get; set; } + + public int? CREATEUSER { get; set; } + + public DateTime? UTIME { get; set; } + + public int? UPDATEUSER { get; set; } + + public string? EDITFORM { get; set; } + + public string? PARANAME { get; set; } + + public string? DEPTCDOE { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/BAS_ROLE.cs b/code/Zxd.Entity/Zxd/BAS_ROLE.cs new file mode 100644 index 0000000..d3b7dc4 --- /dev/null +++ b/code/Zxd.Entity/Zxd/BAS_ROLE.cs @@ -0,0 +1,33 @@ +using System; + +using System; + +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("BAS_ROLE")] + public partial class BAS_ROLE + { + [Key] + public int ROLEID { get; set; } + + [Required] + [StringLength(100)] + public string RNAME { get; set; } + + public int SORTID { get; set; } + + public DateTime? CTIME { get; set; } + + public int? CREATEUSER { get; set; } + + public DateTime? UTIME { get; set; } + + public int? UPDATEUSER { get; set; } + + [StringLength(20)] + public string CODE { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/BasCompanyChannel.cs b/code/Zxd.Entity/Zxd/BasCompanyChannel.cs new file mode 100644 index 0000000..1879df9 --- /dev/null +++ b/code/Zxd.Entity/Zxd/BasCompanyChannel.cs @@ -0,0 +1,20 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("bas_companychannel")] + public class BasCompanyChannel + { + public BasCompanyChannel() + { + } + + [Key] + public int Id { get; set; } + public string? CompanyCode { get; set; } + public int Min { get; set; } + public int Max { get; set; } + public int Defult { get; set; } + public string? CrmCompanyCode { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/Bas_CompanyChannel.cs b/code/Zxd.Entity/Zxd/Bas_CompanyChannel.cs new file mode 100644 index 0000000..7432101 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Bas_CompanyChannel.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + public class Bas_CompanyChannel + { + [Key] + public int Id { get; set; } + + public string? CompanyCode { get; set; } + public int Min { get; set; } + public int Max { get; set; } + public int Defult { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/BaseProduct.cs b/code/Zxd.Entity/Zxd/BaseProduct.cs new file mode 100644 index 0000000..9d0218f --- /dev/null +++ b/code/Zxd.Entity/Zxd/BaseProduct.cs @@ -0,0 +1,59 @@ +using System; + +namespace Zxd.Entity.Zxd +{ + [Table("t_base_product")] + public class BaseProduct + { + public BaseProduct() + { + } + + [Key] + public int Id { get; set; } + + public string? Code { get; set; } + + public string? Name { get; set; } + + public decimal Price { get; set; } + + public int? Day { get; set; } + + public string? Moduleid { get; set; } + + public string? Remark { get; set; } + + public string? Extinfo { get; set; } + + public string? Appextinfo { get; set; } + + public string? Appext { get; set; } + + [Column("webimgurl")] + public string? WebImgUrl { get; set; } + + [Column("appimgurl")] + public string? AppImgUrl { get; set; } + + public int? Active { get; set; } + + public bool? Old { get; set; } + + public int? Groupid { get; set; } + + public DateTime Ctime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + public string? Ext { get; set; } + + public bool? Compliance { get; set; } + + [Column("effective_immediately")] + public bool? EffectiveImmediately { get; set; } + + public virtual List? BaseProductPackageRelations { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/BaseProductPackage.cs b/code/Zxd.Entity/Zxd/BaseProductPackage.cs new file mode 100644 index 0000000..9b935e2 --- /dev/null +++ b/code/Zxd.Entity/Zxd/BaseProductPackage.cs @@ -0,0 +1,51 @@ +using System; + +namespace Zxd.Entity.Zxd +{ + [Table("t_base_product_package")] + public class BaseProductPackage + { + public BaseProductPackage() + { + } + + [Key] + public int Id { get; set; } + + public string? Code { get; set; } + + public string? Name { get; set; } + + public decimal Price { get; set; } + + public string? Remark { get; set; } + + public string? Extinfo { get; set; } + + public string? Appextinfo { get; set; } + + public string? Appext { get; set; } + + [Column("webimgurl")] + public string? WebImgUrl { get; set; } + + [Column("appimgurl")] + public string? AppImgUrl { get; set; } + + public int? Active { get; set; } + + public bool? Old { get; set; } + + public int Groupid { get; set; } + + public DateTime Ctime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + [Column("effective_immediately")] + public bool? EffectiveImmediately { get; set; } + + public virtual List BaseProductPackageRelations { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/BaseProductPackageRelation.cs b/code/Zxd.Entity/Zxd/BaseProductPackageRelation.cs new file mode 100644 index 0000000..8f8309c --- /dev/null +++ b/code/Zxd.Entity/Zxd/BaseProductPackageRelation.cs @@ -0,0 +1,33 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("t_base_product_package_relation")] + public class BaseProductPackageRelation + { + public BaseProductPackageRelation() + { + } + + public int Id { get; set; } + + [Column("product_name")] + public string? ProductName { get; set; } + + public string? Moduleid { get; set; } + + public int? Day { get; set; } + + [Column("package_code")] + public string? PackageCode { get; set; } + + [Column("product_code")] + public string? ProductCode { get; set; } + + public decimal? Price { get; set; } + + public virtual BaseProduct? BaseProduct { get; set; } + + public virtual BaseProductPackage? BaseProductPackage { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/CMS_QIWEI_POSTLOG.cs b/code/Zxd.Entity/Zxd/CMS_QIWEI_POSTLOG.cs new file mode 100644 index 0000000..fb5c596 --- /dev/null +++ b/code/Zxd.Entity/Zxd/CMS_QIWEI_POSTLOG.cs @@ -0,0 +1,34 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("CMS_QIWEI_POSTLOG")] + public partial class CMS_QIWEI_POSTLOG + { + [Key] + public decimal PKID { get; set; } + + [StringLength(255)] + public string? Appid { get; set; } + + [StringLength(255)] + public string? Appuserid { get; set; } + + [StringLength(255)] + public string? Deptid { get; set; } + + [StringLength(1000)] + public string? jsondata { get; set; } + + public DateTime? ctime { get; set; } + public decimal STATUS { get; set; } + + [StringLength(255)] + public string? Reason { get; set; } + [StringLength(2000)] + public string? CmsData { get; set; } + + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/CreateCustomerDto.cs b/code/Zxd.Entity/Zxd/CreateCustomerDto.cs new file mode 100644 index 0000000..7a47b3b --- /dev/null +++ b/code/Zxd.Entity/Zxd/CreateCustomerDto.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + public class CreateCustomerDto + { + public string MOBILE { get; set; } + + public string ResId { get; set; } + + public string CustomerFrom { get; set; } + } + public class CreateCustomerRes { + public CCenum code { get; set; } + public string msg { + get { + return this.code.ToString(); + } + } + public RES_CUSTOMER model { get; set; } + } + public enum CCenum + { + 成功=0, + 客户存在=10, + + } +} diff --git a/code/Zxd.Entity/Zxd/Department.cs b/code/Zxd.Entity/Zxd/Department.cs new file mode 100644 index 0000000..5ead135 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Department.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("department")] + public class ZXDDepartment + { + [Key] + public int Id { get; set; } + + [Column("parent_id")] + public int? ParentId { get; set; } + + [Column("department_name")] + public string? DepartmentName { get; set; } + + [Column("department_type")] + public int? DepartmentType { get; set; } + + [Column("department_code")] + public string? DepartmentCode { get; set; } + + [Column("status")] + public int? Status { get; set; } + [Column("is_deleted")] + public bool IsDeleted { get; set; } + + [Column("create_time")] + public DateTime Create_Time { get; set; } + + [Column("update_time")] + public DateTime Update_Time { get; set; } + + } +} diff --git a/code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_DICT.cs b/code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_DICT.cs new file mode 100644 index 0000000..ecd5dfb --- /dev/null +++ b/code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_DICT.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_soft_dict")] + public class EMPLOYEE_SOFT_DICT + { + [Key] + public int id { get; set; } + + public int eid { get; set; } + public string appusername { get; set; } + public string resid { get; set; } + + } +} diff --git a/code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_LOG.cs b/code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_LOG.cs new file mode 100644 index 0000000..4bbe8e6 --- /dev/null +++ b/code/Zxd.Entity/Zxd/EMPLOYEE_SOFT_LOG.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_soft_log")] + public class EMPLOYEE_SOFT_LOG + { + [Key] + public int id { get; set; } + public int eid { get; set; } + public DateTime createtime { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/EarlyWarningLog.cs b/code/Zxd.Entity/Zxd/EarlyWarningLog.cs new file mode 100644 index 0000000..1244db9 --- /dev/null +++ b/code/Zxd.Entity/Zxd/EarlyWarningLog.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("t_early_warning_log")] + public class EarlyWarningLog + { + [Key] + public int Id { get; set; } + + /// + /// 工号 + /// + public int Eid { get; set; } + + /// + /// 姓名 + /// + public string? Name { get; set; } + + /// + /// 预警值 + /// + [Column("early_warning")] + public decimal EarlyWarning { get; set; } + + /// + /// 最大资源量 + /// + public int Resource { get; set; } + + /// + /// 预警类型 + /// + public EarlyWarningType Type { get; set; } + + /// + /// 去重加微数 + /// + public int Distinct { get; set; } + + /// + /// 接粉周期 + /// + [Column("period_from")] + public DateTime? PeriodFrom { get; set; } + + /// + /// 接粉周期 + /// + [Column("period_to")] + public DateTime? PeriodTo { get; set; } + + /// + /// 状态 + /// + public EarlyWaningLogStatus Status { get; set; } + + [Column("create_time")] + public DateTime CreateTime { get; set; } + + [Column("update_user")] + public string? UpdateUser { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + [Column("template_id")] + public int? TemplateId { get; set; } + + [Column("template_index")] + public string? TemplateIndex { get; set; } + + public int Deptid { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/EarlyWarningSetting.cs b/code/Zxd.Entity/Zxd/EarlyWarningSetting.cs new file mode 100644 index 0000000..5e25e66 --- /dev/null +++ b/code/Zxd.Entity/Zxd/EarlyWarningSetting.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("t_early_warning_setting")] + public class EarlyWarningSetting + { + [Key] + public int Id { get; set; } + + public int Eid { get; set; } + + public string? Name { get; set; } + + public int Deptid { get; set; } + + [Column("create_user")] + public string? CreateUser { get; set; } + + [Column("create_time")] + public DateTime? CreateTime { get; set; } + + [Column("update_user")] + public string? UpdateUser { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + [Column("template_id")] + public int? TemplateId { get; set; } + + [Column("maxnum")] + public int MaxNum { get; set; } + [Column("haschangenum")] + public int HasChangeNum { get; set; } + + public EarlyWarningTemplate? EarlyWarningTemplate { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/EarlyWarningTemplate.cs b/code/Zxd.Entity/Zxd/EarlyWarningTemplate.cs new file mode 100644 index 0000000..2b264ca --- /dev/null +++ b/code/Zxd.Entity/Zxd/EarlyWarningTemplate.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("t_early_warning_template")] + public class EarlyWarningTemplate + { + [Key] + public int Id { get; set; } + public int Deptid { get; set; } + + [Column("template_name")] + public string? TemplateName { get; set; } + + [Column("period_from")] + public DateTime PeriodFrom { get; set; } + + [Column("period_to")] + public DateTime PeriodTo { get; set; } + + [Column("prewarning_value")] + public string? PrewarningValue { get; set; } + + [Column("count")] + public int? Count { get; set; } + + [Column("maxnum")] + public int Maxnum { get; set; } + + [NotMapped] + public List PrewarningValueJson + { + get + { + return string.IsNullOrEmpty(PrewarningValue) ? new List() + : JsonSerializer.Deserialize>(PrewarningValue); + } + } + + public List? EarlyWarningSettings { get; set; } + } + + public class EarlyWarningTemplatePrewarningValue + { + [JsonPropertyName("type")] + public EarlyWarningType Type { get; set; } + + [JsonPropertyName("value")] + public int Value { get; set; } + + [JsonPropertyName("guid")] + public string? Guid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/EarlyWarningUser.cs b/code/Zxd.Entity/Zxd/EarlyWarningUser.cs new file mode 100644 index 0000000..e70c4a3 --- /dev/null +++ b/code/Zxd.Entity/Zxd/EarlyWarningUser.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + /// + /// 预警接受者 + /// + [Table("t_early_warning_user")] + public class EarlyWarningUser + { + [Key] + public int Id { get; set; } + + public string? Code { get; set; } + + /// + /// 企微id + /// + [Column("wxwork_id")] + public string? WxWorkId { get; set; } + + public int Deptid { get; set; } + + [Column("crop_id")] + public string? CropId { get; set; } + + [Column("app_id")] + public string? AppId { get; set; } + + [Column("create_user")] + public string? CreateUser { get; set; } + + [Column("create_time")] + public DateTime? CreateTime { get; set; } + + [Column("update_user")] + public string? UpdateUser { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + [Column("participant_ids")] + public string? Participant { get; set; } + + [NotMapped] + public List ParticipantIds + { + get + { + return string.IsNullOrEmpty(Participant) ? new List() : Participant.Split(',').Select(x => int.Parse(x)).ToList(); + } + } + } +} diff --git a/code/Zxd.Entity/Zxd/Employee.cs b/code/Zxd.Entity/Zxd/Employee.cs new file mode 100644 index 0000000..295598f --- /dev/null +++ b/code/Zxd.Entity/Zxd/Employee.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee")] + public class Employee + { + [Key] + public int id { get; set; } + public int? status { get; set; } + public int? employee_id { get; set; } + public string? employee_name { get; set; } + public string? phone { get; set; } + public string? showPhone { get; set; } + public int? is_deleted { get; set; } + public string? appid { get; set; } + public DateTime? update_time { get; set; } + public DateTime? create_time { get; set; } + public string? phone_resid { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/EmployeeDepartmentDetail.cs b/code/Zxd.Entity/Zxd/EmployeeDepartmentDetail.cs new file mode 100644 index 0000000..7d95259 --- /dev/null +++ b/code/Zxd.Entity/Zxd/EmployeeDepartmentDetail.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_department_detail")] + public class EmployeeDepartmentDetail + { + [Key] + public int id { get; set; } + public int? eid { get; set; } + public int department_id { get; set; } + public string department_name { get; set; } + public int department_type { get; set; } + + /// + /// 1 在职 2 离职 3试用 4待入职 + /// + [Column("emp_status")] + public int empStatus { get; set; } + public int level { get; set; } + public int is_deleted { get; set; } + public DateTime create_time { get; set; } + public DateTime update_time { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/EmployeeDepartmentFull.cs b/code/Zxd.Entity/Zxd/EmployeeDepartmentFull.cs new file mode 100644 index 0000000..12213d0 --- /dev/null +++ b/code/Zxd.Entity/Zxd/EmployeeDepartmentFull.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_department_full")] + public class EmployeeDepartmentFull + { + + [Key] + public int id { get; set; } + public int eid { get; set; } + public string appid { get; set; } + public string app_name { get; set; } + public DateTime create_time { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/Employee_Department_Detail.cs b/code/Zxd.Entity/Zxd/Employee_Department_Detail.cs new file mode 100644 index 0000000..5d69379 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Employee_Department_Detail.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_department_detail")] + public class Employee_Department_Detail + { + [Key] + public int id { get; set; } + public int eid { get; set; } + public int? department_id { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/FieldSetting.cs b/code/Zxd.Entity/Zxd/FieldSetting.cs new file mode 100644 index 0000000..616ba87 --- /dev/null +++ b/code/Zxd.Entity/Zxd/FieldSetting.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("t_field_setting")] + public class FieldSetting + { + [Key] + public int Id { get; set; } + + public int Eid { get; set; } + + [Column("field_id")] + public int FieldId { get; set; } + + public int Order { get; set; } + + public string? Fixed { get; set; } + + public bool Hide { get; set; } + + public TableField? TableField { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/FinishedProduct.cs b/code/Zxd.Entity/Zxd/FinishedProduct.cs new file mode 100644 index 0000000..bd369a7 --- /dev/null +++ b/code/Zxd.Entity/Zxd/FinishedProduct.cs @@ -0,0 +1,135 @@ +using System; + +namespace Zxd.Entity.Zxd +{ + [Table("t_finished_product")] + public class FinishedProduct + { + public FinishedProduct() + { + } + + [Key] + public int Id { get; set; } + + [Column("standard_product_id")] + public int StandardProductId { get; set; } + + [Column("product_type_id")] + public int ProductTypeId { get; set; } + + [Column("product_series_id")] + public int ProductSeriesId { get; set; } + + [Column("product_category_id")] + public int ProductCategoryId { get; set; } + + [Column("product_code")] + public string? ProductCode { get; set; } + + [Column("product_name")] + public string? ProductName { get; set; } + + [Column("deptid")] + public int Deptid { get; set; } + + [Column("product_price")] + public decimal ProducPrice { get; set; } + + public string? Day { get; set; } + + public int Coefficient { get; set; } + + [Column("product_server_type")] + public ProductServerType ProductServerType { get; set; } + + [Column("auto_open")] + public bool AutoOpen { get; set; } + + [Column("open_coendition")] + public int OpenCondition { get; set; } + + [Column("status")] + public ProductStatus Status { get; set; } + + [Column("give")] + public bool Give { get; set; } + + [Column("discount")] + public bool Discount { get; set; } + + public bool Custom { get; set; } + + [Column("discoun_sections")] + public string? DiscounSections { get; set; } + + [Column("give_products")] + public string? GiveProducts { get; set; } + + [Column("custom_prices")] + public string? CustomPrices { get; set; } + + [Column("upgrade")] + public bool Upgrade { get; set; } + + [Column("other_classify")] + public bool OtherClassify { get; set; } + + [Column("buy_online")] + public bool BuyOnline { get; set; } + + public string? Remark { get; set; } + + public string? Module { get; set; } + + public virtual StandardProduct? StandardProduct { get; set; } + + [NotMapped] + public List? GiveProductList + { + get + { + return string.IsNullOrEmpty(GiveProducts) ? null + : JsonSerializer.Deserialize>(GiveProducts); + } + } + + [NotMapped] + public List? DiscounSectionList + { + get + { + return string.IsNullOrEmpty(DiscounSections) ? null + : JsonSerializer.Deserialize>(DiscounSections); + } + } + + [NotMapped] + public List? CustomPriceList + { + get + { + return string.IsNullOrEmpty(CustomPrices) ? null + : JsonSerializer.Deserialize>(CustomPrices); + } + } + } + + public class FinishedGiveProduct + { + public string? ProductCode { get; set; } + + public bool? OrderPaymentPresenter { get; set; } + + public bool? AfterPaymentPresenter { get; set; } + + public int? Sort { get; set; } + } + + public class FinishedCustomPrice + { + public decimal? Max { get; set; } + + public decimal? Min { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/L2SOFTORDER.cs b/code/Zxd.Entity/Zxd/L2SOFTORDER.cs new file mode 100644 index 0000000..f48ece7 --- /dev/null +++ b/code/Zxd.Entity/Zxd/L2SOFTORDER.cs @@ -0,0 +1,86 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("L2_SOFT_ORDER")] + public partial class L2_SOFT_ORDER + { + [Key] + public int ORDERID { get; set; } + + [StringLength(100)] + public string? RESID { get; set; } + + public int? PRODUCTID { get; set; } + + //[Required] + [StringLength(50)] + public string? PRODUCTCODE { get; set; } + + //[Required] + [StringLength(50)] + public string? USERNAME { get; set; } + + /// + /// ����״̬ :0δ��ͨ��1�ѿ�ͨ��2�ѳ�����3�߼�ɾ�� + /// + public int? ORDERSTATUS { get; set; } + + public int? ORDERTYPE { get; set; } + + public int? OPENUSER { get; set; } + + public int? DAYS { get; set; } + + public decimal? PRICE { get; set; } + + public DateTime? OTIME { get; set; } + + public decimal? CANCELUSER { get; set; } + + public DateTime? CANCELTIME { get; set; } + + [StringLength(200)] + public string? MEMO { get; set; } + + public int? CREATEUSER { get; set; } + + public DateTime CTIME { get; set; } + + public int? COMPANYID { get; set; } + + [StringLength(50)] + public string? WEBORDERID { get; set; } + + public string? companycode { get; set; } + public int? MainOrderId { get; set; } + public int? deptid { get; set; } + public string? deptName { get; set; } + public int? groupid { get; set; } + public int? sourcetype { get; set; } + + /// + /// 合同状态 + /// + public int? contractstatus { get; set; } + + /// + /// 合同签订时间 + /// + public DateTime? contractctime { get; set; } + + [StringLength(50)] + public string? CONTRACTCODE { get; set; } + + public int? RISKCTRLSTATUS { get; set; } + + [StringLength(30)] + public string? CNAME { get; set; } + + public string? idcard { get; set; } + public int? adequacy { get; set; } + public string? productname { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/Meeting.cs b/code/Zxd.Entity/Zxd/Meeting.cs new file mode 100644 index 0000000..7833bd9 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Meeting.cs @@ -0,0 +1,57 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("t_meeting")] + public class Meeting + { + public Meeting() + { + MeetingAccessories = new List(); + MeetingParticipants = new List(); + } + + [Key] + public int Id { get; set; } + + [Column("meeting_name")] + public string? MeetingName { get; set; } + + [Column("meeting_type")] + public MeetingType MeetingType { get; set; } + + [Column("begin_time")] + public DateTime BeginTime { get; set; } + + [Column("continue_hour")] + public int ContinueHour { get; set; } + + [Column("continue_minute")] + public int ContinueMinute { get; set; } + + public string? Site { get; set; } + + public string? Compere { get; set; } + + public string? Remark { get; set; } + + [Column("create_user")] + public string? CreateUser { get; set; } + + [Column("create_time")] + public DateTime CreateTime { get; set; } + + [Column("is_delete")] + public bool IsDelete { get; set; } + + [Column("update_user")] + public string? UpdateUser { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + public virtual List MeetingAccessories { get; set; } + + public virtual List MeetingParticipants { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/MeetingAccessory.cs b/code/Zxd.Entity/Zxd/MeetingAccessory.cs new file mode 100644 index 0000000..93093ff --- /dev/null +++ b/code/Zxd.Entity/Zxd/MeetingAccessory.cs @@ -0,0 +1,38 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("meeting_accessory")] + public class MeetingAccessory + { + public MeetingAccessory() + { + } + + [Key] + public int Id { get; set; } + + [Column("meeting_id")] + public int MeetingId { get; set; } + + [Column("file_name")] + public string? FileName { get; set; } + + [Column("file_url")] + public string? FileUrl { get; set; } + + [Column("file_size")] + public string? FileSize { get; set; } + + [Column("uploader")] + public string? Uploader { get; set; } + + [Column("upload_eid")] + public int UploadEid { get; set; } + + [Column("upload_time")] + public DateTime UploadTime { get; set; } + + public virtual Meeting? Meeting { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/MeetingParticipant.cs b/code/Zxd.Entity/Zxd/MeetingParticipant.cs new file mode 100644 index 0000000..37e3a25 --- /dev/null +++ b/code/Zxd.Entity/Zxd/MeetingParticipant.cs @@ -0,0 +1,26 @@ +using System; +namespace Zxd.Entity.Zxd +{ + public class MeetingParticipant + { + public MeetingParticipant() + { + } + + [Key] + public int Id { get; set; } + + [Column("meeting_id")] + public int MeetingId { get; set; } + + public int Eid { get; set; } + + /// + /// 参与人 + /// + public string? Paricipant { get; set; } + + public virtual Meeting? Meeting { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/Order/WX_SZZYORDERDEPOSIT.cs b/code/Zxd.Entity/Zxd/Order/WX_SZZYORDERDEPOSIT.cs new file mode 100644 index 0000000..64cad45 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Order/WX_SZZYORDERDEPOSIT.cs @@ -0,0 +1,43 @@ +namespace Zxd.Entity.Zxd.Order +{ + [Table("WX_SZZYORDERDEPOSIT")] + public class WX_SZZYORDERDEPOSIT + { + [Key] + public int id { get; set; } + + public string? resid { get; set; } + public int paytype { get; set; } + public string? paytypename { get; set; } + public DateTime? paydate { get; set; } + public decimal? payprice { get; set; } + public string? payname { get; set; } + public string? remark { get; set; } + public int auditstatus { get; set; } + public int? auditor { get; set; } + public string? auditorname { get; set; } + public DateTime? audittime { get; set; } + public DateTime ctime { get; set; } + public string? payno { get; set; } + public int isuse { get; set; } + public string? companycode { get; set; } + public int? orderid { get; set; } + public int? channel { get; set; } + public string? tradeno { get; set; } + public int? isdelete { get; set; } + public int? creator { get; set; } + public string? creatorname { get; set; } + public string? rejectremark { get; set; } + public string? checkreslut { get; set; } + public DateTime? checkpaytime { get; set; } + public decimal? lastprice { get; set; } + public decimal? useprice { get; set; } + public decimal? frozenprice { get; set; } + public int? isbu { get; set; } + public DateTime? butime { get; set; } + public string? deptcode { get; set; } + public int? deptid { get; set; } + public string? deptName { get; set; } + public int? groupid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/Order/WX_SZZYORDER_BIND.cs b/code/Zxd.Entity/Zxd/Order/WX_SZZYORDER_BIND.cs new file mode 100644 index 0000000..e725f26 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Order/WX_SZZYORDER_BIND.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd.Order +{ + [Table("WX_SZZYORDER_BIND")] + public class WX_SZZYORDER_BIND + { + [Key] + public int? Id { get; set; } + + public DateTime? CreateTime { get; set; } + + /// + /// 绑定状态 0=未绑定,1=自动绑定,2=手动绑定 + /// + public int? BindType { get; set; } + + /// + /// 支付类型 wechat|wxWork|alipay + /// + public string? PayType { get; set; } + + /// + /// 交易流水号 + /// + public string? TradeNo { get; set; } + + /// + /// 外部流水号 + /// + public string? OutTradeNo { get; set; } + + /// + /// 内部流水号 + /// + public string? UserTradeNo { get; set; } + + /// + /// 金额 + /// + public decimal? TotalAmount { get; set; } + + /// + /// 交易状态 1|0 + /// + public int? TradeStatus { get; set; } + + /// + /// UnionId + /// + public string? UnionId { get; set; } + + /// + /// 员工Id + /// + public int? EId { get; set; } + + /// + /// 备注 + /// + public string? Remark { get; set; } + + /// + /// 客户Id + /// + public string? ResId { get; set; } + + /// + /// 渠道 + /// + public int? Channel { get; set; } + + /// + /// 身份密钥 + /// + public string IdentityKey { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/Order/WX_SzzyOrderRefund.cs b/code/Zxd.Entity/Zxd/Order/WX_SzzyOrderRefund.cs new file mode 100644 index 0000000..1df26dd --- /dev/null +++ b/code/Zxd.Entity/Zxd/Order/WX_SzzyOrderRefund.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd.Order +{ + [Table("wx_szzyorderrefund")] + public class WX_SzzyOrderRefund + { + [Key] + public long id { get; set; } + + public int orderid { get; set; } + public decimal refundprice { get; set; } + public string? account { get; set; } + public string? username { get; set; } + public int? refundtype { get; set; } + public string? refundtypename { get; set; } + public DateTime? refunddate { get; set; } + public string? remark { get; set; } + public string? att { get; set; } + public int auditstatus { get; set; } + public int? auditor { get; set; } + public string? auditorname { get; set; } + public DateTime? audittime { get; set; } + public DateTime ctime { get; set; } + public string? att2 { get; set; } + public string? companycode { get; set; } + public int? channel { get; set; } + public int? isdelete { get; set; } + public int? ismorepay { get; set; } + public int? creator { get; set; } + public string? creatorname { get; set; } + + /// + /// 1:需要实际退款 0:退回可用余额(不需要实际退款) + /// + public int? isacturalrefund { get; set; } + + public int? isold { get; set; } + public string? resid { get; set; } + public string? deptcode { get; set; } + + /// + /// 申请类型 + /// + public int? applytype { get; set; } + + public int? deptid { get; set; } + public string? deptName { get; set; } + public int? groupid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/Order/Wx_SzzyOrder_HandGift.cs b/code/Zxd.Entity/Zxd/Order/Wx_SzzyOrder_HandGift.cs new file mode 100644 index 0000000..45f5fda --- /dev/null +++ b/code/Zxd.Entity/Zxd/Order/Wx_SzzyOrder_HandGift.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd.Order +{ + [Table("Wx_SzzyOrder_HandGift")] + public class Wx_SzzyOrder_HandGift + { + [Key] + public int orderid { get; set; } + + public int? mainorderid { get; set; } + public string? softusername { get; set; } + public string? resid { get; set; } + public int? productid { get; set; } + public string? productcode { get; set; } + public int? orderstatus { get; set; } + public string? subproductcode { get; set; } + public string? subproductname { get; set; } + public string? memo { get; set; } + public string? createuser { get; set; } + public DateTime ctime { get; set; } + public int? channel { get; set; } + public string? companycode { get; set; } + public int? giftdays { get; set; } + public string? openuser { get; set; } + public DateTime? optime { get; set; } + public long? szzyorderid { get; set; } + + public string? checkmemo { get; set; } + + public DateTime? otime { get; set; } + public int? producttype { get; set; } + + public DateTime? closetime { get; set; } + public string? closeuser { get; set; } + public string? closememo { get; set; } + public int? auditType { get; set; } + public int? saleDeptId { get; set; } + + /// + /// 合同状态 + /// + public int contractstatus { get; set; } + + /// + /// 合同签订时间 + /// + public DateTime? contractctime { get; set; } + + [StringLength(50)] + public string? CONTRACTCODE { get; set; } + + public int RISKCTRLSTATUS { get; set; } + + [StringLength(30)] + public string? CNAME { get; set; } + + public string? idcard { get; set; } + public int? adequacy { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/QiweiOnlePay/QWActivityProduct.cs b/code/Zxd.Entity/Zxd/QiweiOnlePay/QWActivityProduct.cs new file mode 100644 index 0000000..a477416 --- /dev/null +++ b/code/Zxd.Entity/Zxd/QiweiOnlePay/QWActivityProduct.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd.QiweiOnlePay +{ + [Table("qiwei_activity_product")] + public class QWActivityProduct + { + [Key] + public int Id { get; set; } + + public int ActId { get; set; } + public string? ProductCode { get; set; } + public int? IsFirst { get; set; } + public int? Status { get; set; } + public int? DeptId { get; set; } + public DateTime? Ctime { get; set; } + public DateTime? Utime { get; set; } + public int? Eid { get; set; } + public string? EName { get; set; } + public int? Order { get; set; } + public QiWeiActivity QiWeiActivity { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivity.cs b/code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivity.cs new file mode 100644 index 0000000..00e632b --- /dev/null +++ b/code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivity.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd.QiweiOnlePay +{ + [Table("qiwei_activity")] + public class QiWeiActivity + { + [Key] + public int Id { get; set; } + + public string? Name { get; set; } + public DateTime? StartTime { get; set; } + public DateTime? EndTime { get; set; } + public int? Num { get; set; } + public string? Remark { get; set; } + public int? Status { get; set; } + public DateTime? Ctime { get; set; } + public DateTime? Utime { get; set; } + public int? Eid { get; set; } + public string? EName { get; set; } + public string? CompanyCode { get; set; } + public int? Order { get; set; } + public List? QiWeiActivityDept { get; set; } + public List? QWActivityProduct { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivityDept.cs b/code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivityDept.cs new file mode 100644 index 0000000..bd445dc --- /dev/null +++ b/code/Zxd.Entity/Zxd/QiweiOnlePay/QiWeiActivityDept.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd.QiweiOnlePay +{ + [Table("qiwei_activity_dept")] + public class QiWeiActivityDept + { + [Key] + public int ActId { get; set; } + + [Key] + public int DeptId { get; set; } + + public DateTime? Ctime { get; set; } + + public QiWeiActivity? QiWeiActivity { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/RES_APPLY.cs b/code/Zxd.Entity/Zxd/RES_APPLY.cs new file mode 100644 index 0000000..3279954 --- /dev/null +++ b/code/Zxd.Entity/Zxd/RES_APPLY.cs @@ -0,0 +1,55 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("RES_APPLY")] + public partial class RES_APPLY + { + [Key] + public decimal PKID { get; set; } + + [Required] + [StringLength(100)] + public string RESOURCETAG { get; set; } + + [Required] + [StringLength(18)] + public string RESID { get; set; } + + [StringLength(50)] + public string USERNAME { get; set; } + + [StringLength(1000)] + public string JSONDATA { get; set; } + + public DateTime? RTIME { get; set; } + + public DateTime? CTIME { get; set; } + + public decimal? JSONTYPE { get; set; } + + public decimal STATUS { get; set; } + + [StringLength(255)] + public string MOBILE { get; set; } + + [StringLength(20)] + public string DATATYPE { get; set; } + + [StringLength(1000)] + public string EXTXML { get; set; } + + [StringLength(50)] + public string ENMOBILE { get; set; } + + public decimal? ERR_COUNT { get; set; } + + [StringLength(1000)] + public string ERR_STR { get; set; } + + [StringLength(200)] + public string KWORD { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/RES_CUSTOMER.cs b/code/Zxd.Entity/Zxd/RES_CUSTOMER.cs new file mode 100644 index 0000000..751a18b --- /dev/null +++ b/code/Zxd.Entity/Zxd/RES_CUSTOMER.cs @@ -0,0 +1,18 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("RES_CUSTOMER")] + public class RES_CUSTOMER + { + [Key] + public string? RESID { get; set; } + public string? UMID { get; set; } + public string CUSTOMERID { get; set; } + public DateTime ctime { get; set; } + public string customerfrom { get; set; } + public string lastnum3 { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/RES_CUSTOMERDETAIL.cs b/code/Zxd.Entity/Zxd/RES_CUSTOMERDETAIL.cs new file mode 100644 index 0000000..faa7b06 --- /dev/null +++ b/code/Zxd.Entity/Zxd/RES_CUSTOMERDETAIL.cs @@ -0,0 +1,37 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("RES_CUSTOMERDETAIL")] + public class RES_CUSTOMERDETAIL + { + [Key] + public string RESID { get; set; } + public string caccount { get; set; } + public string email { get; set; } + public string cname { get; set; } + public string gender { get; set; } + public DateTime birthday { get; set; } + public int provinceid { get; set; } + public int cityid { get; set; } + public string address { get; set; } + public string customertypeid { get; set; } + public string amounttypeid { get; set; } + public string jobtypeid { get; set; } + public string operationtype { get; set; } + public string msn { get; set; } + public string qq { get; set; } + public string fax { get; set; } + public string customerfrombig { get; set; } + public string primarynumberaddress { get; set; } + public string specialmemo { get; set; } + public int createuser { get; set; } + public DateTime utime { get; set; } + public int updateuser { get; set; } + public int isprimarynum { get; set; } + public string zx_userid { get; set; } + public string remark { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/RES_CUSTOMERUSER.cs b/code/Zxd.Entity/Zxd/RES_CUSTOMERUSER.cs new file mode 100644 index 0000000..e09d52e --- /dev/null +++ b/code/Zxd.Entity/Zxd/RES_CUSTOMERUSER.cs @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("RES_CUSTOMERUSER")] + public partial class RES_CUSTOMERUSER + { + [Key] + public decimal PKID { get; set; } + + public string? RESID { get; set; } + + public string? USERNAME { get; set; } + + public DateTime? CTIME { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/RES_MOBILE_MD5.cs b/code/Zxd.Entity/Zxd/RES_MOBILE_MD5.cs new file mode 100644 index 0000000..d60e1bd --- /dev/null +++ b/code/Zxd.Entity/Zxd/RES_MOBILE_MD5.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace Zxd.Entity.Zxd +{ + public class RES_MOBILE_MD5 + { + [Key] + public string ResId { get; set; } + + public string Md5 { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/RES_RESOURCEMOBILE.cs b/code/Zxd.Entity/Zxd/RES_RESOURCEMOBILE.cs new file mode 100644 index 0000000..878c221 --- /dev/null +++ b/code/Zxd.Entity/Zxd/RES_RESOURCEMOBILE.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("RES_RESOURCEMOBILE")] + public partial class RES_RESOURCEMOBILE + { + [Key] + public string? RESID { get; set; } + + public string? MOBILE { get; set; } + + public int? ISMOBILE { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/Res_Tag.cs b/code/Zxd.Entity/Zxd/Res_Tag.cs new file mode 100644 index 0000000..9b52c51 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Res_Tag.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("res_tag")] + public class Res_Tag + { + [Key] + public int id { get; set; } + /// + /// 资源ID + /// + public string resid { get; set; } + /// + /// 标签 + /// + public string tag { get; set; } + /// + /// 是否删除 + /// + public int isdelete { get; set; } + + /// + /// 创建人工号 + /// + public int ceid { get; set; } + /// + /// 删除者工号 + /// + public int deleteeid { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/SMS_MESSAGE.cs b/code/Zxd.Entity/Zxd/SMS_MESSAGE.cs new file mode 100644 index 0000000..2f0b93b --- /dev/null +++ b/code/Zxd.Entity/Zxd/SMS_MESSAGE.cs @@ -0,0 +1,34 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("SMS_MESSAGE")] + public partial class SMS_MESSAGE + { + [Key] + public decimal MESSAGEID { get; set; } + + [Required] + [StringLength(300)] + public string MESSAGE { get; set; } + + //[StringLength(18)] + public string RESID { get; set; } + + [Required] + [StringLength(50)] + public string TYPECODE { get; set; } + + [StringLength(50)] + public string SUBTYPECODE { get; set; } + + [StringLength(6)] + public string CLIENTCODE { get; set; } + + public DateTime CTIME { get; set; } + + public decimal CREATEUSER { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/SMS_MSGSUBTYPE.cs b/code/Zxd.Entity/Zxd/SMS_MSGSUBTYPE.cs new file mode 100644 index 0000000..5a8773d --- /dev/null +++ b/code/Zxd.Entity/Zxd/SMS_MSGSUBTYPE.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("UPDEV.SMS_MSGSUBTYPE")] + public partial class SMS_MSGSUBTYPE + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] + public SMS_MSGSUBTYPE() + { + //SMS_MSGTEMPLATE = new HashSet(); + SMS_MSGTYPE_CLIENT = new HashSet(); + } + + [Key] + public decimal SUBTYPEID { get; set; } + + [Required] + [StringLength(50)] + public string SUBTYPENAME { get; set; } + + [StringLength(50)] + public string TYPECODE { get; set; } + + public DateTime? CTIME { get; set; } + + public decimal? CREATEUSER { get; set; } + + public DateTime? UTIME { get; set; } + + public decimal? UPDATEUSER { get; set; } + + [StringLength(50)] + public string SUBTYPECODE { get; set; } + + //public virtual SMS_MSGTYPE SMS_MSGTYPE { get; set; } + + //[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + //public virtual ICollection SMS_MSGTEMPLATE { get; set; } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] + public virtual ICollection SMS_MSGTYPE_CLIENT { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/SMS_MSGTYPE_CLIENT.cs b/code/Zxd.Entity/Zxd/SMS_MSGTYPE_CLIENT.cs new file mode 100644 index 0000000..345ed4c --- /dev/null +++ b/code/Zxd.Entity/Zxd/SMS_MSGTYPE_CLIENT.cs @@ -0,0 +1,33 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("SMS_MSGTYPE_CLIENT")] + public partial class SMS_MSGTYPE_CLIENT + { + [Key] + public decimal PKID { get; set; } + + public decimal SUBTYPEID { get; set; } + + [Required] + [StringLength(50)] + public string TYPECODE { get; set; } + + [Required] + [StringLength(6)] + public string CLIENTCODE { get; set; } + + public DateTime? CTIME { get; set; } + + public decimal? CREATEUSER { get; set; } + + public decimal? COMPANYID { get; set; } + + //public virtual SMS_ACCOUNT SMS_ACCOUNT { get; set; } + + //public virtual SMS_MSGSUBTYPE SMS_MSGSUBTYPE { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND.cs b/code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND.cs new file mode 100644 index 0000000..36fce28 --- /dev/null +++ b/code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_phone_bind")] + public class EMPLOYEE_PHONE_BIND + { + [Key] + public int id { get; set; } + public int eid { get; set; } + public string resid { get; set; } + public int is_main { get; set; } + public string? show_phone { get; set; } + public DateTime? last_empower_time { get; set; } + public string? appusername { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND_LOG.cs b/code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND_LOG.cs new file mode 100644 index 0000000..49784cc --- /dev/null +++ b/code/Zxd.Entity/Zxd/SOFT_EMPLOYEE_BIND_LOG.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("employee_phone_bind_log")] + public class EMPLOYEE_PHONE_BIND_LOG + { + [Key] + public int id { get; set; } + public int? from_by_eid { get; set; } + public DateTime createtime { get; set; } + public string? type { get; set; } + public string? resid { get; set; } + public int? to_by_eid { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/SOFT_USER.cs b/code/Zxd.Entity/Zxd/SOFT_USER.cs new file mode 100644 index 0000000..2018a82 --- /dev/null +++ b/code/Zxd.Entity/Zxd/SOFT_USER.cs @@ -0,0 +1,68 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("SOFT_USER")] + public partial class SOFT_USER + { + [Key] + [StringLength(50)] + public string? USERNAME { get; set; } + + [Required] + [StringLength(50)] + public string? USERPASS { get; set; } + + public int? USERNO { get; set; } + + public int? USERLEVEL { get; set; } + + public short? ACCEPTSMS { get; set; } + + public int? REGCAMPAINID { get; set; } + + [StringLength(1)] + public string? REGPLATFORM { get; set; } + + public short? ISACTIVE { get; set; } + + public DateTime? ACTIVETIME { get; set; } + + [StringLength(18)] + public string? ACTIVERESID { get; set; } + + public int? ACTCAMPAINID { get; set; } + + public DateTime? UTIME { get; set; } + + public DateTime? CTIME { get; set; } + + public int? COMPANYID { get; set; } + + public DateTime? REGDATE { get; set; } + + [StringLength(18)] + public string? RESID { get; set; } + [StringLength(50)] + public string? UMID { get; set; } + public string? EMAIL { get; set; } + public string? IP { get; set; } + public int? EID { get; set; } + + /// + /// ***第三方用户ID*** + /// + public string? OPENID { get; set; } + + /// + /// ***第三方平台*** + /// + public string? OPENPLAT { get; set; } + + public string? UNIONID { get; set; } + public string? LIVECODE { get; set; } + public string? REGSOURCE { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/ScreenRecord.cs b/code/Zxd.Entity/Zxd/ScreenRecord.cs new file mode 100644 index 0000000..1e22988 --- /dev/null +++ b/code/Zxd.Entity/Zxd/ScreenRecord.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + /// + /// 录屏数据 + /// + [Table("t_screen_record")] + public class ScreenRecord + { + /// + /// 主键 + /// + [Key] + public int id { get; set; } + /// + /// 主控ID + /// + [Column("master_id")] + public string MasterId { get; set; } + /// + /// 主控IP + /// + [Column("master_ip")] + public string MasterIP { get; set; } + /// + /// 主控姓名 + /// + [Column("master_name")] + public string MasterName { get; set; } + /// + /// 主控设备码 + /// + [Column("master_device_code")] + public string MasterDeviceCode { get; set; } + /// + /// 被控ID + /// + [Column("slave_id")] + public string SlaveId { get; set; } + /// + /// 被控IP + /// + [Column("slave_ip")] + public string SlaveIP { get; set; } + /// + /// 被控姓名 + /// + [Column("slave_name")] + public string SlaveName { get; set; } + /// + /// 被控设备码 + /// + [Column("slave_device_code")] + public string SlaveDeviceCode { get; set; } + /// + /// 发起链接日期 + /// + [Column("init_connect_time")] + public DateTime? InitConnectTime { get; set; } + /// + /// 计划链接时长 + /// + [Column("plan_connect_time")] + public int? PlanConnectTime { get; set; } + /// + /// 实际开始日期 + /// + [Column("real_start_time")] + public DateTime? RealStartTime { get; set; } + /// + /// 实际结束日期 + /// + [Column("real_end_time")] + public DateTime? RealEndTime { get; set; } + /// + /// 录屏文件地址 + /// + [Column("file_url")] + public string? FileUrl { get; set; } + /// + /// 0-检验中,1-校验成功,2-校验失败,3-远程连接中, + /// + [Column("state")] + public int? State { get; set; } + /// + /// 失败类型,0-拒绝连接,1-达到并发上限,2-非白名单 + /// + [Column("fail_type")] + public int? FailType { get; set; } + /// + /// 创建时间 + /// + [Column("ctime")] + public DateTime? CTime { get; set; } + /// + /// 更新时间 + /// + [Column("utime")] + public DateTime? UTime { get; set; } + + } +} diff --git a/code/Zxd.Entity/Zxd/Soft_User_CH.cs b/code/Zxd.Entity/Zxd/Soft_User_CH.cs new file mode 100644 index 0000000..60f1822 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Soft_User_CH.cs @@ -0,0 +1,17 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("soft_user_ch")] + public class Soft_User_CH + { + [Key] + public string UserName { get; set; } + + public int CH { get; set; } + public DateTime CTime { get; set; } + public int Eid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/Soft_Userinfo_Sub.cs b/code/Zxd.Entity/Zxd/Soft_Userinfo_Sub.cs new file mode 100644 index 0000000..3473260 --- /dev/null +++ b/code/Zxd.Entity/Zxd/Soft_Userinfo_Sub.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("Soft_Userinfo_Sub")] + public class Soft_Userinfo_Sub + { + [Key] + public int uid { get; set; } + public int? cid { get; set; } + public string appid { get; set; } + public string appuserid { get; set; } + public string mobile { get; set; } + public string unionid { get; set; } + public int? ch { get; set; } + public string? type { get; set; } + public DateTime ctime { get; set; } + public DateTime utime { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/StandardProduct.cs b/code/Zxd.Entity/Zxd/StandardProduct.cs new file mode 100644 index 0000000..0d73656 --- /dev/null +++ b/code/Zxd.Entity/Zxd/StandardProduct.cs @@ -0,0 +1,34 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("t_standard_product")] + public class StandardProduct + { + public StandardProduct() + { + } + + [Key] + public int Id { get; set; } + + [Column("standard_type")] + public StandardType StandardType { get; set; } + + public int Way { get; set; } + + [Column("product_code")] + public string? ProductCode { get; set; } + + [Column("product_package_code")] + public string? ProductPackageCode { get; set; } + + [Column("create_time")] + public DateTime CreateTime { get; set; } + + [Column("update_time")] + public DateTime? UpdateTime { get; set; } + + public virtual List? FinishedProducts { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/TableField.cs b/code/Zxd.Entity/Zxd/TableField.cs new file mode 100644 index 0000000..aca9389 --- /dev/null +++ b/code/Zxd.Entity/Zxd/TableField.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("t_table_field")] + public class TableField + { + [Key] + public int Id { get; set; } + + public string? Module { get; set; } + + public string? Field { get; set; } + + public string? Type { get; set; } + + public string? Title { get; set; } + + public int? Width { get; set; } + + public string? Fixed { get; set; } + + public string? Templet { get; set; } + + public bool? Sort { get; set; } + + [Column("create_time")] + public DateTime? CreateTime { get; set; } + + public bool? Hide { get; set; } + + public int Order { get; set; } + + public bool? Checkbox { get; set; } + + public ICollection? FieldSettings { get; set; } + } +} diff --git a/code/Zxd.Entity/Zxd/WW_EXTUSER_RESID.cs b/code/Zxd.Entity/Zxd/WW_EXTUSER_RESID.cs new file mode 100644 index 0000000..2d43f46 --- /dev/null +++ b/code/Zxd.Entity/Zxd/WW_EXTUSER_RESID.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("WW_EXTUSER_RESID")] + public class WW_EXTUSER_RESID + { + [Key] + public string? Resid { get; set; } + + [Key] + public string? Userid { get; set; } + + public DateTime? Ctime { get; set; } + + [Key] + public string? Deptcode { get; set; } + + public int? Putnum { get; set; } + } + + public class ExUserModel + { + public string? Resid { get; set; } + + public string? Userid { get; set; } + public string? Deptcode { get; set; } + public DateTime? Ctime { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/WX_EMPOWER_LOG.cs b/code/Zxd.Entity/Zxd/WX_EMPOWER_LOG.cs new file mode 100644 index 0000000..182ab60 --- /dev/null +++ b/code/Zxd.Entity/Zxd/WX_EMPOWER_LOG.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("wx_empower_log")] + public class WX_EMPOWER_LOG + { + [Key] + public int id { get; set; } + public string to_by_resid { get; set; } + public int from_by_eid { get; set; } + public int to_by_eid { get; set; } + public int type { get; set; } + public DateTime created_time { get; set; } + public int duration { get; set; } + public string? product_name { get; set; } + public int product_id { get; set; } + public string order_id { get; set; } + public string softusername { get; set;} + public string appid { get; set;} + } +} diff --git a/code/Zxd.Entity/Zxd/WX_SZZYORDER.cs b/code/Zxd.Entity/Zxd/WX_SZZYORDER.cs new file mode 100644 index 0000000..e90e1f7 --- /dev/null +++ b/code/Zxd.Entity/Zxd/WX_SZZYORDER.cs @@ -0,0 +1,279 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Zxd.Entity.Zxd +{ + [Table("WX_SZZYORDER")] + public partial class WX_SZZYORDER + { + [Key] + public int ORDERID { get; set; } + + [StringLength(50)] + public string? EMPLOYEEID { get; set; } + + [StringLength(50)] + public string? PASSWORD { get; set; } + + [StringLength(100)] + public string? USERID { get; set; } + + public int? PRODUCTID { get; set; } + + [StringLength(50)] + public string? PRODUCTNAME { get; set; } + + public int SUBPRODUCTID { get; set; } + + [StringLength(50)] + public string? SUBPRODUCTNAME { get; set; } + + public int? ORDERTYPE { get; set; } + + [StringLength(500)] + public string? UPGRADEORDERIDS { get; set; } + + public int? TOTALUPGRADEVALUE { get; set; } + + public decimal? NEEDPAY { get; set; } + + public int? OPENORDER { get; set; } + + public long? SZZYORDERID { get; set; } + + /// + /// 订单状态:新订单180、已支付200、已开通220、已停用/已退款90、已过期80、已取消70,去掉"已支付200、暂缓开通210"状态 + /// + [StringLength(100)] + public string? ORDERSTATUS { get; set; } + + public DateTime? CTIME { get; set; } + + public int? RETURNNEEDPAY { get; set; } + + [StringLength(50)] + public string? CONTRACTCODE { get; set; } + + public int? RET { get; set; } + public int? RETP { get; set; } + + [StringLength(250)] + public string? MSG { get; set; } + + [StringLength(1000)] + public string? RETURNDETAIL { get; set; } + + public int? INNERUSERID { get; set; } + + public DateTime? OTIME { get; set; } + public DateTime? ENDTIME { get; set; } + + [StringLength(18)] + public string? RESID { get; set; } + + public string? UMID { get; set; } + + public int? REQUESTSTATUS { get; set; } + + public int? ISFINANCEPAY { get; set; } + + public DateTime? FINACEPAYDATE { get; set; } + + [StringLength(2000)] + public string? REMARK { get; set; } + + public decimal? FINALPAY { get; set; } + + /// + /// 订单原价 + /// + public decimal? ORIGINPAY { get; set; } + + /// + /// 剩余金额 + /// + public decimal? BALANCEPAY { get; set; } + + [StringLength(50)] + public string? ORDERSTATUSNAME { get; set; } + + public DateTime? OPERATETIME { get; set; } + + /// + /// 订单暂停结束时间 + /// + [StringLength(50)] + public string? STIME { get; set; } + + /// + /// 订单暂停结束时间 + /// + [StringLength(50)] + public string? ETIME { get; set; } + + /// + /// 订单暂停权限备注说明 + /// + [StringLength(2000)] + public string? SUSPENDCOMMENT { get; set; } + + public DateTime? UPDATEORDERTIME { get; set; } + + public int? ISOPEN { get; set; } + + public int? TEAMSERVE { get; set; } + + [StringLength(200)] + public string? FCTEXT { get; set; } + + [StringLength(200)] + public string? CUSTOMERUSERNAME { get; set; } + + public decimal? ARRIVALPAY { get; set; } + + public DateTime? ARRIVALTIME { get; set; } + + [StringLength(20)] + public string? SOURCE { get; set; } + + [StringLength(30)] + public string? CNAME { get; set; } + + public int? OPENDAYS { get; set; } + + [StringLength(2000)] + public string? CUSTOMERCLASSIFY { get; set; } + + public int? SALEDEPTID { get; set; } + + [StringLength(100)] + public string? SOFTUSERNAME { get; set; } + + [StringLength(100)] + public string? APPUSERNAME { get; set; } + + //[StringLength(50)] + public int? CHANNEL { get; set; } + + public int? BOOKNUM { get; set; } + + [StringLength(50)] + public string? OPENUSER { get; set; } + + /// + /// 是否支付,0:未支付,1:已经支付 + /// + public int ISPAYED { get; set; } + + /// + /// 支付类型。1:支付宝,2:财富通,3:银行转账,4:网银支付,5:微信支付,6:支付宝银联,11:苹果支付,12:华为支付 + /// + public int PAYTYPE { get; set; } + + public string? PRODUCTCODE { get; set; } + + public string? BIGPRODUCTCODE { get; set; } + + public int RISKCTRLSTATUS { get; set; } + + public string? companycode { get; set; } + + /// + /// 合同状态 + /// + public int contractstatus { get; set; } + + /// + /// 合同签订时间 + /// + public DateTime? contractctime { get; set; } + + /// + /// 是否开通企业微信(0:未开通,1:已开通) + /// + public int? qywxstatus { get; set; } + + /// + /// 开通企业微信时间 + /// + public DateTime? qywxopendate { get; set; } + + public string? activeproductcode { get; set; } + public string? activeproductext { get; set; } + public int? ISTEST { get; set; } + + public int? hashgrecord { get; set; } + public string? idcard { get; set; } + + public string? outorderno { get; set; } + public int? giftdays { get; set; } + public string? rejectremark { get; set; } + + public int? giftdays2 { get; set; } + + [NotMapped] + public string? mb { get; set; } //手机号,线上订单推送到线下需要 + + public string? external_userid { get; set; } + public string? wework_remoteid { get; set; } + + public int? eid { get; set; } + public int? SettleType { get; set; } + + public string? fujian { get; set; } + public string? wXShopOrderNo { get; set; } + public string? deptcode { get; set; } + + /// + /// 预计开通时间 + /// + public DateTime? estimateotime { get; set; } + + /// + /// 回访开始时间 + /// + public string? ai_hgrecord_stime { get; set; } + + /// + /// 回访结束时间 + /// + public string? ai_hgrecord_etime { get; set; } + + /// + /// 智能外呼状态 + /// + public int? ai_hgrecord_status { get; set; } + + /// + /// 智能外呼状态名称 + /// + public string? ai_hgrecord_statusname { get; set; } + + /// + /// 是否有外呼录音 + /// + public int? hasaiaudio { get; set; } + + public int? adequacy { get; set; } + + /// + /// 事业部id + /// + [Column("deptid")] + public int? Deptid { get; set; } + + /// + /// 事业部id + /// + [Column("deptname")] + public string? DeptName { get; set; } + + /// + /// 群id + /// + [Column("groupid")] + public int? GroupId { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/WxCanopenorder.cs b/code/Zxd.Entity/Zxd/WxCanopenorder.cs new file mode 100644 index 0000000..5caf5c8 --- /dev/null +++ b/code/Zxd.Entity/Zxd/WxCanopenorder.cs @@ -0,0 +1,12 @@ +namespace Zxd.Entity.Zxd; + +[Table("wx_canopenorder")] +public class WxCanopenorder +{ + [Key] + public string? Username { get; set; } + + public DateTime? Ctime { get; set; } + + public int? Status { get; set; } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/WxOrderActive.cs b/code/Zxd.Entity/Zxd/WxOrderActive.cs new file mode 100644 index 0000000..508a5a8 --- /dev/null +++ b/code/Zxd.Entity/Zxd/WxOrderActive.cs @@ -0,0 +1,35 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("WX_OrderActive")] + public class WxOrderActive + { + public WxOrderActive() + { + } + [Key] + public int Id { get; set; } + public string? ProductCode { get; set; } + public DateTime StartTime { get; set; } + public DateTime? EndTime { get; set; } + public string? ActiveCode { get; set; } + public int ActiveType { get; set; } + public string? CompanyCode { get; set; } + public int? MinCount { get; set; } + public int DonateDay { get; set; } + public int ProductType { get; set; } + public string? ProductName { get; set; } + + public int ProductId { get; set; } + + /// + /// 是否跟随订单赠送,1:用订单表的giftdays字段作为赠送时长,0:用本表的donateday字段作为赠送时长 + /// + public int IsFollowOrder { get; set; } + public string? Giftype { get; set; } + public string? Activename { get; set; } + public int? Isdelete { get; set; } + public int? Deptid { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/WxSzzyProduct.cs b/code/Zxd.Entity/Zxd/WxSzzyProduct.cs new file mode 100644 index 0000000..c3997d4 --- /dev/null +++ b/code/Zxd.Entity/Zxd/WxSzzyProduct.cs @@ -0,0 +1,40 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("WX_SZZYPRODUCT")] + public class WxSzzyProduct + { + public WxSzzyProduct() + { + } + + [Key] + [Column("productid")] + public int ProductId { get; set; } + + [Column("productname")] + public string? ProductName { get; set; } + + [Column("productdesc")] + public string? ProductDesc { get; set; } + + [Column("productbriefdesc")] + public string? ProductBriefDesc { get; set; } + + [Column("isvalid")] + public int? IsValid { get; set; } + + [Column("productguide")] + public string? ProductGuide { get; set; } + + [Column("productcode")] + public string? ProductCode { get; set; } + + public int Parentid { get; set; } + + public int Sort { get; set; } + + public int Level { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/WxSzzySubProductGift.cs b/code/Zxd.Entity/Zxd/WxSzzySubProductGift.cs new file mode 100644 index 0000000..c536d9d --- /dev/null +++ b/code/Zxd.Entity/Zxd/WxSzzySubProductGift.cs @@ -0,0 +1,29 @@ +using System; +namespace Zxd.Entity.Zxd +{ + [Table("WX_SZZYSUBPRODUCT_GIFT")] + public class WxSzzySubProductGift + { + public WxSzzySubProductGift() + { + } + + public int Id { get; set; } + public int SubProductId { get; set; } + public string? SubProductName { get; set; } + public int GiftDays { get; set; } + public string? GiftDaysName { get; set; } + public int Sort { get; set; } + public int IsDefault { get; set; } + public int Type { get; set; } + public string? GiftName { get; set; } + public int Channel { get; set; } + /// + /// 外键,赠送ID + /// + public int Activeid { get; set; } + + public int? Deptid { get; set; } + } +} + diff --git a/code/Zxd.Entity/Zxd/WxSzzySubproduct.cs b/code/Zxd.Entity/Zxd/WxSzzySubproduct.cs new file mode 100644 index 0000000..155931e --- /dev/null +++ b/code/Zxd.Entity/Zxd/WxSzzySubproduct.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("WX_SZZYSUBPRODUCT")] + public class WxSzzySubproduct + { + [Key] + public int subproductid { get; set; } + + public string? subproductname { get; set; } + public string? productcode { get; set; } + public decimal? price { get; set; } + public int? isEmpower { get; set; } + public int? producttype { get; set; } + public int? rightperiod { get; set; } + public int? mid { get; set; } + public int? productlevel { get; set; } + public int? productinvesttype { get; set; } + public int? productinvesttime { get; set; } + public string? callbacklink { get; set; } + public string? buylink { get; set; } + public int? isonlinebuy { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/Zxd/WxSzzySubproductCh.cs b/code/Zxd.Entity/Zxd/WxSzzySubproductCh.cs new file mode 100644 index 0000000..ef09bae --- /dev/null +++ b/code/Zxd.Entity/Zxd/WxSzzySubproductCh.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.Zxd +{ + [Table("WX_SZZYSUBPRODUCT_CH")] + public class WxSzzySubproductCh + { + [Key] + public int id { get; set; } + + public int subproductid { get; set; } + public string? companycode { get; set; } + public string? subproductname { get; set; } + public int? isEmpower { get; set; } + public int? isValid { get; set; } + public int? channel { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.Entity/dim/CustomerEmployee.cs b/code/Zxd.Entity/dim/CustomerEmployee.cs new file mode 100644 index 0000000..983a461 --- /dev/null +++ b/code/Zxd.Entity/dim/CustomerEmployee.cs @@ -0,0 +1,182 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.Entity.dim +{ + [Table("customer_employee")] + public class CustomerEmployee + { + public CustomerEmployee() + { + } + + public UInt32? id { get; set; } + + [Column("customerid")] + public UInt32? customerid { get; set; } + + [Column("eid")] + public int? eid { get; set; } + + [Column("deptid")] + public int? deptid { get; set; } + + [Column("dept_name")] + public string? deptname { get; set; } + + [Column("c_appid")] + public string? appid { get; set; } + + [Column("c_appuserid")] + public string? appuserid { get; set; } + + [Column("c_app_name")] + public string? appname { get; set; } + + /// + /// 应用类型 + /// + [Column("c_app_type")] + public int? apptype { get; set; } + + /// + /// 用户ID + /// + [Column("c_uid")] + public int? uid { get; set; } + + /// + /// 用户资源ID + /// + [Column("resid")] + public string? resid { get; set; } + + /// + /// 用户联合ID + /// + [Column("unionid")] + public string? unionid { get; set; } + + /// + /// 用户类型 0:员工 1:用户 + /// + [Column("user_type")] + public SByte? usertype { get; set; } + + /// + /// 用户昵称 + /// + [Column("nickname")] + public string? nickname { get; set; } + + /// + /// 用户头像 + /// + [Column("headimgurl")] + public string? headimgurl { get; set; } + + /// + ///用户姓名 + /// + [Column("username")] + public string? username { get; set; } + + /// + /// 来源活动类型 + /// + [Column("scenetype")] + public UInt16? scenetype { get; set; } + + /// + /// 来源活动类型名称 + /// + [Column("scenetypename")] + public string? scenetypename { get; set; } + + /// + /// 来源活动值 + /// + [Column("scene")] + public string? scene { get; set; } + + /// + /// 来源活动名称 + /// + [Column("scenename")] + public string? scenename { get; set; } + + /// + /// 用户类型 0:员工 1:用户 + /// + [Column("employee_id")] + public int? employeeid { get; set; } + + /// + /// 员工名称 + /// + [Column("employee_name")] + public string? employeename { get; set; } + + /// + /// 员工状态 + /// + [Column("employee_status")] + public UInt32? employee_status { get; set; } + + /// + /// 员工分组ID + /// + [Column("groupid")] + public int? groupid { get; set; } + + /// + /// 有效事实关系 0:无效关系,1:有效关系 + /// + [Column("status")] + public Byte? status { get; set; } + + /// + /// 业务部小组名称 + /// + [Column("group_name")] + public string? group_name { get; set; } + + /// + /// + /// + /// + [Column("orgid")] + public int? orgid { get; set; } + + /// + /// 组织部门ID + /// + /// + [Column("org_name")] + public string? orgname { get; set; } + + /// + /// 组织部门名称 + /// + /// + [Column("did")] + public int? did { get; set; } + + /// + /// 员工业务部门名称 + /// + /// + [Column("dname")] + public string? dname { get; set; } + + /// + /// 用户类型 0:员工 1:用户 + /// + [Column("create_time")] + public DateTime? createtime { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/CompanyBaseConfDbContext.cs b/code/Zxd.EntityFramework/CompanyBaseConfDbContext.cs new file mode 100644 index 0000000..97e940c --- /dev/null +++ b/code/Zxd.EntityFramework/CompanyBaseConfDbContext.cs @@ -0,0 +1,40 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.EntityFramework +{ + public class CompanyBaseConfDbContext : DbContext + { + public CompanyBaseConfDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + base.OnConfiguring(optionsBuilder); + } + + public DbSet DepartmentCrmconf { get; set; } + public DbSet EmployeeDepartmentDetail { get; set; } + public DbSet EmployeeDepartment { get; set; } + public DbSet Application { get; set; } + public DbSet ApplicationDepartment { get; set; } + + public DbSet Employee { get; set; } + + public DbSet Department { get; set; } + } +} diff --git a/code/Zxd.EntityFramework/CrmCloudDbContext.cs b/code/Zxd.EntityFramework/CrmCloudDbContext.cs new file mode 100644 index 0000000..778dc75 --- /dev/null +++ b/code/Zxd.EntityFramework/CrmCloudDbContext.cs @@ -0,0 +1,47 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Action; + +namespace Zxd.EntityFramework +{ + public class CrmCloudDbContext : DbContext + { + public CrmCloudDbContext(DbContextOptions options) : base(options) + + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + + public DbSet EmployeeDepartmentDetail { get; set; } + public DbSet EmployeeDepartment { get; set; } + + public DbSet CustomerBehaviorLog { get; set; } + public DbSet EmployeeTodoitem { get; set; } + + public DbSet EmployeeDepartmentFull { get; set; } + public DbSet Department { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/CrmDbContext.cs b/code/Zxd.EntityFramework/CrmDbContext.cs new file mode 100644 index 0000000..9f16478 --- /dev/null +++ b/code/Zxd.EntityFramework/CrmDbContext.cs @@ -0,0 +1,73 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Zxd.EntityFramework +{ + public class CrmDbContext : DbContext + { + public CrmDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasOne(x => x.Module) + .WithMany(x => x.Product) + .HasForeignKey(x => x.Moduleid); + + modelBuilder.Entity() + .HasOne(x => x.ProductGroup) + .WithMany(x => x.Product) + .HasForeignKey(x => x.Groupid); + + modelBuilder.Entity() + .HasOne(x => x.ProductGroup) + .WithMany(x => x.ProductPackage) + .HasForeignKey(x => x.Groupid); + + modelBuilder.Entity() + .HasOne(x => x.Product) + .WithMany(x => x.ProductTeachers) + .HasPrincipalKey(x => x.Id) + .HasForeignKey(x => x.ProductId); + + modelBuilder.Entity() + .HasOne(x => x.Teacher) + .WithMany(x => x.ProductTeachers) + .HasPrincipalKey(x => x.Code) + .HasForeignKey(x => x.TeacherCode); + modelBuilder.Entity().HasKey(c => new { c.moduleid, c.orderid }); + + base.OnModelCreating(modelBuilder); + } + + public DbSet Product { get; set; } + + public DbSet ProductPackage { get; set; } + + public DbSet ProductGroup { get; set; } + + public DbSet ProductTeacher { get; set; } + + public DbSet Teacher { get; set; } + + public DbSet Module { get; set; } + + public DbSet UserModule { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/DgActionsDbContext.cs b/code/Zxd.EntityFramework/DgActionsDbContext.cs new file mode 100644 index 0000000..d9ea40d --- /dev/null +++ b/code/Zxd.EntityFramework/DgActionsDbContext.cs @@ -0,0 +1,32 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Zxd.EntityFramework +{ + public class DgActionsDbContext : DbContext + { + public DgActionsDbContext(DbContextOptions options) : base(options) + + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/DncmsDbContext.cs b/code/Zxd.EntityFramework/DncmsDbContext.cs new file mode 100644 index 0000000..bbaaaf7 --- /dev/null +++ b/code/Zxd.EntityFramework/DncmsDbContext.cs @@ -0,0 +1,55 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Zxd.EntityFramework +{ + public class DncmsDbContext : DbContext + { + public DncmsDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasNoKey(); + + modelBuilder.Entity().HasKey(c => new { c.Appid, c.Userid, c.Externaluserid }); + modelBuilder.Entity() + .HasOne(x => x.ResourceFlowConfig) + .WithMany(x => x.ResourceFlowConfigFrom) + .HasForeignKey(x => x.ConfigId); + modelBuilder.Entity() + .HasOne(x => x.ResourceFlowConfig) + .WithMany(x => x.ResourceFlowConfigTo) + .HasForeignKey(x => x.ConfigId); + modelBuilder.Entity() + .HasOne(x => x.ResourceFlowConfig) + .WithMany(x => x.ResourceFlowLog) + .HasForeignKey(x => x.ConfigId); + base.OnModelCreating(modelBuilder); + } + + public DbSet WeworkExternalUserTotal { get; set; } + public DbSet WeworkExternalUser { get; set; } + public DbSet ResourceFlowConfig { get; set; } + public DbSet ResourceFlowConfigFrom { get; set; } + + public DbSet ResourceFlowConfigTo { get; set; } + + public DbSet ResourceFlowDimission { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/DncmsbaseDbContext.cs b/code/Zxd.EntityFramework/DncmsbaseDbContext.cs new file mode 100644 index 0000000..d0dcd63 --- /dev/null +++ b/code/Zxd.EntityFramework/DncmsbaseDbContext.cs @@ -0,0 +1,60 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Zxd.EntityFramework +{ + public class DncmsbaseDbContext : DbContext + { + public DncmsbaseDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasOne(b => b.Deptment) + .WithMany(x => x.DeptmentCampainIds) + .HasForeignKey(b => b.DeptId); + + modelBuilder.Entity().HasKey(c => new { c.Appid, c.Userid, c.Externaluserid }); + modelBuilder.Entity().HasKey(c => new { c.eid, c.salegroupid }); + base.OnModelCreating(modelBuilder); + } + + public DbSet Deptment { get; set; } + + public DbSet ResResidWeworkEventLog { get; set; } + public DbSet ResResidWeworkUser { get; set; } + public DbSet ResResidWeworkUserLog { get; set; } + public DbSet DeptmentCampainId { get; set; } + public DbSet WeworkExternalUser { get; set; } + public DbSet ResCutomerPassTime { get; set; } + public DbSet ResourceProtectInfo { get; set; } + + public DbSet Wx_Szzyorder_log { get; set; } + + public DbSet resourcetag { get; set; } + + public DbSet weworkuser2eid { get; set; } + public DbSet EmployeeDepartmentDetail { get; set; } + public DbSet EmployeeDepartmentFull { get; set; } + public DbSet Department { get; set; } + public DbSet AssignRules { get; set; } + public DbSet Assign { get; set; } + public DbSet WeworkAgent { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/HgActionDbContext.cs b/code/Zxd.EntityFramework/HgActionDbContext.cs new file mode 100644 index 0000000..024655f --- /dev/null +++ b/code/Zxd.EntityFramework/HgActionDbContext.cs @@ -0,0 +1,38 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Zxd.Entity.Action; + +namespace Zxd.EntityFramework +{ + public class HgActionDbContext : DbContext + { + public HgActionDbContext(DbContextOptions options) : base(options) + + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/SSODbContext.cs b/code/Zxd.EntityFramework/SSODbContext.cs new file mode 100644 index 0000000..b71071f --- /dev/null +++ b/code/Zxd.EntityFramework/SSODbContext.cs @@ -0,0 +1,38 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; +using Zxd.Entity.SSO; + +namespace Zxd.EntityFramework +{ + public class SSODbContext : DbContext + { + public SSODbContext(DbContextOptions options) : base(options) + + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } + + public DbSet Department { get; set; } + public DbSet Employee { get; set; } + public DbSet EmployeeDepartment { get; set; } + public DbSet DepartmentCrmConf { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/UserCenterDbContext.cs b/code/Zxd.EntityFramework/UserCenterDbContext.cs new file mode 100644 index 0000000..419f3e4 --- /dev/null +++ b/code/Zxd.EntityFramework/UserCenterDbContext.cs @@ -0,0 +1,34 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; + +namespace Zxd.EntityFramework +{ + public class UserCenterDbContext : DbContext + { + public UserCenterDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + + base.OnModelCreating(modelBuilder); + } + + public DbSet UserInfo { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.EntityFramework/Zxd.EntityFramework.csproj b/code/Zxd.EntityFramework/Zxd.EntityFramework.csproj new file mode 100644 index 0000000..b6e282c --- /dev/null +++ b/code/Zxd.EntityFramework/Zxd.EntityFramework.csproj @@ -0,0 +1,26 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + + + + diff --git a/code/Zxd.EntityFramework/ZxdDbContext.cs b/code/Zxd.EntityFramework/ZxdDbContext.cs new file mode 100644 index 0000000..eb22cf5 --- /dev/null +++ b/code/Zxd.EntityFramework/ZxdDbContext.cs @@ -0,0 +1,163 @@ +using DG.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Logging; +using Zxd.Entity.SSO; +using Zxd.Entity.Zxd; +using Zxd.Entity.Zxd.Order; +using Zxd.Entity.Zxd.QiweiOnlePay; + +namespace Zxd.EntityFramework +{ + public class ZxdDbContext : DbContext + { + public ZxdDbContext(DbContextOptions options) : base(options) + + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + { + var loggerFactory = new LoggerFactory(); + loggerFactory.AddProvider(new EFLoggerProvider()); + optionsBuilder.UseLoggerFactory(loggerFactory); + } + optionsBuilder.ConfigureWarnings(b => b.Ignore(CoreEventId.ContextInitialized)); + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasOne(b => b.BaseProduct) + .WithMany(x => x.BaseProductPackageRelations) + .HasForeignKey(b => b.ProductCode) + .HasPrincipalKey(b => b.Code); + + modelBuilder.Entity() + .HasOne(b => b.BaseProductPackage) + .WithMany(x => x.BaseProductPackageRelations) + .HasForeignKey(b => b.PackageCode) + .HasPrincipalKey(b => b.Code); + + modelBuilder.Entity() + .HasOne(b => b.StandardProduct) + .WithMany(x => x.FinishedProducts) + .HasForeignKey(b => b.StandardProductId); + + modelBuilder.Entity() + .HasKey(x => new { x.Resid, x.Userid }); + + modelBuilder.Entity() + .HasOne(b => b.EarlyWarningTemplate) + .WithMany(x => x.EarlyWarningSettings) + .HasForeignKey(b => b.TemplateId); + + modelBuilder.Entity() + .HasOne(b => b.Meeting) + .WithMany(x => x.MeetingParticipants) + .HasForeignKey(x => x.MeetingId); + + modelBuilder.Entity() + .HasOne(b => b.Meeting) + .WithMany(x => x.MeetingAccessories) + .HasForeignKey(x => x.MeetingId); + + modelBuilder.Entity() + .HasOne(b => b.TableField) + .WithMany(x => x.FieldSettings) + .HasForeignKey(b => b.FieldId); + modelBuilder.Entity().HasKey(t => new { t.Resid, t.Userid, t.Deptcode }); + + modelBuilder.Entity().HasKey(x => new { x.ActId, x.DeptId }); + + modelBuilder.Entity() + .HasOne(b => b.QiWeiActivity) + .WithMany(x => x.QiWeiActivityDept) + .HasForeignKey(b => b.ActId); + modelBuilder.Entity() + .HasOne(b => b.QiWeiActivity) + .WithMany(x => x.QWActivityProduct) + .HasForeignKey(b => b.ActId); + + base.OnModelCreating(modelBuilder); + } + + public DbSet Res_Tag { get; set; } + public DbSet BAS_INNERUSER { get; set; } + public DbSet BAS_INNERUSERSALT { get; set; } + public DbSet WX_SZZYORDER { get; set; } + + public DbSet Bas_CompanyChannel { get; set; } + public DbSet BAS_PARAMETER { get; set; } + public DbSet RES_APPLY { get; set; } + public DbSet RES_RESOURCEMOBILE { get; set; } + public DbSet RES_CUSTOMERUSER { get; set; } + public DbSet RES_CUSTOMER { get; set; } + public DbSet RES_MOBILE_MD5 { get; set; } + public DbSet SMS_MESSAGE { get; set; } + public DbSet SMS_MSGSUBTYPE { get; set; } + public DbSet SMS_MSGTYPE_CLIENT { get; set; } + public DbSet SOFT_USER { get; set; } + public DbSet Soft_User_CH { get; set; } + public DbSet Soft_Userinfo_Sub { get; set; } + + public DbSet WW_EXTUSER_RESID { get; set; } + public DbSet BaseProduct { get; set; } + public DbSet BaseProductPackage { get; set; } + public DbSet BaseProductPackageRelation { get; set; } + public DbSet CMS_QIWEI_POSTLOG { get; set; } + public DbSet StandardProduct { get; set; } + public DbSet FinishedProduct { get; set; } + public DbSet WxSzzyProduct { get; set; } + public DbSet BasCompanyChannel { get; set; } + public DbSet WxSzzySubProductGift { get; set; } + public DbSet WxOrderActive { get; set; } + + public DbSet EarlyWaning { get; set; } + + public DbSet EarlyWaningLog { get; set; } + + public DbSet EarlyWaningSetting { get; set; } + + public DbSet EarlyWarningTemplate { get; set; } + public DbSet EarlyWarningUser { get; set; } + + public DbSet WX_SZZYORDER_BIND { get; set; } + public DbSet Wx_SzzyOrder_HandGift { get; set; } + + public DbSet FieldSetting { get; set; } + + public DbSet TableField { get; set; } + + /*public DbSet FieldSetting { get; set; } + + public DbSet TableField { get; set; }*/ + + public DbSet WX_SZZYORDERDEPOSIT { get; set; } + public DbSet WX_SzzyOrderRefund { get; set; } + + public DbSet L2SOFTORDER { get; set; } + public DbSet Employee { get; set; } + public DbSet WX_EMPOWER_LOG { get; set; } + public DbSet EMPLOYEE_PHONE_BIND { get; set; } + public DbSet EMPLOYEE_PHONE_BIND_LOG { get; set; } + public DbSet EMPLOYEE_SOFT_LOG { get; set; } + public DbSet EMPLOYEE_SOFT_DICT { get; set; } + + public DbSet WX_SZZYSUBPRODUCT { get; set; } + public DbSet WxSzzySubproductCh { get; set; } + public DbSet EmployeeDepartmentDetail { get; set; } + public DbSet EmployeeDepartmentFull { get; set; } + public DbSet Department { get; set; } + + public DbSet ScreenRecord { get; set; } + + public DbSet WxCanopenorder { get; set; } + public DbSet QiWeiActivity { get; set; } + public DbSet QiWeiActivityDept { get; set; } + public DbSet QWActivityProduct { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.SqlSugar/InitConfiguration.cs b/code/Zxd.SqlSugar/InitConfiguration.cs new file mode 100644 index 0000000..681c0d7 --- /dev/null +++ b/code/Zxd.SqlSugar/InitConfiguration.cs @@ -0,0 +1,66 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.Json; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Zxd.SqlSugar +{ + public class InitConfiguration + { + private static IConfiguration Configuration { get; set; } + + static InitConfiguration() + { + var path = "appsettings.json"; + var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + if (!string.IsNullOrEmpty(env) && env != "Development") + { + path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json"; + } + Configuration = new ConfigurationBuilder() + + .Add(new JsonConfigurationSource { Path = path, Optional = false, ReloadOnChange = true }) + .Build(); + } + + public InitConfiguration(IConfiguration configuration) + { + Configuration = configuration; + } + + /// + /// 封装要操作的字符 + /// + /// 节点配置 + /// + public static string app(params string[] sections) + { + try + { + if (sections.Any()) + { + return Configuration[string.Join(":", sections)]; + } + } + catch (Exception) + { + } + + return ""; + } + + public static string GetConnectionString(string key) + { + return Configuration.GetConnectionString(key); + } + + public static IConfigurationSection GetSection(string key) + { + return Configuration.GetSection(key); + } + } +} \ No newline at end of file diff --git a/code/Zxd.SqlSugar/InitDB.cs b/code/Zxd.SqlSugar/InitDB.cs new file mode 100644 index 0000000..72f91fa --- /dev/null +++ b/code/Zxd.SqlSugar/InitDB.cs @@ -0,0 +1,35 @@ +using SqlSugar; + +namespace Zxd.SqlSugar +{ + public static class InitDB + { + public static SqlSugarScope CrmdwmDb = new SqlSugarScope(new ConnectionConfig() + { + ConnectionString = InitConfiguration.GetConnectionString("Crmdwm"), + DbType = DbType.ClickHouse, + IsAutoCloseConnection = true + }, + db => + { + db.Aop.OnLogExecuted = (sql, pars) => + { + //Log.Information(sql, pars); + }; + }); + + public static SqlSugarScope dimDb = new SqlSugarScope(new ConnectionConfig() + { + ConnectionString = InitConfiguration.GetConnectionString("dim"), + DbType = DbType.ClickHouse, + IsAutoCloseConnection = true + }, + db => + { + db.Aop.OnLogExecuted = (sql, pars) => + { + //Log.Information(sql, pars); + }; + }); + } +} \ No newline at end of file diff --git a/code/Zxd.SqlSugar/Zxd - Backup.SqlSugar.csproj b/code/Zxd.SqlSugar/Zxd - Backup.SqlSugar.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/code/Zxd.SqlSugar/Zxd - Backup.SqlSugar.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/code/Zxd.SqlSugar/Zxd.SqlSugar.csproj b/code/Zxd.SqlSugar/Zxd.SqlSugar.csproj new file mode 100644 index 0000000..c72c564 --- /dev/null +++ b/code/Zxd.SqlSugar/Zxd.SqlSugar.csproj @@ -0,0 +1,21 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + diff --git a/code/Zxd.WebApi/.config/dotnet-tools.json b/code/Zxd.WebApi/.config/dotnet-tools.json new file mode 100644 index 0000000..b8c6c1f --- /dev/null +++ b/code/Zxd.WebApi/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "6.0.9", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/AssignUserDomain.cs b/code/Zxd.WebApi/AssignUserDomain.cs new file mode 100644 index 0000000..69a85e7 --- /dev/null +++ b/code/Zxd.WebApi/AssignUserDomain.cs @@ -0,0 +1,75 @@ +using MySqlConnector; +using System.Diagnostics; +using Zxd.WebApi.Dto; +using Zxd.WebApi.Impl; + +namespace Zxd.WebApi +{ + public class AssignUserDomain : IAssignUserDomain + { + private readonly IBaseRepository _cmsrepository; + private readonly IDeptmentDomain _deptmentDomain; + + public AssignUserDomain(IBaseRepository cmsrepository, IDeptmentDomain deptmentDomain) + { + _cmsrepository = cmsrepository; + _deptmentDomain = deptmentDomain; + } + + public async Task> GetAssignModels(string resId) + { + List res = new List(); + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + var sql = @" SELECT distinct a.deptid FROM AssignUser2eid AS a join ( + select a.appid,a.appuserid from usercenter a + left join usercenter b on a.customerid = b.customerid + WHERE b.resid = @resId + ) AS b ON a.appid=b.appid AND a.appuserid=b.appuserid "; + MySqlParameter[] param = new MySqlParameter[] { + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=resId,ParameterName="resId"}, + }; + var deptIdsList = await _cmsrepository.ExecuteSqlToListAsync(sql, param); + stopWatch.Stop(); + Log.Information($"GetAssignModels:{stopWatch.ElapsedMilliseconds}ms 【{deptIdsList.ToJson()}】"); + foreach (var dept in deptIdsList) + { + AssignModel model = new AssignModel + { + DeptId = dept.deptid + }; + res.Add(model); + } + return res; + } + + public async Task> GetAssignDetail(string resId) + { + List res = new List(); + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + var sql = @" SELECT distinct a.deptid,a.eid,a.utime FROM AssignUser2eid AS a join ( + select a.appid,a.appuserid from usercenter a + left join usercenter b on a.customerid = b.customerid + WHERE b.resid = @resId + ) AS b ON a.appid=b.appid AND a.appuserid=b.appuserid"; + MySqlParameter[] param = new MySqlParameter[] { + new MySqlParameter(){ DbType=System.Data.DbType.String,Value=resId,ParameterName="resId"}, + }; + var deptIdsList = await _cmsrepository.ExecuteSqlToListAsync(sql, param); + stopWatch.Stop(); + Log.Information($"GetAssignDetail:{stopWatch.ElapsedMilliseconds}ms 【{deptIdsList.ToJson()}】"); + deptIdsList = deptIdsList.OrderByDescending(n => n.Utime).ToList(); + foreach (var dept in deptIdsList) + { + DbAssignUserEidModel model = new DbAssignUserEidModel + { + deptid = dept.deptid, + eid = dept.eid, + }; + res.Add(model); + } + return res; + } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Controllers/AssignUserController.cs b/code/Zxd.WebApi/Controllers/AssignUserController.cs new file mode 100644 index 0000000..e6935bc --- /dev/null +++ b/code/Zxd.WebApi/Controllers/AssignUserController.cs @@ -0,0 +1,28 @@ +using Zxd.WebApi.Dto; +using Zxd.WebApi.Impl; + +namespace Zxd.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class AssignUserController : BaseController + { + private readonly IAssignUserDomain _assginDomain; + + public AssignUserController(IAssignUserDomain assginDomain) + { + _assginDomain = assginDomain; + } + + [HttpGet("GetAssignModel")] + public async Task> GetAssignModels(string resid) + { + return await _assginDomain.GetAssignModels(resid); + } + + [HttpGet("GetAssignDetail")] + public async Task> GetAssignDetail(string resid) + { + return await _assginDomain.GetAssignDetail(resid); + } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Controllers/BaseController.cs b/code/Zxd.WebApi/Controllers/BaseController.cs new file mode 100644 index 0000000..c271618 --- /dev/null +++ b/code/Zxd.WebApi/Controllers/BaseController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Zxd.WebApi.Controllers +{ + [ApiController] + [Route("Api/[controller]")] + [Produces("application/json")] + public class BaseController : Controller + { + + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Controllers/DeptmentController.cs b/code/Zxd.WebApi/Controllers/DeptmentController.cs new file mode 100644 index 0000000..d34f674 --- /dev/null +++ b/code/Zxd.WebApi/Controllers/DeptmentController.cs @@ -0,0 +1,20 @@ +namespace Zxd.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class DeptmentController : BaseController + { + private readonly IDeptmentDomain _deptDomain; + + public DeptmentController(IDeptmentDomain deptDomain) + { + _deptDomain = deptDomain; + } + + [HttpGet("Depts")] + public async Task> GetDeptments() + { + Log.Information("ZXD查询Depts了"); + return await _deptDomain.GetDeptments(); + } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Controllers/ReSourceController.cs b/code/Zxd.WebApi/Controllers/ReSourceController.cs new file mode 100644 index 0000000..6a36cf2 --- /dev/null +++ b/code/Zxd.WebApi/Controllers/ReSourceController.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Mvc; +using Zxd.Domain.Dto.Resource; + +namespace Zxd.WebApi.Controllers +{ + [ApiSecurity] + public class ReSourceController : BaseController + { + private readonly IReSourceDomain _sourceDomain; + + public ReSourceController(IReSourceDomain sourceDomain) + { + _sourceDomain = sourceDomain; + } + + /// + /// 注册接口 + /// + /// + /// + [HttpPost("SyncUserReg")] + public async Task SyncUserReg([FromBody] SyncRegUserDto activeModel) + { + return await _sourceDomain.SyncRegUser(activeModel, Request.Headers["clientid"].ToString()); + } + + /// + /// 参加活动接口 + /// + /// + /// + /// + /// + [HttpPost("JoinActive")] + public async Task JoinActive([FromBody] JionActiveDto postData) + => await _sourceDomain.Join(postData, Request.Headers["clientid"].ToString()); + + /// + /// 资源分配接口 + /// + /// + /// + [HttpPost("ResAllocation")] + public async Task ResAllocation([FromBody] ResAllocationDto postData) + => await _sourceDomain.Allocation(postData, Request.Headers["clientid"].ToString()); + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Controllers/ScreenRecordController.cs b/code/Zxd.WebApi/Controllers/ScreenRecordController.cs new file mode 100644 index 0000000..59d0997 --- /dev/null +++ b/code/Zxd.WebApi/Controllers/ScreenRecordController.cs @@ -0,0 +1,47 @@ +using Zxd.Domain.Dto.Resource; + +namespace Zxd.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class ScreenRecordController : BaseController + { + private readonly IScreenRecordDomain _screenRecordDomain; + + public ScreenRecordController(IScreenRecordDomain screenRecordDomain) + { + _screenRecordDomain = screenRecordDomain; + } + + /// + /// 创建录屏记录接口 + /// + /// + /// + [HttpPost("Create")] + [ApiTimeSecurity] + public async Task ScreenRecord([FromBody] ScreenRecord postData) + => await _screenRecordDomain.ScreenRecord(postData); + + + /// + /// 录屏文件接收接口 + /// + /// + /// + [HttpPost("FileRecord")] + [ApiTimeSecurity] + public async Task FileRecord([FromBody] ScreenRecordFile postData) + => await _screenRecordDomain.FileRecord(postData); + + /// + /// 录屏数据列表接口 + /// + /// + /// + [HttpGet("Page")] + public async Task> GetScreenRecordList([FromQuery] ScreenRecordRequest postData) + { + return await _screenRecordDomain.GetScreenRecordList(postData); + } + } +} diff --git a/code/Zxd.WebApi/Controllers/SoftUserController.cs b/code/Zxd.WebApi/Controllers/SoftUserController.cs new file mode 100644 index 0000000..416fe3a --- /dev/null +++ b/code/Zxd.WebApi/Controllers/SoftUserController.cs @@ -0,0 +1,115 @@ +using Zxd.Domain.Dto.Resource; + +namespace Zxd.WebApi.Controllers +{ + [ApiSignatureFilterForbid] + public class SoftUserController : BaseController + { + private readonly IReSourceDomain _sourceDomain; + + public SoftUserController(IReSourceDomain sourceDomain) + { + _sourceDomain = sourceDomain; + } + + /// + /// 获取用户接口 + /// + /// + /// + [HttpPost("GetUserProtectInfo")] + public async Task> GetUserProtectInfo([FromBody] CheckUserDTO postData) + => await _sourceDomain.GetUserProtectInfo(postData); + + /// + /// 获取用户成交保护期接口(销售线索) + /// + /// + /// + [HttpPost("GetUserProtectInfoAuth")] + [ApiTimeSecurity] + public async Task> GetUserProtectInfoAuth([FromBody] CheckUserDTO postData) + { + Log.Warning($"appid_{postData.Appid}_appuserid_{postData.Appuserid}"); + return await _sourceDomain.GetUserProtectInfo(postData); + } + + /// + /// 获取用户是否可以成交 + /// + /// + /// + [HttpPost("GetUserCanOpenOrder")] + [ApiTimeSecurity] + public async Task GetUserCanOpenOrder([FromBody] CheckUserDTO dto) + { + return await _sourceDomain.GetUserCanOpenOrder(dto); + } + + /// + /// 根据客户id获取用户是否可以成交 + /// + /// + /// + [HttpGet("GetUserCanOpenOrderByResid")] + public async Task GetUserCanOpenOrderByResid(string? resid) + { + return await _sourceDomain.GetUserCanOpenOrderByResid(resid); + } + + /// + /// 初始化客户过期 + /// + /// + /// + [HttpGet("InitUserProtect")] + public async Task InitUserProtect(int type) + => await _sourceDomain.InitUserProtect(type); + + /// + /// 获取用户成交保护期接口 + /// + /// + /// + [HttpPost("GetSoftUserByResid")] + [ApiTimeSecurity] + public async Task> GetSoftUserByResid([FromBody] CheckResidDTO dto) + => await _sourceDomain.GetSoftUserByResid(dto.Resid); + + /// + /// 获取资源保护期接口 + /// + /// + /// + [HttpPost("GetResoucePassTime")] + [ApiTimeSecurity] + public async Task GetResoucePassTime([FromBody] CheckUserDTO dto) + { + Log.Warning($"appid_{dto.Appid}_appuserid_{dto.Appuserid}"); + return await _sourceDomain.GetResoucePassTimeBySql(dto); + } + + /// + /// 获取资源保护期接口 + /// + /// + /// + [HttpPost("GetResoucePassTime2")] + [ApiTimeSecurity] + public async Task GetResoucePassTime2([FromBody] CheckUserDTO dto) + => await _sourceDomain.GetResoucePassTime(dto); + + /// + /// 获取资源保护期接口(非加密测试后续删除) + /// + /// + /// + [HttpGet("GetResoucePassTimeTest")] + public async Task GetResoucePassTimeTest([FromQuery] CheckUserDTO dto) + => await _sourceDomain.GetResoucePassTimeBySql(dto); + + [HttpGet("GetSoftUserDetail")] + public async Task GetSoftUserPassTime([FromQuery] string username) + => await _sourceDomain.GetSoftUserDetail(username); + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Controllers/TestController.cs b/code/Zxd.WebApi/Controllers/TestController.cs new file mode 100644 index 0000000..93ace4c --- /dev/null +++ b/code/Zxd.WebApi/Controllers/TestController.cs @@ -0,0 +1,92 @@ +using Microsoft.AspNetCore.Mvc; +using Zxd.Domain.Dto.Resource; +using Zxd.Domain.Impl; + +namespace Zxd.WebApi.Controllers +{ + public class TestController : BaseController + { + private readonly IBasRoseDomain _freeOrdDomain; + + // 提供各种http请求方法 + private readonly IHttpClient _httpClient; + + public TestController(IBasRoseDomain freeOrdDomain, + IHttpClient httpClient) + { + _freeOrdDomain = freeOrdDomain; + _httpClient = httpClient; + } + + /// + /// 免费产品类型 + /// + /// + /// + /// + [HttpGet("test")] + [ApiSignatureFilterForbid] + public async Task GetFreeOrderPage() + { + try + { + await _freeOrdDomain.test(); + var ss = ""; + for (var i = 0; i <= 1; i++) + { + var ch = 7000; + if (i % 2 == 0) + { + ch = 7300; + } + var syncRegUserDto = new SyncRegUserDto + { + username = $"csd100878{i}", + password = "123qwe123", + mobile = $"1351102568{i}", + channel = ch, + curChannel = ch, + plat = "0", + ip = "192.168.91.238", + clientip = "192.168.91.238", + regDate = 1624430678384, + eid = "", + unionId = "", + refeid = $"10597{i}", + liveCode = "", + regSource = "soft_reg" + }; + + ResAllocationDto resAllocationDto = new ResAllocationDto + { + Ctime = Convert.ToDateTime("2022-11-01T15:26:55"), + Appid = "com.dongniu", + Appuserid = "dn0178911", + Deptid = "2", + Seaid = null, + Groupid = "14", + Eid = 60251, + Addway = "0", + /*Unionid = $"oz-hQ5idpaTgjQyHa0ZblNbpBLRQ", + Ch = ch.ToString(), + CampaignId = $"tag",*/ + AssignType = 1, + Hhuserid = null + }; + CheckUserDTO checkUserDTO = new CheckUserDTO + { + Appid = "ww89347c2378b6e050", + Appuserid = "yujinglin" + }; + var obj = await _httpClient.PostSecurityAsync>("http://localhost:7009/Api/SoftUser/GetUserProtectInfo", checkUserDTO, "UPWEBSITE", "YafhQn$3gLUl@XDI", "Nx7GqcMxc=F&cpUa"); + //ss = JsonConvert.SerializeObject(obj); + } + return ss; + } + catch (Exception ex) + { + throw new Exception(ex.Message); + } + } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Dockerfile b/code/Zxd.WebApi/Dockerfile new file mode 100644 index 0000000..18b3389 --- /dev/null +++ b/code/Zxd.WebApi/Dockerfile @@ -0,0 +1,22 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["zxd.webapi/zxd.webapi.csproj", "zxd.webapi/"] +RUN dotnet restore "zxd.webapi/zxd.webapi.csproj" +COPY . . +WORKDIR "/src/zxd.webapi" +RUN dotnet build "zxd.webapi.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "zxd.webapi.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "zxd.webapi.dll"] \ No newline at end of file diff --git a/code/Zxd.WebApi/Dto/AssignModel.cs b/code/Zxd.WebApi/Dto/AssignModel.cs new file mode 100644 index 0000000..32f48a2 --- /dev/null +++ b/code/Zxd.WebApi/Dto/AssignModel.cs @@ -0,0 +1,23 @@ +namespace Zxd.WebApi.Dto +{ + public class DbAssignUserModel + { + //public int? eid { get; set; } + public int? deptid { get; set; } + } + + public class DbAssignUserEidModel + { + public int? eid { get; set; } + public int? deptid { get; set; } + public DateTime? Utime { get; set; } + } + + public class AssignModel + { + public int? DeptId { get; set; } + public string? DeptName { get; set; } + public int? GroupId { get; set; } + //public int? Eid { get; set; } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Impl/IAssignUserDomain.cs b/code/Zxd.WebApi/Impl/IAssignUserDomain.cs new file mode 100644 index 0000000..e7fa481 --- /dev/null +++ b/code/Zxd.WebApi/Impl/IAssignUserDomain.cs @@ -0,0 +1,11 @@ +using Zxd.WebApi.Dto; + +namespace Zxd.WebApi.Impl +{ + public interface IAssignUserDomain : IScopedDependency + { + Task> GetAssignModels(string resId); + + Task> GetAssignDetail(string resId); + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Program.cs b/code/Zxd.WebApi/Program.cs new file mode 100644 index 0000000..69e78d4 --- /dev/null +++ b/code/Zxd.WebApi/Program.cs @@ -0,0 +1,115 @@ +using Exceptionless; + +try +{ + // Add services to the container. + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("Serilog.json") + .AddJsonFile($"Serilog.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true) + .Build(); + + var builder = WebApplication.CreateBuilder(args); + var logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .WriteTo.Exceptionless(builder.Configuration.GetValue("Exceptionless:ApiKey"), builder.Configuration.GetValue("Exceptionless:ServerUrl"), new string[] { "zxd-webapi" }) + .CreateLogger(); + Log.Logger = logger; + builder.Services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(logger); + }); + + Log.Information("Starting ZXD Service"); + builder.Services.AddControllers() + .AddApiResult() + .AddApiSignature() + .AddJsonOptions(options => + { + options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; + options.JsonSerializerOptions.Converters.Add(new JsonOptionsExtensions()); + }); + builder.Services.AddDGHttpClient(); + //builder.Services.AddHostedService(); + /* if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != "Production") + { + builder.Services.AddHostedService(); + }*/ + var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; + builder.Services.AddCors(option => + { + option.AddPolicy(MyAllowSpecificOrigins, + policy => + { + policy.SetIsOriginAllowed(_ => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); + }); + builder.Services.AddExceptionless(builder.Configuration); + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo + { + Version = "v1", + Title = "ZXD CORE API", + Description = "ZXD CORE API" + }); + var xmlFilename = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"; + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Zxd.Domain.xml")); + }); + builder.Services.AddRedis(builder.Configuration); + builder.Services.AddOptions() + .Configure(e => builder.Configuration.GetSection("SystemConfig").Bind(e)) + .Configure(e => builder.Configuration.GetSection("ClientKey").Bind(e)); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("zxdcrm"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("zxdcrm"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("dncmsbase"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("dncmsbase"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("dncms"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("dncms"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("crm"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("crm"))); + }); + builder.Services.AddDGEntityFramework(options => + { + options.UseMySql(builder.Configuration.GetConnectionString("usercenter"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("usercenter"))); + }); + builder.Services.AddAutoIoc(typeof(IScopedDependency), LifeCycle.Scoped) + .AddAutoIoc(typeof(ISingletonDependency), LifeCycle.Singleton) + .AddAutoIoc(typeof(ITransientDependency), LifeCycle.Transient) + .AddMapper(); + var app = builder.Build(); + app.UseCors(MyAllowSpecificOrigins); + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment() || Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "PreProduction") + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseAuthorization(); + app.UseExceptionless(); + app.MapControllers(); + + app.Run(); +} +catch (Exception ex) +{ + Log.Fatal(ex, "Host terminated unexpectedly"); +} +finally +{ + Log.CloseAndFlush(); +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Properties/launchSettings.json b/code/Zxd.WebApi/Properties/launchSettings.json new file mode 100644 index 0000000..bf49afc --- /dev/null +++ b/code/Zxd.WebApi/Properties/launchSettings.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:3050", + "sslPort": 44303 + } + }, + "profiles": { + "Zxd.WebApi": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:7009", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": {}, + "publishAllPorts": true, + "useSSL": true, + "httpPort": 5255, + "sslPort": 5256 + } + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/Readme.md b/code/Zxd.WebApi/Readme.md new file mode 100644 index 0000000..1a11f43 --- /dev/null +++ b/code/Zxd.WebApi/Readme.md @@ -0,0 +1,6 @@ +# 供外部调用的中心点接口 +# 连接数据库: zxdcrm,dncmsbase,usercenter,crm +# 测试地址:http://192.168.11.81:8087 +# 正式地址:http://centerapi.soft.dn8188.com +# 相关api: 企微资源入库 +# 获取用户过期标签接口 \ No newline at end of file diff --git a/code/Zxd.WebApi/Serilog.Production.json b/code/Zxd.WebApi/Serilog.Production.json new file mode 100644 index 0000000..dd96049 --- /dev/null +++ b/code/Zxd.WebApi/Serilog.Production.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.AspNetCore" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "System": "Warning", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/Zxd.WebApi/Serilog.json b/code/Zxd.WebApi/Serilog.json new file mode 100644 index 0000000..bbd3ba0 --- /dev/null +++ b/code/Zxd.WebApi/Serilog.json @@ -0,0 +1,33 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.AspNetCore" ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "System": "Warning", + "Microsoft.EntityFrameworkCore": "Warning", + "System.Net.Http.HttpClient": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "encoding": "System.Text.Encoding::UTF8", + "path": "logs/log.log", + "rollingInterval": "3", + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff}] <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}", + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] + } +} diff --git a/code/Zxd.WebApi/Zxd.WebApi.csproj b/code/Zxd.WebApi/Zxd.WebApi.csproj new file mode 100644 index 0000000..aaebba4 --- /dev/null +++ b/code/Zxd.WebApi/Zxd.WebApi.csproj @@ -0,0 +1,58 @@ + + + + net6.0 + enable + enable + 2c68bd3b-64d4-48dc-9225-fe34d9e25ac7 + Linux + True + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + true + PreserveNewest + + + diff --git a/code/Zxd.WebApi/appsettings.Disaster.json b/code/Zxd.WebApi/appsettings.Disaster.json new file mode 100644 index 0000000..9497e5f --- /dev/null +++ b/code/Zxd.WebApi/appsettings.Disaster.json @@ -0,0 +1,74 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Data Source=10.22.15.61;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=10.22.15.68;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "crm": "Data Source=10.22.15.61;Port=3306;Initial Catalog=db_crm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "usercenter": "Data Source=10.22.15.68;Port=3306;Initial Catalog=usercenter;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "2mcoAUXvYMnqyCluIARX6AsmdDQgrOu5WNMPhvid" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "Appid": "qt_core", + "AppSecret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=", + "SsoUrl": "http://10.22.15.22:15814", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "SalesLeadUrl": "http://10.22.15.22:16549/dev.html", + "CmsUrl": "http://resourcecenter.soft.dn8188.com/", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://172.18.10.78:8090", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://qm.dn8188.com:8099/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=" + }, + "Redis": { + "HostName": "10.22.15.65", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/appsettings.Production.json b/code/Zxd.WebApi/appsettings.Production.json new file mode 100644 index 0000000..cef986a --- /dev/null +++ b/code/Zxd.WebApi/appsettings.Production.json @@ -0,0 +1,81 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=zxdcrm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "dncmsbase": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncmsbase;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "crm": "Data Source=mysql98ff96c3dffa.rds.ivolces.com;Port=3306;Initial Catalog=db_crm;user id=qianbenjie;password=Hcqianbenjie@123;Old Guids=true;SslMode=None", + "usercenter": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=usercenter;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None", + "dncms": "Data Source=pc-wz927dkkv6y71jao7.rwlb.rds.aliyuncs.com;Port=3306;Initial Catalog=dncms;user id=dn_cms;password=dn3EdxCms@8zsw_2Wkm;SslMode=None" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.11.9:5000", + "ApiKey": "2mcoAUXvYMnqyCluIARX6AsmdDQgrOu5WNMPhvid" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + }, + { + "Id": "SCREENRECORD", + "Vi": "Ra3GwdMxf=D&tjLh", + "NewAccessKey": "WhglRc$5uAFD@YNB" + } + ], + "SystemConfig": { + "ZXDCoreUrl": "http://172.18.11.63:8089/", + "Appid": "qt_core", + "AppSecret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=", + "SsoUrl": "http://conf.soft.dn8188.com", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "CmsUrl": "http://resourcecenter.soft.dn8188.com/", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://172.18.10.78:8090", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://qm.dn8188.com:8099/cache/clear" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "uoJdPl19HK2iWGLPGuOMxh38BGx8WveClY3I3PqDNYk=" + }, + "Redis": { + "HostName": "redis-cngzdnddztrevahsz.redis.ivolces.com", + "Port": "6379", + "Password": "dn8sCe@mxTvzx", + "Defaultdatabase": "0" + } +} \ No newline at end of file diff --git a/code/Zxd.WebApi/appsettings.json b/code/Zxd.WebApi/appsettings.json new file mode 100644 index 0000000..cb8c6af --- /dev/null +++ b/code/Zxd.WebApi/appsettings.json @@ -0,0 +1,82 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;", + "crm": "Server=192.168.11.141;Database=db_crm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "usercenter": "Server=192.168.11.41;Database=usercenter;UserId=root;Password=sa123456.;port=3306;", + "dncms": "Server=192.168.11.41;Database=dncms;UserId=root;Password=sa123456.;port=3306;" + }, + "Exceptionless": { + "ServerUrl": "http://10.22.12.9:5000", + "ApiKey": "h20zFUA8Uwn6x7QwgZwIiqQcZZvSXqGzfkm3BeNJ" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Ew6GqcKnb=F&tjFb", + "NewAccessKey": "GsvhQn$3gCPl@KRT" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + }, + { + "Id": "SCREENRECORD", + "Vi": "Ra3GwdMxf=D&tjLh", + "NewAccessKey": "WhglRc$5uAFD@YNB" + } + ], + "SystemConfig": { + "ZXDCoreUrl": "http://120.77.165.155:8089/", + "Appid": "qt_core", + "AppSecret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=", + "SsoUrl": "http://192.168.11.141:24434", + "SsoTokenUrl": "/v1/api/open/sso/token", + "SsoOrganizationUrl": "/v1/api/open/data/sync/organization", + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "CmsUrl": "http://192.168.111.143:19855/", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "ClearCacheUrls": [ + "http://192.168.11.46/home/cache" + ] + }, + "SignConfig": { + "AppId": "qt_core", + "Secret": "1Xn2x1HNV3PzC1vJ/we62YJnwkBzBLIhutbB/uWqp1o=" + }, + "Redis": { + "HostName": "192.168.11.81", + "Port": "6379", + "Password": "Abc@123456", + "Defaultdatabase": "1" + } +} \ No newline at end of file diff --git a/test/Zxd.Core.Test/UnitTest1.cs b/test/Zxd.Core.Test/UnitTest1.cs new file mode 100644 index 0000000..5ce9a08 --- /dev/null +++ b/test/Zxd.Core.Test/UnitTest1.cs @@ -0,0 +1,43 @@ +namespace Zxd.Core.Test +{ + [TestClass] + public class UnitTest1 + { + public UnitTest1() + { + const string OUTPUT_TEMPLATE = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} <{ThreadId}> [{Level:u3}] {Message:lj}{NewLine}{Exception}"; + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) + .Enrich.WithThreadId() + .Enrich.FromLogContext() + .WriteTo.Console(outputTemplate: OUTPUT_TEMPLATE) + .WriteTo.File("logs/log.log" + , rollingInterval: RollingInterval.Day + , outputTemplate: OUTPUT_TEMPLATE) + .CreateLogger(); + var config = new ConfigurationBuilder() + .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true }) + .Build(); + + IServiceCollection services = new ServiceCollection(); + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(config); + + var serviceProvider = services.BuildServiceProvider(); + + } + + [TestMethod] + public void TestMethod1() + { + var time = 1 << 0; + var str = $"{time}"; + } + } +} \ No newline at end of file diff --git a/test/Zxd.Core.Test/Usings.cs b/test/Zxd.Core.Test/Usings.cs new file mode 100644 index 0000000..501043b --- /dev/null +++ b/test/Zxd.Core.Test/Usings.cs @@ -0,0 +1,8 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.Configuration.Json; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using System.Text.Json; +global using Serilog; +global using Serilog.Events; \ No newline at end of file diff --git a/test/Zxd.Core.Test/Zxd.Core.Test.csproj b/test/Zxd.Core.Test/Zxd.Core.Test.csproj new file mode 100644 index 0000000..91c179c --- /dev/null +++ b/test/Zxd.Core.Test/Zxd.Core.Test.csproj @@ -0,0 +1,34 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + PreserveNewest + true + PreserveNewest + + + + + + + + + + + + + + + diff --git a/test/Zxd.Core.Test/appsettings.json b/test/Zxd.Core.Test/appsettings.json new file mode 100644 index 0000000..ae47ddc --- /dev/null +++ b/test/Zxd.Core.Test/appsettings.json @@ -0,0 +1,54 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "zxdcrm": "Server=192.168.11.141;Database=zxdcrm;UserId=tafadmin;Password=tafadmin2017;port=3306;", + "dncmsbase": "Server=192.168.11.41;Database=dncmsbase;UserId=root;Password=sa123456.;port=3306;" + }, + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ], + "SystemConfig": { + "SalesLeadUrl": "http://sc.soft.dn8188.com/dev.html", + "CRMClientKey": "TDORDERSITE", + "DataClientCode": "DNG8", + "shj": "192.168.11.222:3050", //录音链接用到 + "DataSyncApiUrl": "http://192.168.11.46:8090", + "ClientKey": [ + { + "Id": "UPWEBSITE", + "Name": "NewWebSite", + "AccessKey": "1622a92d", + "Vi": "Nx7GqcMxc=F&cpUa", + "NewAccessKey": "YafhQn$3gLUl@XDI" + }, + { + "Id": "TDORDERSITE", + "Name": "订单接口", + "AccessKey": "622a92d1" + } + ] + }, + "Redis": { + "HostName": "192.168.11.81", + "Port": "6379", + "Password": "Abc@123456", + "Defaultdatabase": "0" + } +} \ No newline at end of file