From ad68f6b75b31659d113b908ff0b954a8dc26e816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=E5=BB=BA=E4=B8=9C?= <617601767@qq.com> Date: Fri, 29 Dec 2023 13:00:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E7=89=88=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 583 ++++++++ BuildGateway.bat | 1 + BuildLanSheng.bat | 1 + BuildZhongLian.bat | 1 + Cache/CacheInterface/CacheInterface.csproj | 9 + Cache/CacheInterface/ICacheService.cs | 25 + Cache/CacheService/CacheService.cs | 38 + Cache/CacheService/CacheService.csproj | 23 + Cache/CacheService/MemoryCacheService.cs | 116 ++ Cache/CacheService/RedisCacheService.cs | 123 ++ CommonExtend/ByteBufferExtend.cs | 61 + CommonExtend/ByteExtend.cs | 189 +++ CommonExtend/CommonExtend.csproj | 14 + CommonExtend/DaprExtend.cs | 28 + CommonExtend/StringExtend.cs | 16 + CommonModel/BadRequestException.cs | 16 + CommonModel/CommonModel.csproj | 9 + CommonModel/PageBase.cs | 21 + CommonModel/PageData.cs | 23 + CommonModel/PageSearch.cs | 122 ++ CommonModel/Properties/launchSettings.json | 12 + CommonModel/SplitDateId.cs | 26 + Dapr/Components/pubsub-rabbitmq.yaml | 30 + Dapr/Components/pubsub-redis.yaml | 13 + Dapr/Components/statestore.yaml | 20 + Dapr/config.yaml | 10 + DockerCompose/docker-compose-all.yml | 379 +++++ DockerCompose/docker-compose-dev.yml | 103 ++ DockerCompose/docker-compose-env.yml | 60 + FYCore.sln | 140 ++ GatewayAPI/.config/dotnet-tools.json | 12 + GatewayAPI/Dockerfile | 22 + GatewayAPI/GatewayAPI.csproj | 20 + GatewayAPI/HostReplaceMiddleware.cs | 121 ++ GatewayAPI/Program.cs | 48 + GatewayAPI/Properties/launchSettings.json | 37 + GatewayAPI/appsettings.Development.json | 8 + GatewayAPI/appsettings.json | 88 ++ .../Controllers/DeviceController.cs | 88 ++ LanSheng/LanShengAPI/Dockerfile | 29 + LanSheng/LanShengAPI/LanShengAPI.csproj | 24 + LanSheng/LanShengAPI/Program.cs | 29 + .../Properties/launchSettings.json | 37 + .../LanShengAPI/appsettings.Development.json | 13 + LanSheng/LanShengAPI/appsettings.json | 18 + .../LanShengInterface/IDeviceDataActor.cs | 14 + LanSheng/LanShengInterface/IDeviceService.cs | 35 + .../LanShengInterface/ITcpDataLogActor.cs | 14 + LanSheng/LanShengInterface/ITcpService.cs | 20 + .../LanShengInterface.csproj | 19 + LanSheng/LanShengModel/ChannelQueue.cs | 23 + LanSheng/LanShengModel/DeviceData.cs | 507 +++++++ LanSheng/LanShengModel/DeviceData1001.cs | 41 + LanSheng/LanShengModel/DeviceData1103.cs | 372 +++++ LanSheng/LanShengModel/DeviceError.cs | 48 + LanSheng/LanShengModel/DeviceErrorReport.cs | 45 + LanSheng/LanShengModel/LanShengModel.csproj | 14 + LanSheng/LanShengModel/TcpDataLog.cs | 74 + LanSheng/LanShengService/DeviceService.cs | 1292 +++++++++++++++++ LanSheng/LanShengService/LanShengService.cs | 52 + .../LanShengService/LanShengService.csproj | 33 + .../LanShengService/Tcp/ChannelHandler.cs | 119 ++ .../LanShengService/Tcp/DecoderHandler.cs | 178 +++ .../LanShengService/Tcp/EncoderHandler.cs | 72 + .../LanShengService/Tcp/HeartBeatHandler.cs | 40 + LanSheng/LanShengService/TcpService.cs | 340 +++++ README.md | 1 + .../Controllers/DriveController.cs | 71 + .../Controllers/InstallController.cs | 107 ++ .../Controllers/MaintenanceController.cs | 67 + .../Controllers/ParamController.cs | 70 + .../Controllers/ProjectController.cs | 87 ++ ZhongLian/ZhongLianAPI/Dockerfile | 25 + ZhongLian/ZhongLianAPI/Program.cs | 52 + .../Properties/launchSettings.json | 37 + ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj | 23 + .../ZhongLianAPI/appsettings.Development.json | 8 + ZhongLian/ZhongLianAPI/appsettings.json | 12 + ZhongLian/ZhongLianInterface/IDriveService.cs | 47 + ZhongLian/ZhongLianInterface/IInstallActor.cs | 35 + .../ZhongLianInterface/IInstallService.cs | 111 ++ .../ZhongLianInterface/IMaintenanceService.cs | 27 + ZhongLian/ZhongLianInterface/IParamService.cs | 26 + .../ZhongLianInterface/IProjectService.cs | 55 + .../ZhongLianInterface.csproj | 18 + ZhongLian/ZhongLianModel/CompanyDO.cs | 92 ++ ZhongLian/ZhongLianModel/DeviceDO.cs | 34 + ZhongLian/ZhongLianModel/FileDO.cs | 48 + ZhongLian/ZhongLianModel/GeoProjectDTO.cs | 17 + ZhongLian/ZhongLianModel/GroupDO.cs | 66 + ZhongLian/ZhongLianModel/InstallDO.cs | 171 +++ ZhongLian/ZhongLianModel/InstallStepDO.cs | 70 + ZhongLian/ZhongLianModel/MaintenanceDO.cs | 161 ++ ZhongLian/ZhongLianModel/ParamDO.cs | 25 + ZhongLian/ZhongLianModel/ProjectDO.cs | 201 +++ .../Properties/launchSettings.json | 12 + .../ZhongLianModel/ZhongLianModel.csproj | 13 + ZhongLian/ZhongLianService/DriveService.cs | 103 ++ ZhongLian/ZhongLianService/InstallActor.cs | 55 + ZhongLian/ZhongLianService/InstallService.cs | 385 +++++ .../ZhongLianService/MaintenanceService.cs | 162 +++ ZhongLian/ZhongLianService/ParamService.cs | 113 ++ ZhongLian/ZhongLianService/ProjectService.cs | 266 ++++ .../Properties/launchSettings.json | 12 + .../ZhongLianService/ZhongLianService.cs | 42 + .../ZhongLianService/ZhongLianService.csproj | 22 + 106 files changed, 9107 insertions(+) create mode 100644 .gitignore create mode 100644 BuildGateway.bat create mode 100644 BuildLanSheng.bat create mode 100644 BuildZhongLian.bat create mode 100644 Cache/CacheInterface/CacheInterface.csproj create mode 100644 Cache/CacheInterface/ICacheService.cs create mode 100644 Cache/CacheService/CacheService.cs create mode 100644 Cache/CacheService/CacheService.csproj create mode 100644 Cache/CacheService/MemoryCacheService.cs create mode 100644 Cache/CacheService/RedisCacheService.cs create mode 100644 CommonExtend/ByteBufferExtend.cs create mode 100644 CommonExtend/ByteExtend.cs create mode 100644 CommonExtend/CommonExtend.csproj create mode 100644 CommonExtend/DaprExtend.cs create mode 100644 CommonExtend/StringExtend.cs create mode 100644 CommonModel/BadRequestException.cs create mode 100644 CommonModel/CommonModel.csproj create mode 100644 CommonModel/PageBase.cs create mode 100644 CommonModel/PageData.cs create mode 100644 CommonModel/PageSearch.cs create mode 100644 CommonModel/Properties/launchSettings.json create mode 100644 CommonModel/SplitDateId.cs create mode 100644 Dapr/Components/pubsub-rabbitmq.yaml create mode 100644 Dapr/Components/pubsub-redis.yaml create mode 100644 Dapr/Components/statestore.yaml create mode 100644 Dapr/config.yaml create mode 100644 DockerCompose/docker-compose-all.yml create mode 100644 DockerCompose/docker-compose-dev.yml create mode 100644 DockerCompose/docker-compose-env.yml create mode 100644 FYCore.sln create mode 100644 GatewayAPI/.config/dotnet-tools.json create mode 100644 GatewayAPI/Dockerfile create mode 100644 GatewayAPI/GatewayAPI.csproj create mode 100644 GatewayAPI/HostReplaceMiddleware.cs create mode 100644 GatewayAPI/Program.cs create mode 100644 GatewayAPI/Properties/launchSettings.json create mode 100644 GatewayAPI/appsettings.Development.json create mode 100644 GatewayAPI/appsettings.json create mode 100644 LanSheng/LanShengAPI/Controllers/DeviceController.cs create mode 100644 LanSheng/LanShengAPI/Dockerfile create mode 100644 LanSheng/LanShengAPI/LanShengAPI.csproj create mode 100644 LanSheng/LanShengAPI/Program.cs create mode 100644 LanSheng/LanShengAPI/Properties/launchSettings.json create mode 100644 LanSheng/LanShengAPI/appsettings.Development.json create mode 100644 LanSheng/LanShengAPI/appsettings.json create mode 100644 LanSheng/LanShengInterface/IDeviceDataActor.cs create mode 100644 LanSheng/LanShengInterface/IDeviceService.cs create mode 100644 LanSheng/LanShengInterface/ITcpDataLogActor.cs create mode 100644 LanSheng/LanShengInterface/ITcpService.cs create mode 100644 LanSheng/LanShengInterface/LanShengInterface.csproj create mode 100644 LanSheng/LanShengModel/ChannelQueue.cs create mode 100644 LanSheng/LanShengModel/DeviceData.cs create mode 100644 LanSheng/LanShengModel/DeviceData1001.cs create mode 100644 LanSheng/LanShengModel/DeviceData1103.cs create mode 100644 LanSheng/LanShengModel/DeviceError.cs create mode 100644 LanSheng/LanShengModel/DeviceErrorReport.cs create mode 100644 LanSheng/LanShengModel/LanShengModel.csproj create mode 100644 LanSheng/LanShengModel/TcpDataLog.cs create mode 100644 LanSheng/LanShengService/DeviceService.cs create mode 100644 LanSheng/LanShengService/LanShengService.cs create mode 100644 LanSheng/LanShengService/LanShengService.csproj create mode 100644 LanSheng/LanShengService/Tcp/ChannelHandler.cs create mode 100644 LanSheng/LanShengService/Tcp/DecoderHandler.cs create mode 100644 LanSheng/LanShengService/Tcp/EncoderHandler.cs create mode 100644 LanSheng/LanShengService/Tcp/HeartBeatHandler.cs create mode 100644 LanSheng/LanShengService/TcpService.cs create mode 100644 README.md create mode 100644 ZhongLian/ZhongLianAPI/Controllers/DriveController.cs create mode 100644 ZhongLian/ZhongLianAPI/Controllers/InstallController.cs create mode 100644 ZhongLian/ZhongLianAPI/Controllers/MaintenanceController.cs create mode 100644 ZhongLian/ZhongLianAPI/Controllers/ParamController.cs create mode 100644 ZhongLian/ZhongLianAPI/Controllers/ProjectController.cs create mode 100644 ZhongLian/ZhongLianAPI/Dockerfile create mode 100644 ZhongLian/ZhongLianAPI/Program.cs create mode 100644 ZhongLian/ZhongLianAPI/Properties/launchSettings.json create mode 100644 ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj create mode 100644 ZhongLian/ZhongLianAPI/appsettings.Development.json create mode 100644 ZhongLian/ZhongLianAPI/appsettings.json create mode 100644 ZhongLian/ZhongLianInterface/IDriveService.cs create mode 100644 ZhongLian/ZhongLianInterface/IInstallActor.cs create mode 100644 ZhongLian/ZhongLianInterface/IInstallService.cs create mode 100644 ZhongLian/ZhongLianInterface/IMaintenanceService.cs create mode 100644 ZhongLian/ZhongLianInterface/IParamService.cs create mode 100644 ZhongLian/ZhongLianInterface/IProjectService.cs create mode 100644 ZhongLian/ZhongLianInterface/ZhongLianInterface.csproj create mode 100644 ZhongLian/ZhongLianModel/CompanyDO.cs create mode 100644 ZhongLian/ZhongLianModel/DeviceDO.cs create mode 100644 ZhongLian/ZhongLianModel/FileDO.cs create mode 100644 ZhongLian/ZhongLianModel/GeoProjectDTO.cs create mode 100644 ZhongLian/ZhongLianModel/GroupDO.cs create mode 100644 ZhongLian/ZhongLianModel/InstallDO.cs create mode 100644 ZhongLian/ZhongLianModel/InstallStepDO.cs create mode 100644 ZhongLian/ZhongLianModel/MaintenanceDO.cs create mode 100644 ZhongLian/ZhongLianModel/ParamDO.cs create mode 100644 ZhongLian/ZhongLianModel/ProjectDO.cs create mode 100644 ZhongLian/ZhongLianModel/Properties/launchSettings.json create mode 100644 ZhongLian/ZhongLianModel/ZhongLianModel.csproj create mode 100644 ZhongLian/ZhongLianService/DriveService.cs create mode 100644 ZhongLian/ZhongLianService/InstallActor.cs create mode 100644 ZhongLian/ZhongLianService/InstallService.cs create mode 100644 ZhongLian/ZhongLianService/MaintenanceService.cs create mode 100644 ZhongLian/ZhongLianService/ParamService.cs create mode 100644 ZhongLian/ZhongLianService/ProjectService.cs create mode 100644 ZhongLian/ZhongLianService/Properties/launchSettings.json create mode 100644 ZhongLian/ZhongLianService/ZhongLianService.cs create mode 100644 ZhongLian/ZhongLianService/ZhongLianService.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb40f83 --- /dev/null +++ b/.gitignore @@ -0,0 +1,583 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# 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 +# Note: 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 + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# 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 +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# 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 +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# 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 +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd +*.mp4 +MySQL/Conf/mysql.cnf +MySQL/Data/#ib_16384_0.dblwr +MySQL/Data/#ib_16384_1.dblwr +MySQL/Data/auto.cnf +MySQL/Data/binlog.000013 +MySQL/Data/binlog.000014 +MySQL/Data/binlog.000015 +MySQL/Data/binlog.000016 +MySQL/Data/binlog.000017 +MySQL/Data/binlog.000018 +MySQL/Data/binlog.000019 +MySQL/Data/binlog.000020 +MySQL/Data/binlog.000021 +MySQL/Data/binlog.000022 +MySQL/Data/binlog.index +MySQL/Data/ca-key.pem +MySQL/Data/ca.pem +MySQL/Data/client-cert.pem +MySQL/Data/client-key.pem +MySQL/Data/ib_buffer_pool +MySQL/Data/ibdata1 +MySQL/Data/ibtmp1 +MySQL/Data/mysql-bin.000001 +MySQL/Data/mysql-bin.000002 +MySQL/Data/mysql-bin.000003 +MySQL/Data/mysql-bin.000004 +MySQL/Data/mysql-bin.000005 +MySQL/Data/mysql-bin.index +MySQL/Data/mysql.ibd +MySQL/Data/mysql.sock +MySQL/Data/private_key.pem +MySQL/Data/public_key.pem +MySQL/Data/server-cert.pem +MySQL/Data/server-key.pem +MySQL/Data/undo_001 +MySQL/Data/undo_002 +MySQL/Data/#innodb_redo/#ib_redo794 +MySQL/Data/#innodb_redo/#ib_redo795_tmp +MySQL/Data/#innodb_redo/#ib_redo796_tmp +MySQL/Data/#innodb_redo/#ib_redo797_tmp +MySQL/Data/#innodb_redo/#ib_redo798_tmp +MySQL/Data/#innodb_redo/#ib_redo799_tmp +MySQL/Data/#innodb_redo/#ib_redo800_tmp +MySQL/Data/#innodb_redo/#ib_redo801_tmp +MySQL/Data/#innodb_redo/#ib_redo802_tmp +MySQL/Data/#innodb_redo/#ib_redo803_tmp +MySQL/Data/#innodb_redo/#ib_redo804_tmp +MySQL/Data/#innodb_redo/#ib_redo805_tmp +MySQL/Data/#innodb_redo/#ib_redo806_tmp +MySQL/Data/#innodb_redo/#ib_redo807_tmp +MySQL/Data/#innodb_redo/#ib_redo808_tmp +MySQL/Data/#innodb_redo/#ib_redo809_tmp +MySQL/Data/#innodb_redo/#ib_redo810_tmp +MySQL/Data/#innodb_redo/#ib_redo811_tmp +MySQL/Data/#innodb_redo/#ib_redo812_tmp +MySQL/Data/#innodb_redo/#ib_redo813_tmp +MySQL/Data/#innodb_redo/#ib_redo814_tmp +MySQL/Data/#innodb_redo/#ib_redo815_tmp +MySQL/Data/#innodb_redo/#ib_redo816_tmp +MySQL/Data/#innodb_redo/#ib_redo817_tmp +MySQL/Data/#innodb_redo/#ib_redo818_tmp +MySQL/Data/#innodb_redo/#ib_redo819_tmp +MySQL/Data/#innodb_redo/#ib_redo820_tmp +MySQL/Data/#innodb_redo/#ib_redo821_tmp +MySQL/Data/#innodb_redo/#ib_redo822_tmp +MySQL/Data/#innodb_redo/#ib_redo823_tmp +MySQL/Data/#innodb_redo/#ib_redo824_tmp +MySQL/Data/#innodb_redo/#ib_redo825_tmp +MySQL/Data/#innodb_temp/temp_1.ibt +MySQL/Data/#innodb_temp/temp_2.ibt +MySQL/Data/#innodb_temp/temp_3.ibt +MySQL/Data/#innodb_temp/temp_4.ibt +MySQL/Data/#innodb_temp/temp_5.ibt +MySQL/Data/#innodb_temp/temp_6.ibt +MySQL/Data/#innodb_temp/temp_7.ibt +MySQL/Data/#innodb_temp/temp_8.ibt +MySQL/Data/#innodb_temp/temp_9.ibt +MySQL/Data/#innodb_temp/temp_10.ibt +MySQL/Data/lsdb/cap_man.ibd +MySQL/Data/lsdb/cap_people.ibd +MySQL/Data/lsdb/cap_woman.ibd +MySQL/Data/lsdb/cap@002epublished.ibd +MySQL/Data/lsdb/cap@002ereceived.ibd +MySQL/Data/lsdb/ls_devicedata.ibd +MySQL/Data/lsdb/ls_tcpdatalog_20230330.ibd +MySQL/Data/lsdb/ls_tcpdatalog_20230331.ibd +MySQL/Data/lsdb/ls_tcpdatalog_20230401.ibd +MySQL/Data/lsdb/ls_tcpdatalog_20230402.ibd +MySQL/Data/lsdb/ls_tcpdatalog_20230403.ibd +MySQL/Data/lsdb/tprz_device.ibd +MySQL/Data/lsdb/zl_install_20230101.ibd +MySQL/Data/lsdb/zl_installstep_20230101.ibd +MySQL/Data/lsdb/zl_maintenance_20230101.ibd +MySQL/Data/lsdb/zl_param.ibd +MySQL/Data/lsdb/zl_product.ibd +MySQL/Data/mysql/general_log_213.sdi +MySQL/Data/mysql/general_log.CSM +MySQL/Data/mysql/general_log.CSV +MySQL/Data/mysql/slow_log_214.sdi +MySQL/Data/mysql/slow_log.CSM +MySQL/Data/mysql/slow_log.CSV +MySQL/Data/performance_schema/accounts_145.sdi +MySQL/Data/performance_schema/binary_log_trans_189.sdi +MySQL/Data/performance_schema/cond_instances_82.sdi +MySQL/Data/performance_schema/data_lock_waits_161.sdi +MySQL/Data/performance_schema/data_locks_160.sdi +MySQL/Data/performance_schema/error_log_83.sdi +MySQL/Data/performance_schema/events_errors_su_139.sdi +MySQL/Data/performance_schema/events_errors_su_140.sdi +MySQL/Data/performance_schema/events_errors_su_141.sdi +MySQL/Data/performance_schema/events_errors_su_142.sdi +MySQL/Data/performance_schema/events_errors_su_143.sdi +MySQL/Data/performance_schema/events_stages_cu_111.sdi +MySQL/Data/performance_schema/events_stages_hi_112.sdi +MySQL/Data/performance_schema/events_stages_hi_113.sdi +MySQL/Data/performance_schema/events_stages_su_114.sdi +MySQL/Data/performance_schema/events_stages_su_115.sdi +MySQL/Data/performance_schema/events_stages_su_116.sdi +MySQL/Data/performance_schema/events_stages_su_117.sdi +MySQL/Data/performance_schema/events_stages_su_118.sdi +MySQL/Data/performance_schema/events_statement_119.sdi +MySQL/Data/performance_schema/events_statement_120.sdi +MySQL/Data/performance_schema/events_statement_121.sdi +MySQL/Data/performance_schema/events_statement_122.sdi +MySQL/Data/performance_schema/events_statement_123.sdi +MySQL/Data/performance_schema/events_statement_124.sdi +MySQL/Data/performance_schema/events_statement_125.sdi +MySQL/Data/performance_schema/events_statement_126.sdi +MySQL/Data/performance_schema/events_statement_127.sdi +MySQL/Data/performance_schema/events_statement_128.sdi +MySQL/Data/performance_schema/events_statement_129.sdi +MySQL/Data/performance_schema/events_statement_130.sdi +MySQL/Data/performance_schema/events_transacti_131.sdi +MySQL/Data/performance_schema/events_transacti_132.sdi +MySQL/Data/performance_schema/events_transacti_133.sdi +MySQL/Data/performance_schema/events_transacti_134.sdi +MySQL/Data/performance_schema/events_transacti_135.sdi +MySQL/Data/performance_schema/events_transacti_136.sdi +MySQL/Data/performance_schema/events_transacti_137.sdi +MySQL/Data/performance_schema/events_transacti_138.sdi +MySQL/Data/performance_schema/events_waits_cur_84.sdi +MySQL/Data/performance_schema/events_waits_his_85.sdi +MySQL/Data/performance_schema/events_waits_his_86.sdi +MySQL/Data/performance_schema/events_waits_sum_87.sdi +MySQL/Data/performance_schema/events_waits_sum_88.sdi +MySQL/Data/performance_schema/events_waits_sum_89.sdi +MySQL/Data/performance_schema/events_waits_sum_90.sdi +MySQL/Data/performance_schema/events_waits_sum_91.sdi +MySQL/Data/performance_schema/events_waits_sum_92.sdi +MySQL/Data/performance_schema/file_instances_93.sdi +MySQL/Data/performance_schema/file_summary_by__94.sdi +MySQL/Data/performance_schema/file_summary_by__95.sdi +MySQL/Data/performance_schema/global_status_181.sdi +MySQL/Data/performance_schema/global_variables_184.sdi +MySQL/Data/performance_schema/host_cache_96.sdi +MySQL/Data/performance_schema/hosts_146.sdi +MySQL/Data/performance_schema/keyring_componen_191.sdi +MySQL/Data/performance_schema/keyring_keys_152.sdi +MySQL/Data/performance_schema/log_status_174.sdi +MySQL/Data/performance_schema/memory_summary_b_154.sdi +MySQL/Data/performance_schema/memory_summary_b_155.sdi +MySQL/Data/performance_schema/memory_summary_b_156.sdi +MySQL/Data/performance_schema/memory_summary_b_157.sdi +MySQL/Data/performance_schema/memory_summary_g_153.sdi +MySQL/Data/performance_schema/metadata_locks_159.sdi +MySQL/Data/performance_schema/mutex_instances_97.sdi +MySQL/Data/performance_schema/objects_summary__98.sdi +MySQL/Data/performance_schema/performance_time_99.sdi +MySQL/Data/performance_schema/persisted_variab_187.sdi +MySQL/Data/performance_schema/prepared_stateme_175.sdi +MySQL/Data/performance_schema/processlist_100.sdi +MySQL/Data/performance_schema/replication_appl_165.sdi +MySQL/Data/performance_schema/replication_appl_166.sdi +MySQL/Data/performance_schema/replication_appl_167.sdi +MySQL/Data/performance_schema/replication_appl_168.sdi +MySQL/Data/performance_schema/replication_appl_170.sdi +MySQL/Data/performance_schema/replication_appl_171.sdi +MySQL/Data/performance_schema/replication_asyn_172.sdi +MySQL/Data/performance_schema/replication_asyn_173.sdi +MySQL/Data/performance_schema/replication_conn_162.sdi +MySQL/Data/performance_schema/replication_conn_164.sdi +MySQL/Data/performance_schema/replication_grou_163.sdi +MySQL/Data/performance_schema/replication_grou_169.sdi +MySQL/Data/performance_schema/rwlock_instances_101.sdi +MySQL/Data/performance_schema/session_account__151.sdi +MySQL/Data/performance_schema/session_connect__150.sdi +MySQL/Data/performance_schema/session_status_182.sdi +MySQL/Data/performance_schema/session_variable_185.sdi +MySQL/Data/performance_schema/setup_actors_102.sdi +MySQL/Data/performance_schema/setup_consumers_103.sdi +MySQL/Data/performance_schema/setup_instrument_104.sdi +MySQL/Data/performance_schema/setup_objects_105.sdi +MySQL/Data/performance_schema/setup_threads_106.sdi +MySQL/Data/performance_schema/socket_instances_147.sdi +MySQL/Data/performance_schema/socket_summary_b_148.sdi +MySQL/Data/performance_schema/socket_summary_b_149.sdi +MySQL/Data/performance_schema/status_by_accoun_177.sdi +MySQL/Data/performance_schema/status_by_host_178.sdi +MySQL/Data/performance_schema/status_by_thread_179.sdi +MySQL/Data/performance_schema/status_by_user_180.sdi +MySQL/Data/performance_schema/table_handles_158.sdi +MySQL/Data/performance_schema/table_io_waits_s_107.sdi +MySQL/Data/performance_schema/table_io_waits_s_108.sdi +MySQL/Data/performance_schema/table_lock_waits_109.sdi +MySQL/Data/performance_schema/threads_110.sdi +MySQL/Data/performance_schema/tls_channel_stat_190.sdi +MySQL/Data/performance_schema/user_defined_fun_188.sdi +MySQL/Data/performance_schema/user_variables_b_176.sdi +MySQL/Data/performance_schema/users_144.sdi +MySQL/Data/performance_schema/variables_by_thr_183.sdi +MySQL/Data/performance_schema/variables_info_186.sdi +MySQL/Data/sys/sys_config.ibd +MySQL/Data/ymdb/wh_bill_data.ibd +MySQL/Data/ymdb/wh_bill.ibd +MySQL/Data/ymdb/wh_material.ibd +MySQL/Data/ymdb/wh_warehouse_manager.ibd +MySQL/Data/ymdb/wh_warehouse.ibd +MySQL/Data/zklt/database_source.ibd +Redis/redis.conf diff --git a/BuildGateway.bat b/BuildGateway.bat new file mode 100644 index 0000000..c1f2d58 --- /dev/null +++ b/BuildGateway.bat @@ -0,0 +1 @@ + start "gateway" cmd /k docker build -f GatewayAPI\Dockerfile -t gateway:latest . \ No newline at end of file diff --git a/BuildLanSheng.bat b/BuildLanSheng.bat new file mode 100644 index 0000000..5ff323a --- /dev/null +++ b/BuildLanSheng.bat @@ -0,0 +1 @@ + start "lansheng" cmd /k docker build -f Lansheng\LanShengAPI\Dockerfile -t lansheng:latest . \ No newline at end of file diff --git a/BuildZhongLian.bat b/BuildZhongLian.bat new file mode 100644 index 0000000..bc810ad --- /dev/null +++ b/BuildZhongLian.bat @@ -0,0 +1 @@ + start "zhonglian" cmd /k docker build -f ZhongLian\ZhongLianAPI\Dockerfile -t zhonglian:latest . \ No newline at end of file diff --git a/Cache/CacheInterface/CacheInterface.csproj b/Cache/CacheInterface/CacheInterface.csproj new file mode 100644 index 0000000..cfadb03 --- /dev/null +++ b/Cache/CacheInterface/CacheInterface.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + diff --git a/Cache/CacheInterface/ICacheService.cs b/Cache/CacheInterface/ICacheService.cs new file mode 100644 index 0000000..8ad884e --- /dev/null +++ b/Cache/CacheInterface/ICacheService.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CacheInterface +{ + public interface ICacheService + { + Task Set(string key, T value, int ttl = -1); + + Task BatchSet(Dictionary values, int ttl = -1); + + Task Get(string key); + + Task> BatchGet(IEnumerable keys); + + Task Delete(string key); + + Task BatchDelete(params string[] keys); + + Task> Query(string query, int count = 9999); + } +} diff --git a/Cache/CacheService/CacheService.cs b/Cache/CacheService/CacheService.cs new file mode 100644 index 0000000..11ff816 --- /dev/null +++ b/Cache/CacheService/CacheService.cs @@ -0,0 +1,38 @@ +using CacheInterface; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Dapr.AspNetCore; +using Microsoft.Extensions.Caching.Memory; +using Google.Protobuf.WellKnownTypes; +using CommonExtend; +using Dapr.Client; +using Microsoft.Extensions.Logging; +using System.Text.Json; + +namespace CacheService +{ + public static class CacheServiceExtend + { + public static IServiceCollection InitRedisCacheService(this IServiceCollection services, string url) + { + services.AddSingleton((_services) => + { + return new RedisCacheService(_services, url); + }); + return services; + } + + public static IServiceCollection InitMemoryCacheService(this IServiceCollection services) + { + services.AddSingleton((_services) => + { + return new MemoryCacheService(_services); + }); + return services; + } + } +} diff --git a/Cache/CacheService/CacheService.csproj b/Cache/CacheService/CacheService.csproj new file mode 100644 index 0000000..7556207 --- /dev/null +++ b/Cache/CacheService/CacheService.csproj @@ -0,0 +1,23 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + + + + + diff --git a/Cache/CacheService/MemoryCacheService.cs b/Cache/CacheService/MemoryCacheService.cs new file mode 100644 index 0000000..9b36023 --- /dev/null +++ b/Cache/CacheService/MemoryCacheService.cs @@ -0,0 +1,116 @@ +using CacheInterface; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NewLife.Caching; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace CacheService +{ + public class MemoryCacheService : ICacheService + { + public MemoryCacheService(IServiceProvider services) + { + Services = services; + + Logger = Services.GetRequiredService>(); + + Memory = new MemoryCache(); + + Logger.LogDebug("加载缓存服务"); + } + + private readonly IServiceProvider Services; + + private readonly ILogger Logger; + + private readonly MemoryCache Memory; + + public Task Set(string key, T value, int ttl = -1) + { + Logger.LogDebug($"设置缓存{key}:{JsonSerializer.Serialize(value)}"); + + if (value == null) + { + Memory.Remove(key); + } + else + { + Memory.Set(key, value, ttl); + } + + return Task.CompletedTask; + } + + public Task BatchSet(Dictionary values, int ttl = -1) + { + Logger.LogDebug($"批量设置缓存:{JsonSerializer.Serialize(values)}"); + + Memory.SetAll(values, ttl); + + return Task.CompletedTask; + } + + public Task Get(string key) + { + Logger.LogDebug($"读取缓存{key}"); + + T Result = Memory.Get(key); + + Logger.LogDebug($"{JsonSerializer.Serialize(Result)}"); + + return Task.FromResult(Result); + } + + public Task> BatchGet(IEnumerable keys) + { + Logger.LogDebug("批量读取缓存"); + + Dictionary Result = (Dictionary)Memory.GetAll(keys); + + Logger.LogDebug($"{JsonSerializer.Serialize(Result)}"); + + return Task.FromResult(Result); + } + + public Task Delete(string key) + { + Logger.LogDebug($"删除缓存{key}"); + + Memory.Remove(key); + + return Task.CompletedTask; + } + + public Task BatchDelete(params string[] keys) + { + Logger.LogDebug($"批量删除缓存{JsonSerializer.Serialize(keys)}"); + + Memory.Remove(keys); + + return Task.CompletedTask; + } + + public Task> Query(string query, int count = 9999) + { + Logger.LogDebug($"查询缓存{query}"); + + var Keys = Memory.Keys.Where(x => x.Contains(query)); + + var Result = new Dictionary(); + + if (Keys.Count() > 0) + { + Result = (Dictionary)Memory.GetAll(Keys); + } + + Logger.LogDebug($"查询缓存{query}:{JsonSerializer.Serialize(Result)}"); + + return Task.FromResult(Result); + } + } +} diff --git a/Cache/CacheService/RedisCacheService.cs b/Cache/CacheService/RedisCacheService.cs new file mode 100644 index 0000000..cd73964 --- /dev/null +++ b/Cache/CacheService/RedisCacheService.cs @@ -0,0 +1,123 @@ +using CacheInterface; +using Google.Api; +using Google.Protobuf.WellKnownTypes; +using Microsoft.AspNetCore.DataProtection.KeyManagement; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NewLife.Caching; +using Newtonsoft.Json.Linq; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace CacheService +{ + public class RedisCacheService : ICacheService + { + public RedisCacheService(IServiceProvider services, string url) + { + Services = services; + + Logger = Services.GetRequiredService>(); + + Redis = new FullRedis(); + + Redis.Init(url); + + Logger.LogDebug("加载Redis缓存服务"); + } + + private readonly IServiceProvider Services; + + private readonly ILogger Logger; + + private readonly FullRedis Redis; + + public Task Set(string key, T value, int ttl = -1) + { + Logger.LogDebug($"设置缓存{key}:{JsonSerializer.Serialize(value)}"); + + if (value == null) + { + Redis.Remove(key); + } + else + { + Redis.Set(key, value, ttl); + } + + return Task.CompletedTask; + } + + public Task BatchSet(Dictionary values, int ttl = -1) + { + Logger.LogDebug($"批量设置缓存:{JsonSerializer.Serialize(values)}"); + + Redis.SetAll(values, ttl); + + return Task.CompletedTask; + } + + public Task Get(string key) + { + Logger.LogDebug($"读取缓存{key}"); + + T Result = Redis.Get(key); + + Logger.LogDebug($"{JsonSerializer.Serialize(Result)}"); + + return Task.FromResult(Result); + } + + public Task> BatchGet(IEnumerable keys) + { + Logger.LogDebug("批量读取缓存"); + + Dictionary Result = (Dictionary)Redis.GetAll(keys); + + Logger.LogDebug($"{JsonSerializer.Serialize(Result)}"); + + return Task.FromResult(Result); + } + + public Task Delete(string key) + { + Logger.LogDebug($"删除缓存{key}"); + + Redis.Remove(key); + + return Task.CompletedTask; + } + + public Task BatchDelete(params string[] keys) + { + Logger.LogDebug($"批量删除缓存{JsonSerializer.Serialize(keys)}"); + + Redis.Remove(keys); + + return Task.CompletedTask; + } + + public Task> Query(string query, int count = 9999) + { + Logger.LogDebug($"查询缓存{query}"); + + var Keys = Redis.Search(query, count); + + var Result = new Dictionary(); + + if (Keys.Count() > 0) + { + Result = (Dictionary)Redis.GetAll(Keys); + } + + Logger.LogDebug($"查询缓存{query}:{JsonSerializer.Serialize(Result)}"); + + return Task.FromResult(Result); + } + } +} diff --git a/CommonExtend/ByteBufferExtend.cs b/CommonExtend/ByteBufferExtend.cs new file mode 100644 index 0000000..918afef --- /dev/null +++ b/CommonExtend/ByteBufferExtend.cs @@ -0,0 +1,61 @@ +using DotNetty.Buffers; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonExtend +{ + public static class ByteBufferExtend + { + public static string ReadHex(this IByteBuffer buffer, int length) + { + IByteBuffer Temp = Unpooled.Buffer(length); + buffer.ReadBytes(Temp, length); + var Result = Temp.Array.Byte2HexString(); + Temp.Clear(); + return Result; + } + + public static void WriteHex(this IByteBuffer buffer, string value,int length) + { + var Temp = value.HexString2Byte().BytePadLeft(length); + buffer.WriteBytes(Temp); + } + + public static int ReadInt(this IByteBuffer buffer, int length) + { + IByteBuffer Temp = Unpooled.Buffer(length); + buffer.ReadBytes(Temp, length); + var Result = Temp.Array.Byte2Int(); + Temp.Clear(); + return Result; + } + + public static void WriteInt(this IByteBuffer buffer, int value,int length) { + var Temp = value.Int2Byte().BytePadLeft(length); + buffer.WriteBytes(Temp); + } + + public static int[] ReadBitArray(this IByteBuffer buffer) + { + IByteBuffer Temp = Unpooled.Buffer(1); + buffer.ReadBytes(Temp, 1); + var Temp1 = Temp.Array.Byte2BitArray(); + var Result = new int[] { + Temp1[0]?1:0, + Temp1[1]?1:0, + Temp1[2]?1:0, + Temp1[3]?1:0, + Temp1[4]?1:0, + Temp1[5]?1:0, + Temp1[6]?1:0, + Temp1[7]?1:0 + }; + Temp.Clear(); + return Result; + } + } +} diff --git a/CommonExtend/ByteExtend.cs b/CommonExtend/ByteExtend.cs new file mode 100644 index 0000000..7538084 --- /dev/null +++ b/CommonExtend/ByteExtend.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace CommonExtend +{ + /// + /// 字节扩展方法 + /// + public static class ByteExtend + { + /// + /// 字节数组转16进制字符串:空格分隔 + /// + /// + /// + public static string Byte2HexString(this byte[] byteDatas) + { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < byteDatas.Length; i++) + { + builder.Append(string.Format("{0:X2}", byteDatas[i])); + } + return builder.ToString().Trim(); + } + + /// + /// Hex字符串转Byte数组 + /// + /// 字符串 + /// + public static byte[] HexString2Byte(this string hex) + { + var inputByteArray = new byte[hex.Length / 2]; + for (var x = 0; x < inputByteArray.Length; x++) + { + var i = Convert.ToInt32(hex.Substring(x * 2, 2), 16); + inputByteArray[x] = (byte)i; + } + return inputByteArray; + } + + public static int Byte2HexSum(this byte[] byteDatas) + { + var Sum = 0; + foreach (var byteData in byteDatas) + { + Sum += new byte[] { byteData }.Byte2HexString().Hex2Int(); + } + return Sum; + } + + /// + /// 字节byte 转int + /// + /// + /// + public static int Byte2Int(this byte[] data) + { + if (data.Length <= 1) + { + data = data.BytePadLeft(2); + } + if (BitConverter.IsLittleEndian) + Array.Reverse(data); + return BitConverter.ToUInt16(data, 0); + } + + /// + /// 字节byte 转int + /// + /// + /// + public static byte[] Int2Byte(this int data) + { + var Temp = BitConverter.GetBytes(data); + + if (BitConverter.IsLittleEndian) + Array.Reverse(Temp); + + return Temp; + } + + /// + /// 字节byte 转string + /// + /// 字节数组 + /// + public static string Byte2String(this byte[] data) + { + return System.Text.Encoding.UTF8.GetString(data); + } + + /// + /// 字符串转byte数组 + /// + /// 字符串 + /// + public static byte[] String2Byte(this string data) + { + return System.Text.Encoding.UTF8.GetBytes(data); + } + + /// + /// 字节byte 转bit数组 + /// + /// 字节数组 + /// + public static BitArray Byte2BitArray(this byte[] data) + { + return new BitArray(data); + } + + /// + /// 字节byte 转bit数组 + /// + /// 字节数组 + /// + public static int Byte2Bit(this byte[] data, short index) + { + var _Bits = new BitArray(data); + return _Bits[index] ? 1 : 0; + } + + public static byte[] BitArray2Byte(this BitArray bitArray) + { + bitArray.Length = 8; + byte[] Temp = new byte[1]; + bitArray.CopyTo(Temp, 0); + return Temp; + } + + public static byte[] BitArray2Byte(this int[] bitArray) + { + BitArray bitArray1 = new BitArray(new bool[] { + Convert.ToBoolean(bitArray[0]), + Convert.ToBoolean(bitArray[1]), + Convert.ToBoolean(bitArray[2]), + Convert.ToBoolean(bitArray[3]), + Convert.ToBoolean(bitArray[4]), + Convert.ToBoolean(bitArray[5]), + Convert.ToBoolean(bitArray[6]), + Convert.ToBoolean(bitArray[7]) + }); + return BitArray2Byte(bitArray1); + } + + public static int[] Int2Bit(this int data, int length) + { + string Temp = Convert.ToString(data, 2).PadLeft(length, '0'); + int[] Temp1 = new int[length]; + for (var i = 0; i < length; i++) + { + Temp1[i] = Convert.ToInt32(Temp.Substring(i, 1)); + } + return Temp1; + } + + /// + /// 根据长度补全字节数组 + /// + /// 字节数组 + /// 长度 + /// + public static byte[] BytePadLeft(this IEnumerable data, int length) + { + var _List = data.ToList(); + if (_List.Count < length) + { + for (var i = 0; i < length - data.Count(); i++) + { + _List.Insert(0, new byte()); + } + } + else if (_List.Count > length) + { + for (var i = 0; i < data.Count() - length; i++) + { + _List.RemoveAt(0); + } + } + return _List.ToArray(); + } + } +} diff --git a/CommonExtend/CommonExtend.csproj b/CommonExtend/CommonExtend.csproj new file mode 100644 index 0000000..3fd5d18 --- /dev/null +++ b/CommonExtend/CommonExtend.csproj @@ -0,0 +1,14 @@ + + + + net7.0 + enable + enable + + + + + + + + diff --git a/CommonExtend/DaprExtend.cs b/CommonExtend/DaprExtend.cs new file mode 100644 index 0000000..2070928 --- /dev/null +++ b/CommonExtend/DaprExtend.cs @@ -0,0 +1,28 @@ +using Dapr.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonExtend +{ + public static class DaprExtend + { + public static bool Completed = false; + + public static Task WaitComplete(this DaprClient daprClient) { + while (!daprClient.CheckHealthAsync().Result) { + Thread.Sleep(1000); + } + daprClient.WaitForSidecarAsync().Wait(); + if (Completed) + { + return Task.CompletedTask; + } + Thread.Sleep(3000); + Completed = true; + return Task.CompletedTask; + } + } +} diff --git a/CommonExtend/StringExtend.cs b/CommonExtend/StringExtend.cs new file mode 100644 index 0000000..24f7937 --- /dev/null +++ b/CommonExtend/StringExtend.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonExtend +{ + public static class StringExtend + { + public static int Hex2Int(this string data) + { + return Convert.ToInt32(data, 16); + } + } +} diff --git a/CommonModel/BadRequestException.cs b/CommonModel/BadRequestException.cs new file mode 100644 index 0000000..68b46a1 --- /dev/null +++ b/CommonModel/BadRequestException.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonModel +{ + public class BadRequestException: Exception + { + public BadRequestException(string message) : base(message) { + + + } + } +} diff --git a/CommonModel/CommonModel.csproj b/CommonModel/CommonModel.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/CommonModel/CommonModel.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/CommonModel/PageBase.cs b/CommonModel/PageBase.cs new file mode 100644 index 0000000..940b994 --- /dev/null +++ b/CommonModel/PageBase.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonModel +{ + public class PageBase + { + /// + /// 分页下标 + /// + public int Index = 1; + + /// + /// 分页大小 + /// + public int Size = 20; + } +} diff --git a/CommonModel/PageData.cs b/CommonModel/PageData.cs new file mode 100644 index 0000000..a61e74e --- /dev/null +++ b/CommonModel/PageData.cs @@ -0,0 +1,23 @@ +namespace CommonModel +{ + public class PageData : PageBase + { + /// + /// 结果条目合计 + /// + public int Total { get; set; } + + /// + /// 分页数据 + /// + public List? Data { get; set; } + } + + public class PageData : PageData + { + /// + /// 分页数据 + /// + public new List? Data { get; set; } + } +} \ No newline at end of file diff --git a/CommonModel/PageSearch.cs b/CommonModel/PageSearch.cs new file mode 100644 index 0000000..984440e --- /dev/null +++ b/CommonModel/PageSearch.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonModel +{ + public class PageSearch : PageBase + { + /// + /// 统一查询 + /// + public string? Search { get; set; } + + /// + /// 开始日期 + /// + public DateTime? StartDate { get; set; } + + /// + /// 结束日期 + /// + public DateTime? EndDate { get; set; } + } + + public class PageSearch : PageSearch + { + /// + /// 查询条件 + /// + public T? Mode { get; set; } + } + + public class PageDaySearch : PageSearch { + public PageDaySearch() + { + var DateNow = DateTime.Now; + if (StartDate == null && EndDate == null) + { + StartDate = DateTime.Today; + + EndDate = DateNow; + } + else if (StartDate == null) + { + StartDate = DateTime.Today; + } + else if (EndDate == null) + { + EndDate = DateNow; + } + } + } + + public class PageDaySearch : PageDaySearch { + /// + /// 查询条件 + /// + public T? Mode { get; set; } + } + + public class PageMonthSearch : PageSearch + { + public PageMonthSearch() + { + var DateNow = DateTime.Now; + if (StartDate == null && EndDate == null) + { + StartDate = DateNow.AddMonths(-1); + + EndDate = DateNow; + } + else if (StartDate == null) + { + StartDate = DateNow.AddMonths(-1); + } + else if (EndDate == null) + { + EndDate = DateNow; + } + } + } + + public class PageMonthSearch : PageMonthSearch + { + /// + /// 查询条件 + /// + public T? Mode { get; set; } + } + + public class PageYearSearch : PageSearch + { + public PageYearSearch() + { + var DateNow = DateTime.Now; + if (StartDate == null && EndDate == null) + { + StartDate = DateNow.AddYears(-1); + + EndDate = DateNow; + } + else if (StartDate == null) + { + StartDate = DateNow.AddYears(-1); + } + else if (EndDate == null) + { + EndDate = DateNow; + } + } + } + + public class PageYearSearch : PageYearSearch + { + /// + /// 查询条件 + /// + public T? Mode { get; set; } + } +} diff --git a/CommonModel/Properties/launchSettings.json b/CommonModel/Properties/launchSettings.json new file mode 100644 index 0000000..36887e4 --- /dev/null +++ b/CommonModel/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "CommonModel": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:64279;http://localhost:64282" + } + } +} \ No newline at end of file diff --git a/CommonModel/SplitDateId.cs b/CommonModel/SplitDateId.cs new file mode 100644 index 0000000..772ab44 --- /dev/null +++ b/CommonModel/SplitDateId.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CommonModel +{ + public class SplitDateId + { + /// + /// 开始日期 + /// + public DateTime StartDate { get; set; } + + /// + /// 结束日期 + /// + public DateTime EndDate { get; set; } + + public SplitDateId(string id, int index) { + StartDate = new DateTime(int.Parse(id.Substring(index, 4)), int.Parse(id.Substring(index + 4, 2)), int.Parse(id.Substring(index + 6, 2)), 0, 0, 0); + EndDate = new DateTime(int.Parse(id.Substring(index, 4)), int.Parse(id.Substring(index + 4, 2)), int.Parse(id.Substring(index + 6, 2)), 23, 59, 59); + } + } +} diff --git a/Dapr/Components/pubsub-rabbitmq.yaml b/Dapr/Components/pubsub-rabbitmq.yaml new file mode 100644 index 0000000..3c031b7 --- /dev/null +++ b/Dapr/Components/pubsub-rabbitmq.yaml @@ -0,0 +1,30 @@ +# 本地测试请修改hosts文件 +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: rabbitmq-pubsub +spec: + type: pubsub.rabbitmq + version: v1 + metadata: + # rabbitmq地址 + - name: host + value: "amqp://rabbitmq:5672" + # 消息持久化 + - name: durable + value: "true" + # 是否自动删除 + - name: deletedWhenUnused + value: "false" + # 持久模型 + - name: deliveryMode + value: "2" + # 预提消息数 + - name: prefetchCount + value: "10" + # 重试等待时间 + - name: reconnectWait + value: "3" + # 并行处理 + - name: concurrencyMode + value: parallel \ No newline at end of file diff --git a/Dapr/Components/pubsub-redis.yaml b/Dapr/Components/pubsub-redis.yaml new file mode 100644 index 0000000..8881b02 --- /dev/null +++ b/Dapr/Components/pubsub-redis.yaml @@ -0,0 +1,13 @@ +# 本地测试请修改hosts文件 +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: redis-pubsub +spec: + type: pubsub.redis + version: v1 + metadata: + - name: redisHost + value: redis:6379 + - name: redisPassword + value: "" diff --git a/Dapr/Components/statestore.yaml b/Dapr/Components/statestore.yaml new file mode 100644 index 0000000..feb0f72 --- /dev/null +++ b/Dapr/Components/statestore.yaml @@ -0,0 +1,20 @@ +# 本地测试请修改hosts文件 +apiVersion: dapr.io/v1alpha1 +kind: Component +metadata: + name: statestore +spec: + type: state.redis + version: v1 + metadata: + - name: redisHost + value: redis:6379 + - name: redisPassword + value: "" + - name: actorStateStore + value: "true" + - name: keyPrefix + value: None + # - 这是默认策略。 带有appid前缀的状态仅允许具有指定appid的应用程序管理。 所有的状态键都会以appid为前缀,并对应用进行限定。 + # name - 此设置使用状态存储组件的名称作为前缀。 对于一个给定的状态存储,多个应用程序可以共享同一个状态。 + # none - 此设置不使用前缀。 多个应用程序在不同的状态存储中共享状态。 diff --git a/Dapr/config.yaml b/Dapr/config.yaml new file mode 100644 index 0000000..37231da --- /dev/null +++ b/Dapr/config.yaml @@ -0,0 +1,10 @@ +# 本地测试请修改hosts文件 +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: daprConfig +spec: + tracing: + samplingRate: "1" + zipkin: + endpointAddress: http://zipkin:9411/api/v2/spans diff --git a/DockerCompose/docker-compose-all.yml b/DockerCompose/docker-compose-all.yml new file mode 100644 index 0000000..3fb2a2c --- /dev/null +++ b/DockerCompose/docker-compose-all.yml @@ -0,0 +1,379 @@ +version: '3.4' + +services: + # Dapr Actor 服务 + placement: + container_name: placement + hostname: placement + image: "daprio/dapr:1.9.5" + restart: always + command: ["./placement", "-port", "6050"] + networks: + - fy + + # Dapr zipkin 检测 + zipkin: + container_name: zipkin + hostname: zipkin + image: "openzipkin/zipkin:2.23.19" + restart: always + ports: + - "9411:9411" + networks: + - fy + + gateway: + # container_name: gateway + image: "gateway:latest" + restart: always + # 端口映射 + ports: + - "5330:5330" + # 应用启动时的地址 + environment: + - "ASPNETCORE_URLS=http://*:5330;" + depends_on: + - placement + - zipkin + networks: + - fy + - mq + - cache + - db + + gateway-dapr: + image: "daprio/daprd:1.9.5" + # restart: always + command: [ "./daprd", "-app-id", "gateway", + # 应用端口号 + "-app-port", "5330" , + "-dapr-http-port","6330", + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + depends_on: + - gateway + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:gateway" + + auth: + # container_name: zhonglian + image: "auth:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + # environment: + # - "ASPNETCORE_URLS=http://*:8081;" + depends_on: + - placement + - zipkin + #volumes: + # - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" + networks: + - fy + - mq + - cache + - db + + auth-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "auth", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - auth + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:auth" + + crm: + # container_name: zhonglian + image: "crm:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + # environment: + # - "ASPNETCORE_URLS=http://*:8081;" + depends_on: + - placement + - zipkin + #volumes: + # - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" + networks: + - fy + - mq + - cache + - db + + crm-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "crm", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - crm + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:crm" + + drive: + # container_name: zhonglian + image: "drive:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + # environment: + # - "ASPNETCORE_URLS=http://*:8081;" + depends_on: + - placement + - zipkin + #volumes: + # - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" + networks: + - fy + - mq + - cache + - db + + drive-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "drive", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - drive + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:drive" + + tprz: + # container_name: zhonglian + image: "tprz:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + # environment: + # - "ASPNETCORE_URLS=http://*:8081;" + depends_on: + - placement + - zipkin + #volumes: + # - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" + networks: + - fy + - mq + - cache + - db + + tprz-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "tprz", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - tprz + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:tprz" + + wms: + # container_name: zhonglian + image: "wms:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + # environment: + # - "ASPNETCORE_URLS=http://*:8081;" + depends_on: + - placement + - zipkin + #volumes: + # - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" + networks: + - fy + - mq + - cache + - db + + wms-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "wms", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - wms + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:wms" + + bw: + # container_name: zhonglian + image: "bw:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + # environment: + # - "ASPNETCORE_URLS=http://*:8081;" + depends_on: + - placement + - zipkin + #volumes: + # - "/usr/share/zoneinfo/Asia/Shanghai:/etc/localtime" + networks: + - fy + - mq + - cache + - db + + bw-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "bw", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - bw + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:bw" + + zhonglian: + # container_name: zhonglian + image: "zhonglian:latest" + restart: always + # 端口映射 + # ports: + # - "5027:80" + # 应用启动时的地址 + depends_on: + - placement + - zipkin + networks: + - fy + - mq + - cache + - db + + zhonglian-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "zhonglian", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - zhonglian + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:zhonglian" + + lansheng: + image: "lansheng:latest" + restart: always + # 端口映射 + ports: + - "9001:9001" + + networks: + - fy + - mq + - cache + - db + + lansheng-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "lansheng", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - lansheng + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:lansheng" + +networks: + fy: + db: + external: true + mq: + external: true + cache: + external: true \ No newline at end of file diff --git a/DockerCompose/docker-compose-dev.yml b/DockerCompose/docker-compose-dev.yml new file mode 100644 index 0000000..9748cb5 --- /dev/null +++ b/DockerCompose/docker-compose-dev.yml @@ -0,0 +1,103 @@ +version: '3.4' + +services: + # Dapr Actor 服务 + placement: + container_name: placement + hostname: placement + image: "daprio/dapr:1.9.5" + restart: always + command: ["./placement", "-port", "6050"] + networks: + - fy + + # Dapr zipkin 检测 + zipkin: + container_name: zipkin + hostname: zipkin + image: "openzipkin/zipkin:2.23.19" + restart: always + ports: + - "9411:9411" + networks: + - fy + + gateway: + # container_name: gateway + image: "gateway:latest" + restart: always + # 端口映射 + ports: + - "5330:5330" + # 应用启动时的地址 + environment: + - "ASPNETCORE_URLS=http://*:5330;" + depends_on: + - placement + - zipkin + networks: + - fy + - mq + - cache + - db + + gateway-dapr: + image: "daprio/daprd:1.9.5" + # restart: always + command: [ "./daprd", "-app-id", "gateway", + # 应用端口号 + "-app-port", "5330" , + "-dapr-http-port","6330", + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + depends_on: + - gateway + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:gateway" + + lansheng: + image: "lansheng:latest" + restart: always + # 端口映射 + ports: + - "9001:9001" + + networks: + - fy + - mq + - cache + - db + + lansheng-dapr: + image: "daprio/daprd:1.9.5" + restart: always + command: [ "./daprd", "-app-id", "lansheng", + # 应用端口号 + "-app-port", "80" , + "-placement-host-address","placement:6050", + # dapr 配置文件 + "-config","/Dapr/config.yaml", + # dapr 组件 + "-components-path", "/Dapr/Components"] + # 数据持久化 - [卷标名称]:/var/lib/mysql 或者 - [直接使用宿主机的本地路径]:/var/lib/mysql + depends_on: + - lansheng + volumes: + - "../Dapr:/Dapr" + # 工作模型:绑定边车匹配的应用服务名 + network_mode: "service:lansheng" + +networks: + fy: + db: + external: true + mq: + external: true + cache: + external: true \ No newline at end of file diff --git a/DockerCompose/docker-compose-env.yml b/DockerCompose/docker-compose-env.yml new file mode 100644 index 0000000..6eea087 --- /dev/null +++ b/DockerCompose/docker-compose-env.yml @@ -0,0 +1,60 @@ +version: '3.4' + +services: + # Dapr Actor 服务 + redis: + container_name: redis + hostname: redis + image: "redis:6" + restart: always + ports: + - 6379:6379 + environment: + TZ: Asia/Shanghai + volumes: + - ../Redis/redis.conf:/etc/redis/redis.conf + - ../Redis/data:/data + - ../Redis/logs:/logs + command: ["redis-server","/etc/redis/redis.conf"] + networks: + - cache + + rabbitmq: + container_name: rabbitmq + hostname: rabbitmq + image: "rabbitmq:3.9.26-management" + restart: always + ports: + - 5672:5672 + - 15672:15672 + environment: + TZ: Asia/Shanghai + networks: + - mq + + mysql: + container_name: mysql + hostname: mysql + image: "mysql:8" + restart: always + ports: + - 3306:3306 + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: lsdb + TZ: Asia/Shanghai + volumes: + - ../MySQL/Data:/var/lib/mysql + - ../Mysql/Conf:/etc/mysql/conf.d/ + command: + --lower_case_table_names=1 + networks: + - db + +networks: + db: + external: true + mq: + external: true + cache: + external: true \ No newline at end of file diff --git a/FYCore.sln b/FYCore.sln new file mode 100644 index 0000000..a99e92c --- /dev/null +++ b/FYCore.sln @@ -0,0 +1,140 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33213.308 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ZhongLian", "ZhongLian", "{1FC51DED-0F42-4590-8FBA-ABCDDA960DFF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZhongLianAPI", "ZhongLian\ZhongLianAPI\ZhongLianAPI.csproj", "{6CB326C0-7C4F-404B-9CCC-6DCAFF907934}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZhongLianService", "ZhongLian\ZhongLianService\ZhongLianService.csproj", "{9E0013B1-441E-436A-B162-CF563E420391}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZhongLianModel", "ZhongLian\ZhongLianModel\ZhongLianModel.csproj", "{726BDE65-C3DC-498A-AFFD-9A35870BF573}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonModel", "CommonModel\CommonModel.csproj", "{19193040-09A6-4B46-9BDA-9A8482A2E6E6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DockerCompose", "DockerCompose", "{AE411252-D6A9-4242-B67A-73D3FCB54778}" + ProjectSection(SolutionItems) = preProject + DockerCompose\docker-compose-all.yml = DockerCompose\docker-compose-all.yml + DockerCompose\docker-compose-dev.yml = DockerCompose\docker-compose-dev.yml + DockerCompose\docker-compose-env.yml = DockerCompose\docker-compose-env.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dapr", "Dapr", "{C9A49A38-F460-428D-9580-E810EA00F4E8}" + ProjectSection(SolutionItems) = preProject + Dapr\config.yaml = Dapr\config.yaml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Components", "Components", "{F65F5C2A-33B2-48D9-B4B0-14C455FE4C64}" + ProjectSection(SolutionItems) = preProject + Dapr\Components\pubsub-rabbitmq.yaml = Dapr\Components\pubsub-rabbitmq.yaml + Dapr\Components\pubsub-redis.yaml = Dapr\Components\pubsub-redis.yaml + Dapr\Components\statestore.yaml = Dapr\Components\statestore.yaml + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GatewayAPI", "GatewayAPI\GatewayAPI.csproj", "{56EB64A2-F37F-4AE0-B63B-60C1E37FA7BE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Redis", "Redis", "{8C4F2BD0-8150-4812-8586-58367CD78B58}" + ProjectSection(SolutionItems) = preProject + Redis\redis.conf = Redis\redis.conf + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonExtend", "CommonExtend\CommonExtend.csproj", "{FA95FA55-08F7-45A3-BFAD-177D36444024}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZhongLianInterface", "ZhongLian\ZhongLianInterface\ZhongLianInterface.csproj", "{D14C3E63-AA5A-45AA-BB8F-A9F3629A4839}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LanSheng", "LanSheng", "{32BDB007-D878-44E8-8AE2-1F9883DC1F0C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cache", "Cache", "{B2F2732F-074B-45AA-AFA4-A15C24A44E6C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CacheService", "Cache\CacheService\CacheService.csproj", "{592A8FEE-B09E-4A58-B56A-DFF2106A5A40}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CacheInterface", "Cache\CacheInterface\CacheInterface.csproj", "{4CC3E08E-C392-4584-BAD8-D686B366EF6D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanShengAPI", "LanSheng\LanShengAPI\LanShengAPI.csproj", "{75DF5305-9570-4B5A-8EA7-A9E221A5AFC5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanShengService", "LanSheng\LanShengService\LanShengService.csproj", "{518B59A4-7FE1-49DB-90D4-795B7A5FB59D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanShengInterface", "LanSheng\LanShengInterface\LanShengInterface.csproj", "{E201C20A-D557-4E11-AC62-1DFCDB3FD434}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanShengModel", "LanSheng\LanShengModel\LanShengModel.csproj", "{F1FA7228-55A8-4D7A-A10C-1180AB5F3A70}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6CB326C0-7C4F-404B-9CCC-6DCAFF907934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CB326C0-7C4F-404B-9CCC-6DCAFF907934}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CB326C0-7C4F-404B-9CCC-6DCAFF907934}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CB326C0-7C4F-404B-9CCC-6DCAFF907934}.Release|Any CPU.Build.0 = Release|Any CPU + {9E0013B1-441E-436A-B162-CF563E420391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E0013B1-441E-436A-B162-CF563E420391}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E0013B1-441E-436A-B162-CF563E420391}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E0013B1-441E-436A-B162-CF563E420391}.Release|Any CPU.Build.0 = Release|Any CPU + {726BDE65-C3DC-498A-AFFD-9A35870BF573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {726BDE65-C3DC-498A-AFFD-9A35870BF573}.Debug|Any CPU.Build.0 = Debug|Any CPU + {726BDE65-C3DC-498A-AFFD-9A35870BF573}.Release|Any CPU.ActiveCfg = Release|Any CPU + {726BDE65-C3DC-498A-AFFD-9A35870BF573}.Release|Any CPU.Build.0 = Release|Any CPU + {19193040-09A6-4B46-9BDA-9A8482A2E6E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19193040-09A6-4B46-9BDA-9A8482A2E6E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19193040-09A6-4B46-9BDA-9A8482A2E6E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19193040-09A6-4B46-9BDA-9A8482A2E6E6}.Release|Any CPU.Build.0 = Release|Any CPU + {56EB64A2-F37F-4AE0-B63B-60C1E37FA7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56EB64A2-F37F-4AE0-B63B-60C1E37FA7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56EB64A2-F37F-4AE0-B63B-60C1E37FA7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56EB64A2-F37F-4AE0-B63B-60C1E37FA7BE}.Release|Any CPU.Build.0 = Release|Any CPU + {FA95FA55-08F7-45A3-BFAD-177D36444024}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA95FA55-08F7-45A3-BFAD-177D36444024}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA95FA55-08F7-45A3-BFAD-177D36444024}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA95FA55-08F7-45A3-BFAD-177D36444024}.Release|Any CPU.Build.0 = Release|Any CPU + {D14C3E63-AA5A-45AA-BB8F-A9F3629A4839}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D14C3E63-AA5A-45AA-BB8F-A9F3629A4839}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D14C3E63-AA5A-45AA-BB8F-A9F3629A4839}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D14C3E63-AA5A-45AA-BB8F-A9F3629A4839}.Release|Any CPU.Build.0 = Release|Any CPU + {592A8FEE-B09E-4A58-B56A-DFF2106A5A40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {592A8FEE-B09E-4A58-B56A-DFF2106A5A40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {592A8FEE-B09E-4A58-B56A-DFF2106A5A40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {592A8FEE-B09E-4A58-B56A-DFF2106A5A40}.Release|Any CPU.Build.0 = Release|Any CPU + {4CC3E08E-C392-4584-BAD8-D686B366EF6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4CC3E08E-C392-4584-BAD8-D686B366EF6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CC3E08E-C392-4584-BAD8-D686B366EF6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4CC3E08E-C392-4584-BAD8-D686B366EF6D}.Release|Any CPU.Build.0 = Release|Any CPU + {75DF5305-9570-4B5A-8EA7-A9E221A5AFC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {75DF5305-9570-4B5A-8EA7-A9E221A5AFC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {75DF5305-9570-4B5A-8EA7-A9E221A5AFC5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {75DF5305-9570-4B5A-8EA7-A9E221A5AFC5}.Release|Any CPU.Build.0 = Release|Any CPU + {518B59A4-7FE1-49DB-90D4-795B7A5FB59D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {518B59A4-7FE1-49DB-90D4-795B7A5FB59D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {518B59A4-7FE1-49DB-90D4-795B7A5FB59D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {518B59A4-7FE1-49DB-90D4-795B7A5FB59D}.Release|Any CPU.Build.0 = Release|Any CPU + {E201C20A-D557-4E11-AC62-1DFCDB3FD434}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E201C20A-D557-4E11-AC62-1DFCDB3FD434}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E201C20A-D557-4E11-AC62-1DFCDB3FD434}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E201C20A-D557-4E11-AC62-1DFCDB3FD434}.Release|Any CPU.Build.0 = Release|Any CPU + {F1FA7228-55A8-4D7A-A10C-1180AB5F3A70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1FA7228-55A8-4D7A-A10C-1180AB5F3A70}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1FA7228-55A8-4D7A-A10C-1180AB5F3A70}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1FA7228-55A8-4D7A-A10C-1180AB5F3A70}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {6CB326C0-7C4F-404B-9CCC-6DCAFF907934} = {1FC51DED-0F42-4590-8FBA-ABCDDA960DFF} + {9E0013B1-441E-436A-B162-CF563E420391} = {1FC51DED-0F42-4590-8FBA-ABCDDA960DFF} + {726BDE65-C3DC-498A-AFFD-9A35870BF573} = {1FC51DED-0F42-4590-8FBA-ABCDDA960DFF} + {F65F5C2A-33B2-48D9-B4B0-14C455FE4C64} = {C9A49A38-F460-428D-9580-E810EA00F4E8} + {D14C3E63-AA5A-45AA-BB8F-A9F3629A4839} = {1FC51DED-0F42-4590-8FBA-ABCDDA960DFF} + {592A8FEE-B09E-4A58-B56A-DFF2106A5A40} = {B2F2732F-074B-45AA-AFA4-A15C24A44E6C} + {4CC3E08E-C392-4584-BAD8-D686B366EF6D} = {B2F2732F-074B-45AA-AFA4-A15C24A44E6C} + {75DF5305-9570-4B5A-8EA7-A9E221A5AFC5} = {32BDB007-D878-44E8-8AE2-1F9883DC1F0C} + {518B59A4-7FE1-49DB-90D4-795B7A5FB59D} = {32BDB007-D878-44E8-8AE2-1F9883DC1F0C} + {E201C20A-D557-4E11-AC62-1DFCDB3FD434} = {32BDB007-D878-44E8-8AE2-1F9883DC1F0C} + {F1FA7228-55A8-4D7A-A10C-1180AB5F3A70} = {32BDB007-D878-44E8-8AE2-1F9883DC1F0C} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9BB66DA6-6F98-49BB-BC0B-FB09B4CC7C05} + EndGlobalSection +EndGlobal diff --git a/GatewayAPI/.config/dotnet-tools.json b/GatewayAPI/.config/dotnet-tools.json new file mode 100644 index 0000000..6b93cca --- /dev/null +++ b/GatewayAPI/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "7.0.3", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/GatewayAPI/Dockerfile b/GatewayAPI/Dockerfile new file mode 100644 index 0000000..3b08e56 --- /dev/null +++ b/GatewayAPI/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 +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" >/etc/timezone +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["GatewayAPI/GatewayAPI.csproj", "GatewayAPI/"] +RUN dotnet restore "GatewayAPI/GatewayAPI.csproj" +COPY . . +WORKDIR "/src/GatewayAPI" +RUN dotnet build "GatewayAPI.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "GatewayAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "GatewayAPI.dll"] \ No newline at end of file diff --git a/GatewayAPI/GatewayAPI.csproj b/GatewayAPI/GatewayAPI.csproj new file mode 100644 index 0000000..d819032 --- /dev/null +++ b/GatewayAPI/GatewayAPI.csproj @@ -0,0 +1,20 @@ + + + + net6.0 + enable + enable + Linux + + + + + + + + + + + + + diff --git a/GatewayAPI/HostReplaceMiddleware.cs b/GatewayAPI/HostReplaceMiddleware.cs new file mode 100644 index 0000000..7d24703 --- /dev/null +++ b/GatewayAPI/HostReplaceMiddleware.cs @@ -0,0 +1,121 @@ +using Ocelot.Authentication.Middleware; +using Ocelot.Authorization.Middleware; +using Ocelot.Cache.Middleware; +using Ocelot.Claims.Middleware; +using Ocelot.DownstreamPathManipulation.Middleware; +using Ocelot.DownstreamRouteFinder.Middleware; +using Ocelot.DownstreamRouteFinder.UrlMatcher; +using Ocelot.DownstreamUrlCreator.Middleware; +using Ocelot.Errors.Middleware; +using Ocelot.Headers.Middleware; +using Ocelot.LoadBalancer.Middleware; +using Ocelot.Logging; +using Ocelot.Middleware; +using Ocelot.Multiplexer; +using Ocelot.QueryStrings.Middleware; +using Ocelot.RateLimit.Middleware; +using Ocelot.Request.Middleware; +using Ocelot.Requester.Middleware; +using Ocelot.RequestId.Middleware; +using Ocelot.Responder.Middleware; +using Ocelot.Security.Middleware; +using Ocelot.WebSockets.Middleware; + +namespace GatewayAPI +{ + public static class OcelotPipelineExtensions + { + public static RequestDelegate BuildOcelotPipeline(this IApplicationBuilder app, OcelotPipelineConfiguration pipelineConfiguration) + { + app.UseDownstreamContextMiddleware(); + app.UseExceptionHandlerMiddleware(); + app.MapWhen((HttpContext httpContext) => httpContext.WebSockets.IsWebSocketRequest, delegate (IApplicationBuilder wenSocketsApp) + { + wenSocketsApp.UseDownstreamRouteFinderMiddleware(); + wenSocketsApp.UseMultiplexingMiddleware(); + wenSocketsApp.UseDownstreamRequestInitialiser(); + wenSocketsApp.UseLoadBalancingMiddleware(); + wenSocketsApp.UseMiddleware(); + wenSocketsApp.UseDownstreamUrlCreatorMiddleware(); + wenSocketsApp.UseWebSocketsProxyMiddleware(); + }); + app.UseIfNotNull(pipelineConfiguration.PreErrorResponderMiddleware); + app.UseResponderMiddleware(); + app.UseDownstreamRouteFinderMiddleware(); + app.UseMultiplexingMiddleware(); + app.UseSecurityMiddleware(); + if (pipelineConfiguration.MapWhenOcelotPipeline != null) + { + foreach (KeyValuePair, Action> item in pipelineConfiguration.MapWhenOcelotPipeline) + { + app.MapWhen(item.Key, item.Value); + } + } + + app.UseHttpHeadersTransformationMiddleware(); + app.UseDownstreamRequestInitialiser(); + app.UseRateLimiting(); + app.UseRequestIdMiddleware(); + app.UseIfNotNull(pipelineConfiguration.PreAuthenticationMiddleware); + if (pipelineConfiguration.AuthenticationMiddleware == null) + { + app.UseAuthenticationMiddleware(); + } + else + { + app.Use(pipelineConfiguration.AuthenticationMiddleware); + } + + app.UseClaimsToClaimsMiddleware(); + app.UseIfNotNull(pipelineConfiguration.PreAuthorizationMiddleware); + if (pipelineConfiguration.AuthorizationMiddleware == null) + { + app.UseAuthorizationMiddleware(); + } + else + { + app.Use(pipelineConfiguration.AuthorizationMiddleware); + } + + app.UseClaimsToHeadersMiddleware(); + app.UseIfNotNull(pipelineConfiguration.PreQueryStringBuilderMiddleware); + app.UseClaimsToQueryStringMiddleware(); + app.UseClaimsToDownstreamPathMiddleware(); + app.UseLoadBalancingMiddleware(); + app.UseMiddleware(); + app.UseDownstreamUrlCreatorMiddleware(); + app.UseOutputCacheMiddleware(); + app.UseHttpRequesterMiddleware(); + return app.Build(); + } + + private static void UseIfNotNull(this IApplicationBuilder builder, Func, Task> middleware) + { + if (middleware != null) + { + builder.Use(middleware); + } + } + } + + public class HostReplaceMiddleware : OcelotMiddleware + { + private readonly RequestDelegate _next; + + public HostReplaceMiddleware(RequestDelegate next, IOcelotLoggerFactory loggerFactory) + : base(loggerFactory.CreateLogger()) + { + _next = next; + } + + public async Task Invoke(HttpContext httpContext) + { + DownstreamRequest downstreamRequest = httpContext.Items.DownstreamRequest(); + List list = httpContext.Items.TemplatePlaceholderNameAndValues(); + list.ForEach((v) => { + downstreamRequest.Host = downstreamRequest.Host.Replace(v.Name, v.Value); + }); + await _next(httpContext); + } + } +} diff --git a/GatewayAPI/Program.cs b/GatewayAPI/Program.cs new file mode 100644 index 0000000..da7a55e --- /dev/null +++ b/GatewayAPI/Program.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Ocelot.DependencyInjection; +using Ocelot.Middleware; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +#region Cors +builder.Services.AddCors(options => +{ + options.AddPolicy("all", builder => + { + builder.SetIsOriginAllowed(origin => true) //κԴ + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials();//ָcookie + }); +}); +#endregion +#region Body +builder.Services.Configure(options => +{ + options.Limits.MaxRequestBodySize = null;// +}); +builder.Services.Configure(options => +{ + options.MaxRequestBodySize = null;// +}); +builder.Services.Configure(x => +{ + x.ValueLengthLimit = int.MaxValue; + x.MultipartBodyLengthLimit = int.MaxValue; + x.MultipartHeadersLengthLimit = int.MaxValue; +}); +#endregion +builder.Services.AddOcelot(builder.Configuration); + +var app = builder.Build(); +#region Cors +app.UseCors("all"); +#endregion +app.UseWebSockets(); +app.UseOcelot((build, cfg) => +{ + build.BuildOcelotPipeline(cfg); +}).Wait(); +app.Run(); diff --git a/GatewayAPI/Properties/launchSettings.json b/GatewayAPI/Properties/launchSettings.json new file mode 100644 index 0000000..076d27e --- /dev/null +++ b/GatewayAPI/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "profiles": { + "GatewayAPI": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5080" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:16737", + "sslPort": 0 + } + } +} \ No newline at end of file diff --git a/GatewayAPI/appsettings.Development.json b/GatewayAPI/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/GatewayAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/GatewayAPI/appsettings.json b/GatewayAPI/appsettings.json new file mode 100644 index 0000000..fc333ab --- /dev/null +++ b/GatewayAPI/appsettings.json @@ -0,0 +1,88 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Routes": [ + { + "DownstreamPathTemplate": "/v1.0/invoke/{app}/method/api/{url}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": "6330" + } + ], + "UpstreamPathTemplate": "/{app}/api/{url}", + "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], + "Priority": 0 + }, + { + "DownstreamPathTemplate": "/v1.0/invoke/lansheng/method/api/device/{url}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": "6330" + } + ], + "UpstreamPathTemplate": "/ry/api/gpsdata/{url}", + "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], + "Priority": 1 + }, + { + "DownstreamPathTemplate": "/2WaoDPVQth.txt", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "tprz", + "Port": "80" + } + ], + "UpstreamPathTemplate": "/2WaoDPVQth.txt", + "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], + "Priority": 0 + }, + { + "DownstreamPathTemplate": "/Scanner.mp4", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "tprz", + "Port": "80" + } + ], + "UpstreamPathTemplate": "/Scanner.mp4", + "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], + "Priority": 0 + }, + { + "DownstreamPathTemplate": "/{target}/{device}/preview/{stream}", + "DownstreamScheme": "ws", + "DownstreamHostAndPorts": [ + { + "Host": "bw", + "Port": "80" + } + ], + "UpstreamPathTemplate": "/bw/{target}/{device}/preview/{stream}", + "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ] + }, + { + "DownstreamPathTemplate": "/{url}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": "5027" + } + ], + "UpstreamPathTemplate": "/zhonglian/{url}", + "UpstreamHttpMethod": [ "Get", "Post", "Put", "Delete" ], + "Priority": 10 + } + ] +} diff --git a/LanSheng/LanShengAPI/Controllers/DeviceController.cs b/LanSheng/LanShengAPI/Controllers/DeviceController.cs new file mode 100644 index 0000000..502d338 --- /dev/null +++ b/LanSheng/LanShengAPI/Controllers/DeviceController.cs @@ -0,0 +1,88 @@ +using CommonModel; +using LanShengInterface; +using LanShengModel; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace LanShengAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class DeviceController : ControllerBase + { + public DeviceController(IDeviceService deviceService, ITcpService tcpService) + { + TcpService = tcpService; + DeviceService = deviceService; + } + + private readonly ITcpService TcpService; + + private readonly IDeviceService DeviceService; + + [HttpPost("PushParams")] + public async Task PushParams(DeviceData deviceData) + { + try + { + await TcpService.PushParams(deviceData); + return Ok(); + } + catch (BadRequestException ex) + { + return BadRequest(ex.Message); + } + } + + [HttpGet("GetDeviceData")] + public async Task GetDeviceData([FromQuery] string id) + { + try + { + return Ok(await DeviceService.GetDeviceData(id)); + } + catch (BadRequestException ex) + { + return BadRequest(ex.Message); + } + } + + [HttpGet("ResetRunCount")] + public async Task ResetRunCount([FromQuery] string id) { + try + { + await DeviceService.ResetRunCount(id); + return Ok(); + } + catch (BadRequestException ex) + { + return BadRequest(ex.Message); + } + } + + [HttpPost("GetDeviceDatas")] + public async Task GetDeviceData(string[] ids) { + try + { + return Ok(await DeviceService.GetDeviceData(ids)); + } + catch (BadRequestException ex) + { + return BadRequest(ex.Message); + } + } + + [HttpPost("GetDeviceError")] + public async Task GetDeviceError(PageYearSearch page) + { + try + { + return Ok(await DeviceService.GetDeviceErrorPage(page)); + } + catch (BadRequestException ex) + { + return BadRequest(ex.Message); + } + } + } +} diff --git a/LanSheng/LanShengAPI/Dockerfile b/LanSheng/LanShengAPI/Dockerfile new file mode 100644 index 0000000..c810bdb --- /dev/null +++ b/LanSheng/LanShengAPI/Dockerfile @@ -0,0 +1,29 @@ +#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/aspnet:7.0 AS base +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" >/etc/timezone +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["LanSheng/LanShengAPI/LanShengAPI.csproj", "LanSheng/LanShengAPI/"] +COPY ["LanSheng/LanShengService/LanShengService.csproj", "LanSheng/LanShengService/"] +COPY ["Cache/CacheService/CacheService.csproj", "Cache/CacheService/"] +COPY ["CommonExtend/CommonExtend.csproj", "CommonExtend/"] +COPY ["Cache/CacheInterface/CacheInterface.csproj", "Cache/CacheInterface/"] +COPY ["CommonModel/CommonModel.csproj", "CommonModel/"] +COPY ["LanSheng/LanShengInterface/LanShengInterface.csproj", "LanSheng/LanShengInterface/"] +COPY ["LanSheng/LanShengModel/LanShengModel.csproj", "LanSheng/LanShengModel/"] +RUN dotnet restore "LanSheng/LanShengAPI/LanShengAPI.csproj" +COPY . . +WORKDIR "/src/LanSheng/LanShengAPI" +RUN dotnet build "LanShengAPI.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "LanShengAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "LanShengAPI.dll"] \ No newline at end of file diff --git a/LanSheng/LanShengAPI/LanShengAPI.csproj b/LanSheng/LanShengAPI/LanShengAPI.csproj new file mode 100644 index 0000000..6e20237 --- /dev/null +++ b/LanSheng/LanShengAPI/LanShengAPI.csproj @@ -0,0 +1,24 @@ + + + + net7.0 + enable + enable + Linux + ..\.. + + + + + + + + + + + + + + + + diff --git a/LanSheng/LanShengAPI/Program.cs b/LanSheng/LanShengAPI/Program.cs new file mode 100644 index 0000000..b690384 --- /dev/null +++ b/LanSheng/LanShengAPI/Program.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using LanShengService; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers().AddNewtonsoftJson(options => +{ + options.SerializerSettings.ContractResolver = new DefaultContractResolver(); + + options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; +}).AddDapr(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.InitLanShengService(builder.Configuration); +var app = builder.Build(); + +app.UseSwagger(); +app.UseSwaggerUI(); +app.UseHttpsRedirection(); +app.UseRouting(); +app.UseAuthorization(); +app.UseStaticFiles(); +app.MapControllers(); +app.CreateLanShengService(); +app.Run(); \ No newline at end of file diff --git a/LanSheng/LanShengAPI/Properties/launchSettings.json b/LanSheng/LanShengAPI/Properties/launchSettings.json new file mode 100644 index 0000000..ea34080 --- /dev/null +++ b/LanSheng/LanShengAPI/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5048" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:53288", + "sslPort": 0 + } + } +} \ No newline at end of file diff --git a/LanSheng/LanShengAPI/appsettings.Development.json b/LanSheng/LanShengAPI/appsettings.Development.json new file mode 100644 index 0000000..33c4e86 --- /dev/null +++ b/LanSheng/LanShengAPI/appsettings.Development.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "Microsoft.AspNetCore": "Warning" + } + }, + "DotNetty": { + "Use": "Y", + "ThreadPool": 8, + "Port": 5888 + } +} diff --git a/LanSheng/LanShengAPI/appsettings.json b/LanSheng/LanShengAPI/appsettings.json new file mode 100644 index 0000000..925c227 --- /dev/null +++ b/LanSheng/LanShengAPI/appsettings.json @@ -0,0 +1,18 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "Default": "Data Source=mysql;database=lsdb;User Id=root;Pwd=root;charset=utf8;pooling=true;" + }, + "DotNetty": { + "Use": "Y", + "ThreadPool": 8, + "Port": 9001 + }, + "Redis": "redis:6379" +} diff --git a/LanSheng/LanShengInterface/IDeviceDataActor.cs b/LanSheng/LanShengInterface/IDeviceDataActor.cs new file mode 100644 index 0000000..3de1d8d --- /dev/null +++ b/LanSheng/LanShengInterface/IDeviceDataActor.cs @@ -0,0 +1,14 @@ +using Dapr.Actors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengInterface +{ + public interface IDeviceDataActor : IActor + { + Task StartTimer(); + } +} diff --git a/LanSheng/LanShengInterface/IDeviceService.cs b/LanSheng/LanShengInterface/IDeviceService.cs new file mode 100644 index 0000000..5f077c4 --- /dev/null +++ b/LanSheng/LanShengInterface/IDeviceService.cs @@ -0,0 +1,35 @@ +using CommonModel; +using LanShengModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengInterface +{ + public interface IDeviceService + { + Task InsertData(DeviceData deviceData); + + Task InsertDataDo(); + + Task TimerInsertDataDo(); + + Task InsertDataLog(TcpDataLog dataLog); + + Task InsertDataLogDo(); + + Task TimerInsertDataLogDo(); + + Task Offline(string id = ""); + + Task GetDeviceData(string id); + + Task> GetDeviceData(string[] ids); + + Task ResetRunCount(string id = ""); + + Task> GetDeviceErrorPage(PageYearSearch search); + } +} diff --git a/LanSheng/LanShengInterface/ITcpDataLogActor.cs b/LanSheng/LanShengInterface/ITcpDataLogActor.cs new file mode 100644 index 0000000..334995c --- /dev/null +++ b/LanSheng/LanShengInterface/ITcpDataLogActor.cs @@ -0,0 +1,14 @@ +using Dapr.Actors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengInterface +{ + public interface ITcpDataLogActor : IActor + { + Task StartTimer(); + } +} diff --git a/LanSheng/LanShengInterface/ITcpService.cs b/LanSheng/LanShengInterface/ITcpService.cs new file mode 100644 index 0000000..c830b2c --- /dev/null +++ b/LanSheng/LanShengInterface/ITcpService.cs @@ -0,0 +1,20 @@ +using DotNetty.Transport.Channels; +using DotNetty.Transport.Channels.Groups; +using LanShengModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengInterface +{ + public interface ITcpService + { + Task AddChannel(string id, IChannelHandlerContext context); + + Task PushParams(DeviceData deviceData); + + Task RemoveMessageItem(TcpDataLog packet); + } +} diff --git a/LanSheng/LanShengInterface/LanShengInterface.csproj b/LanSheng/LanShengInterface/LanShengInterface.csproj new file mode 100644 index 0000000..e700f82 --- /dev/null +++ b/LanSheng/LanShengInterface/LanShengInterface.csproj @@ -0,0 +1,19 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + diff --git a/LanSheng/LanShengModel/ChannelQueue.cs b/LanSheng/LanShengModel/ChannelQueue.cs new file mode 100644 index 0000000..ded09c7 --- /dev/null +++ b/LanSheng/LanShengModel/ChannelQueue.cs @@ -0,0 +1,23 @@ +using DotNetty.Transport.Channels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengModel +{ + public class ChannelQueue + { + public ChannelQueue(IChannelId channelId,string dtu_id) { + ChannelId = channelId; + DTU_Id = dtu_id; + } + + public readonly IChannelId ChannelId; + + public readonly string DTU_Id; + + public int MsgId = 0; + } +} diff --git a/LanSheng/LanShengModel/DeviceData.cs b/LanSheng/LanShengModel/DeviceData.cs new file mode 100644 index 0000000..c319a99 --- /dev/null +++ b/LanSheng/LanShengModel/DeviceData.cs @@ -0,0 +1,507 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengModel +{ + [SugarTable("LS_DeviceData")] + public class DeviceData + { + /// + /// 编号 + /// + [SugarColumn(IsPrimaryKey = true, Length = 50)] + public string? Id { get; set; } + + /// + /// 设备状态 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? Status { get; set; } + + /// + /// 故障代码 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? ErrCode { get; set; } + + /// + /// 故障信息 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? ErrMsg { get; set; } + + /// + /// 当前DTU的软件版本号 + /// + [SugarColumn(IsNullable = true)] + public int? Version { get; set; } + + /// + /// 启动指示 (0未启动, 1已启动) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B7 { get; set; } + + /// + /// 电锁/IC卡 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B6 { get; set; } + + /// + /// 笼内急停 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B5 { get; set; } + + /// + /// 笼顶急停 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B4 { get; set; } + + /// + /// 防坠器限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B3 { get; set; } + + /// + /// 防冲顶限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B2 { get; set; } + + /// + /// 备用限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B1 { get; set; } + + /// + /// GPS限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data2_B0 { get; set; } + + /// + /// 进料门限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B7 { get; set; } + + /// + /// 出料门限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B6 { get; set; } + + /// + /// 天窗门限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B5 { get; set; } + + /// + /// 上限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B4 { get; set; } + + /// + /// 下限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B3 { get; set; } + + /// + /// 上减速限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B2 { get; set; } + + /// + /// 下减速限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B1 { get; set; } + + /// + /// 抱闸状态 (0:动作 1:未动作) + /// + [SugarColumn(IsNullable = true)] + public int? Data3_B0 { get; set; } + + /// + /// 一体机驱动故障 + /// + [SugarColumn(IsNullable = true)] + public int? Data4 { get; set; } + + /// + /// 一体机逻辑故障 + /// + [SugarColumn(IsNullable = true)] + public int? Data5 { get; set; } + + /// + /// 一体机电梯载重 + /// + [SugarColumn(IsNullable = true)] + public decimal? Data6 { get; set; } + + // + /// 一体机运行频率 + /// + [SugarColumn(IsNullable = true)] + public int? Data7 { get; set; } + + /// + /// 一体机输入电压 + /// + [SugarColumn(IsNullable = true)] + public int? Data8 { get; set; } + + /// + /// 一体机输出电流 + /// + [SugarColumn(IsNullable = true)] + public int? Data10 { get; set; } + + /// + /// 一体机当前楼层 + /// + [SugarColumn(Length = 5, IsNullable = true)] + public int? Data11 { get; set; } + + /// + /// 一体机目标楼层 + /// + [SugarColumn(Length = 5, IsNullable = true)] + public int? Data12 { get; set; } + + /// + /// 信道号 + /// + [SugarColumn(IsNullable = true)] + public int? Data13 { get; set; } + + /// + /// 一体机操作模式(1:智能模式2:笼顶操作3防坠测试) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B6 { get; set; } + + /// + /// 一体机上升输入(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B5 { get; set; } + + /// + /// 一体机下降输入(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B4 { get; set; } + + /// + /// 一体机高速输入(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B3 { get; set; } + + /// + /// 一体机上升输出(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B2 { get; set; } + + /// + /// 一体机下降输出(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B1 { get; set; } + + /// + /// 一体机高速输出(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data14_B0 { get; set; } + + /// + /// 一体机运行状态(1:上升2:下降3:停机) + /// + [SugarColumn(IsNullable = true)] + public int? Data15_B6 { get; set; } + + /// + /// 门机运行状态(1:上升2:下降3:停机) + /// + [SugarColumn(IsNullable = true)] + public int? Data15_B4 { get; set; } + + /// + /// 进料门上限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data15_B3 { get; set; } + + /// + /// 进料门下限位 (0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data15_B2 { get; set; } + + /// + /// 出料门上限位(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data15_B1 { get; set; } + + /// + /// 出料门下限位(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data15_B0 { get; set; } + + /// + /// 一体机通讯(0异常,1正常) + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B7 { get; set; } + + /// + /// 门机通讯(0异常,1正常) + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B6 { get; set; } + + /// + /// 左右笼通讯(0异常,1正常) + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B5 { get; set; } + + /// + /// 人数摄像头通讯(0异常,1正常) + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B4 { get; set; } + + /// + /// 门机控制 (0:无1进料门2出料门 + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B2 { get; set; } + + /// + /// 进料门光幕(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B1 { get; set; } + + /// + /// 出料门光幕(0断开,1闭合) + /// + [SugarColumn(IsNullable = true)] + public int? Data16_B0 { get; set; } + + /// + /// 门机故障代码 + /// + [SugarColumn(IsNullable = true)] + public int? Data17 { get; set; } + + /// + /// 门机控制(0:自动 1:手动 ) + /// + [SugarColumn(IsNullable = true)] + public int? Data18 { get; set; } + + /// + /// 手动模式(0:点动 1:开关到位) + /// + [SugarColumn(IsNullable = true)] + public int? Data19 { get; set; } + + /// + /// 检修开关(0:正常 1:检修) + /// + [SugarColumn(IsNullable = true)] + public int? Data20 { get; set; } + + /// + /// 吊笼内人数 + /// + [SugarColumn(IsNullable = true)] + public int? Data21 { get; set; } + + /// + /// 语音码 + /// + [SugarColumn(IsNullable = true)] + public int? Data22 { get; set; } + + /// + /// 自动平层开关(0:关闭 1:开启) + /// + [SugarColumn(IsNullable = true)] + public int? Data23 { get; set; } + + /// + /// 已学楼层数 + /// + [SugarColumn(IsNullable = true)] + public int? Data24 { get; set; } + + /// + /// 密码第一位 + /// + [SugarColumn(IsNullable = true)] + public int? Data25_B4 { get; set; } + + /// + /// 密码第二位 + /// + [SugarColumn(IsNullable = true)] + public int? Data25_B0 { get; set; } + + /// + /// 密码第三位 + /// + [SugarColumn(IsNullable = true)] + public int? Data26_B4 { get; set; } + + /// + /// 密码第四位 + /// + [SugarColumn(IsNullable = true)] + public int? Data26_B0 { get; set; } + + /// + /// 限速 (0:不限速1:限速) + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B7 { get; set; } + + /// + /// 锁机 (0:不锁机1:锁机) + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B6 { get; set; } + + /// + /// 故障复位 (0:不复位1:复位) + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B5 { get; set; } + + /// + /// 超载清零 (0:不清零1:清零) + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B4 { get; set; } + + /// + /// 载波修改 (0:不修改1:修改载波) + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B3 { get; set; } + + /// + /// 预留 + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B2 { get; set; } + + /// + /// 预留 + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B1 { get; set; } + + /// + /// 修改完成标志(0:未完成1:完成) + /// + [SugarColumn(IsNullable = true)] + public int? Data27_B0 { get; set; } + + /// + /// 协议版本号,1 施工梯 2通用机 3塔机4揽胜升降机 + /// + [SugarColumn(IsNullable = true)] + public int? AgreementVersion { get; set; } + + /// + /// 上传数据的间隔时间(每隔n秒),0XFFFF表示关闭定时上传 + /// + [SugarColumn(IsNullable = true)] + public int? DataTick { get; set; } + + /// + /// 全部为ASCII码字符;需要记录下来,上下线后都能显示,上线后如和上一次不一致需做个图标标识出来 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? ICCID { get; set; } + + /// + /// 东经 + /// + [SugarColumn(IsNullable = true)] + public string? Longitude { get; set; } + + /// + /// 北纬 + /// + [SugarColumn(IsNullable = true)] + public string? Latitude { get; set; } + + /// + /// 连接字符串长度 + /// + [SugarColumn(IsNullable = true)] + public int? ConnectStrLength { get; set; } + + /// + /// 连接字符串 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? ConnectString { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(IsNullable = true)] + public DateTime? UpdateDate { get; set; } + + [SugarColumn(IsNullable = true)] + public DateTime? OfflineDate { get; set; } + + /// + /// 修改标志,1:外围控制板执行修改;0:外围控制板不执行修改 + /// + [SugarColumn(IsNullable = true)] + public int? UpdateTag { get; set; } + + /// + /// IP是否修改,0:不修改,1:修改 + /// + [SugarColumn(IsNullable = true)] + public int? IPSFXG { get; set; } + + /// + /// 运行次数 + /// + [SugarColumn(IsNullable = true,IsOnlyIgnoreInsert = true,DefaultValue = "0")] + public int? RunCount { get; set; } + + #region 业务字段 + [SugarColumn(IsIgnore = true)] + public string? MsgType { get; set; } + #endregion + } +} diff --git a/LanSheng/LanShengModel/DeviceData1001.cs b/LanSheng/LanShengModel/DeviceData1001.cs new file mode 100644 index 0000000..bf4b8b3 --- /dev/null +++ b/LanSheng/LanShengModel/DeviceData1001.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengModel +{ + public class DeviceData1001 + { + + public string? Status { get; set; } + + public DateTime? UpdateDate { get; set; } + + public int? AgreementVersion { get; set; } + + public int? DataTick { get; set; } + + public string? ICCID { get; set; } + + public string? Longitude { get; set; } + + public string? Latitude { get; set; } + + public int? ConnectStrLength { get; set; } + + public string? ConnectString { get; set; } + + public static string[] GetColumns() + { + var Result = new List(); + var Type = typeof(DeviceData1001); + foreach (var Propety in Type.GetProperties()) + { + Result.Add(Propety.Name); + } + return Result.ToArray(); + } + } +} diff --git a/LanSheng/LanShengModel/DeviceData1103.cs b/LanSheng/LanShengModel/DeviceData1103.cs new file mode 100644 index 0000000..976121a --- /dev/null +++ b/LanSheng/LanShengModel/DeviceData1103.cs @@ -0,0 +1,372 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengModel +{ + public class DeviceData1103 + { + + public string? Status { get; set; } + + /// + /// 故障代码 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? ErrCode { get; set; } + + /// + /// 故障信息 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? ErrMsg { get; set; } + + /// + /// 当前DTU的软件版本号 + /// + [SugarColumn(IsNullable = true)] + public int? Version { get; set; } + + + public DateTime? UpdateDate { get; set; } + + /// + /// 启动指示 (0未启动, 1已启动) + /// + public int? Data2_B7 { get; set; } + + /// + /// 电锁/IC卡 (0断开,1闭合) + /// + public int? Data2_B6 { get; set; } + + /// + /// 笼内急停 (0断开,1闭合) + /// + public int? Data2_B5 { get; set; } + + /// + /// 笼顶急停 (0断开,1闭合) + /// + public int? Data2_B4 { get; set; } + + /// + /// 防坠器限位 (0断开,1闭合) + /// + public int? Data2_B3 { get; set; } + + /// + /// 防冲顶限位 (0断开,1闭合) + /// + public int? Data2_B2 { get; set; } + + /// + /// 备用限位 (0断开,1闭合) + /// + public int? Data2_B1 { get; set; } + + /// + /// GPS限位 (0断开,1闭合) + /// + public int? Data2_B0 { get; set; } + + /// + /// 进料门限位 (0断开,1闭合) + /// + public int? Data3_B7 { get; set; } + + /// + /// 出料门限位 (0断开,1闭合) + /// + public int? Data3_B6 { get; set; } + + /// + /// 天窗门限位 (0断开,1闭合) + /// + public int? Data3_B5 { get; set; } + + /// + /// 上限位 (0断开,1闭合) + /// + public int? Data3_B4 { get; set; } + + /// + /// 下限位 (0断开,1闭合) + /// + public int? Data3_B3 { get; set; } + + /// + /// 上减速限位 (0断开,1闭合) + /// + public int? Data3_B2 { get; set; } + + /// + /// 下减速限位 (0断开,1闭合) + /// + public int? Data3_B1 { get; set; } + + /// + /// 抱闸状态 (0:动作 1:未动作) + /// + public int? Data3_B0 { get; set; } + + /// + /// 一体机驱动故障 + /// + public int? Data4 { get; set; } + + /// + /// 一体机逻辑故障 + /// + public int? Data5 { get; set; } + + /// + /// 一体机电梯载重 + /// + public decimal? Data6 { get; set; } + + // + /// 一体机运行频率 + /// + public int? Data7 { get; set; } + + /// + /// 一体机输入电压 + /// + public int? Data8 { get; set; } + + /// + /// 一体机输出电流 + /// + public int? Data10 { get; set; } + + /// + /// 一体机当前楼层 + /// + public int? Data11 { get; set; } + + /// + /// 一体机目标楼层 + /// + public int? Data12 { get; set; } + + /// + /// 信道号 + /// + public int? Data13 { get; set; } + + /// + /// 一体机操作模式(1:智能模式2:笼顶操作3防坠测试) + /// + public int? Data14_B6 { get; set; } + + /// + /// 一体机上升输入(0断开,1闭合) + /// + public int? Data14_B5 { get; set; } + + /// + /// 一体机下降输入(0断开,1闭合) + /// + public int? Data14_B4 { get; set; } + + /// + /// 一体机高速输入(0断开,1闭合) + /// + public int? Data14_B3 { get; set; } + + /// + /// 一体机上升输出(0断开,1闭合) + /// + public int? Data14_B2 { get; set; } + + /// + /// 一体机下降输出(0断开,1闭合) + /// + public int? Data14_B1 { get; set; } + + /// + /// 一体机高速输出(0断开,1闭合) + /// + public int? Data14_B0 { get; set; } + + /// + /// 一体机运行状态(1:上升2:下降3:停机) + /// + public int? Data15_B6 { get; set; } + + /// + /// 门机运行状态(1:上升2:下降3:停机) + /// + public int? Data15_B4 { get; set; } + + /// + /// 进料门上限位 (0断开,1闭合) + /// + public int? Data15_B3 { get; set; } + + /// + /// 进料门下限位 (0断开,1闭合) + /// + public int? Data15_B2 { get; set; } + + /// + /// 出料门上限位(0断开,1闭合) + /// + public int? Data15_B1 { get; set; } + + /// + /// 出料门下限位(0断开,1闭合) + /// + public int? Data15_B0 { get; set; } + + /// + /// 一体机通讯(0异常,1正常) + /// + public int? Data16_B7 { get; set; } + + /// + /// 门机通讯(0异常,1正常) + /// + public int? Data16_B6 { get; set; } + + /// + /// 左右笼通讯(0异常,1正常) + /// + public int? Data16_B5 { get; set; } + + /// + /// 人数摄像头通讯(0异常,1正常) + /// + public int? Data16_B4 { get; set; } + + /// + /// 门机控制 (0:无1进料门2出料门 + /// + public int? Data16_B2 { get; set; } + + /// + /// 进料门光幕(0断开,1闭合) + /// + public int? Data16_B1 { get; set; } + + /// + /// 出料门光幕(0断开,1闭合) + /// + public int? Data16_B0 { get; set; } + + /// + /// 门机故障代码 + /// + public int? Data17 { get; set; } + + /// + /// 门机控制(0:自动 1:手动 ) + /// + public int? Data18 { get; set; } + + /// + /// 手动模式(0:点动 1:开关到位) + /// + public int? Data19 { get; set; } + + /// + /// 检修开关(0:正常 1:检修) + /// + public int? Data20 { get; set; } + + /// + /// 吊笼内人数 + /// + public int? Data21 { get; set; } + + /// + /// 语音码 + /// + public int? Data22 { get; set; } + + /// + /// 自动平层开关(0:关闭 1:开启) + /// + public int? Data23 { get; set; } + + /// + /// 已学楼层数 + /// + public int? Data24 { get; set; } + + /// + /// 密码第一位 + /// + public int? Data25_B4 { get; set; } + + /// + /// 密码第二位 + /// + public int? Data25_B0 { get; set; } + + /// + /// 密码第三位 + /// + public int? Data26_B4 { get; set; } + + /// + /// 密码第四位 + /// + public int? Data26_B0 { get; set; } + + /// + /// 限速 (0:不限速1:限速) + /// + public int? Data27_B7 { get; set; } + + /// + /// 锁机 (0:不锁机1:锁机) + /// + public int? Data27_B6 { get; set; } + + /// + /// 故障复位 (0:不复位1:复位) + /// + public int? Data27_B5 { get; set; } + + /// + /// 超载清零 (0:不清零1:清零) + /// + public int? Data27_B4 { get; set; } + + /// + /// 载波修改 (0:不修改1:修改载波) + /// + public int? Data27_B3 { get; set; } + + /// + /// 预留 + /// + public int? Data27_B2 { get; set; } + + /// + /// 预留 + /// + public int? Data27_B1 { get; set; } + + /// + /// 修改完成标志(0:未完成1:完成) + /// + public int? Data27_B0 { get; set; } + + public static string[] GetColumns() + { + var Result = new List(); + var Type = typeof(DeviceData1103); + foreach (var Propety in Type.GetProperties()) + { + Result.Add(Propety.Name); + } + return Result.ToArray(); + } + } +} diff --git a/LanSheng/LanShengModel/DeviceError.cs b/LanSheng/LanShengModel/DeviceError.cs new file mode 100644 index 0000000..1828ef4 --- /dev/null +++ b/LanSheng/LanShengModel/DeviceError.cs @@ -0,0 +1,48 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengModel +{ + [SugarTable("LS_DeviceError_{year}{month}{day}")] + [SplitTable(SplitType.Year)] + public class DeviceError + { + /// + /// 编号 + /// + [SugarColumn(IsPrimaryKey = true,Length = 50,ColumnDescription = "编号")] + public string? Id { get; set; } + + /// + /// 设备编号 + /// + [SugarColumn(IsPrimaryKey = true,Length = 50,ColumnDescription = "设备编号")] + public string? DeviceId { get; set; } + + /// + /// 错误代码 + /// + [SugarColumn(IsNullable = true,ColumnDescription = "错误代码",Length = 20)] + public string? ErrCode { get; set; } + + /// + /// 错误信息 + /// + [SugarColumn(IsNullable = true,ColumnDescription = "错误信息",Length = 200)] + public string? ErrMsg { get; set; } + + /// + /// 结束日期 + /// + [SugarColumn(IsNullable = true,ColumnDescription = "结束日期")] + public DateTime? EndDate { get; set; } + + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + } +} diff --git a/LanSheng/LanShengModel/DeviceErrorReport.cs b/LanSheng/LanShengModel/DeviceErrorReport.cs new file mode 100644 index 0000000..612fe19 --- /dev/null +++ b/LanSheng/LanShengModel/DeviceErrorReport.cs @@ -0,0 +1,45 @@ +/// +/// 设备故障报表 +/// +public class DeviceErrorReport +{ + /// + /// 故障类型 + /// + public IEnumerable? ErrCodes { get; set; } + + /// + /// 公司编号 + /// + public IEnumerable? CompanyIds { get; set; } + + /// + /// 项目编号 + /// + public IEnumerable? ProjectIds { get; set; } + + /// + /// 设备编号 + /// + public IEnumerable? DeviceIds { get; set; } + + /// + /// 开始日期 + /// + public DateTime? StartDate { get; set; } + + /// + /// 结束日期 + /// + public DateTime? EndDate { get; set; } + + /// + /// 单元 + /// + public string? Unit { get; set; } + + /// + /// 数据集 + /// + public Dictionary? Items { get; set; } +} \ No newline at end of file diff --git a/LanSheng/LanShengModel/LanShengModel.csproj b/LanSheng/LanShengModel/LanShengModel.csproj new file mode 100644 index 0000000..ed3da8f --- /dev/null +++ b/LanSheng/LanShengModel/LanShengModel.csproj @@ -0,0 +1,14 @@ + + + + net7.0 + enable + enable + + + + + + + + diff --git a/LanSheng/LanShengModel/TcpDataLog.cs b/LanSheng/LanShengModel/TcpDataLog.cs new file mode 100644 index 0000000..dec59a3 --- /dev/null +++ b/LanSheng/LanShengModel/TcpDataLog.cs @@ -0,0 +1,74 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengModel +{ + [SugarTable("LS_TcpDataLog_{year}{month}{day}")] + [SplitTable(SplitType.Day)] + public class TcpDataLog + { + + [SugarColumn(IsNullable = true, Length = 10)] + public string? Frame_START { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public int? Frame_Length { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public int? Frame_number { get; set; } + + [SugarColumn(IsNullable = true, Length = 200)] + public string? DTU_ID { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public string? Msg_ID { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public int? Checksum { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public string? Frame_END { get; set; } + + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + } + + [SugarTable("LS_TcpDataLog_{year}{month}{day}")] + [SplitTable(SplitType.Day)] + public class TcpDataLog + { + + [SugarColumn(IsNullable = true, Length = 10)] + public string? Frame_START { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public int? Frame_Length { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public int? Frame_number { get; set; } + + [SugarColumn(IsNullable = true, Length = 200)] + public string? DTU_ID { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public string? Msg_ID { get; set; } + + [SugarColumn(IsNullable = true, IsJson = true, ColumnDataType = "Text")] + public T? Content { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public int? Checksum { get; set; } + + [SugarColumn(IsNullable = true, Length = 10)] + public string? Frame_END { get; set; } + + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + } +} diff --git a/LanSheng/LanShengService/DeviceService.cs b/LanSheng/LanShengService/DeviceService.cs new file mode 100644 index 0000000..808da46 --- /dev/null +++ b/LanSheng/LanShengService/DeviceService.cs @@ -0,0 +1,1292 @@ +using CommonModel; +using Dapr.Client; +using LanShengInterface; +using LanShengModel; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NewLife.Reflection; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace LanShengService +{ + public class DeviceService : IDeviceService + { + public DeviceService(IServiceProvider services) + { + Services = services; + + Logger = services.GetRequiredService>(); + + Db = services.GetRequiredService(); + + Db.CodeFirst.InitTables(typeof(DeviceData)); + + Db.CodeFirst.SplitTables().InitTables(typeof(TcpDataLog)); + + Db.CodeFirst.SplitTables().InitTables(typeof(DeviceError)); + + Columns1001 = DeviceData1001.GetColumns(); + + Columns1103 = DeviceData1103.GetColumns(); + + Logger.LogDebug("加载数据结构"); + + CacheService = services.GetRequiredService(); + + Logger.LogDebug("加载缓存服务"); + + InitDeviceError(); + + Logger.LogDebug("加载设备故障表"); + + Logger.LogDebug("创建设备服务"); + } + + private readonly IServiceProvider Services; + + private readonly ILogger Logger; + + private readonly ISqlSugarClient Db; + + private readonly CacheInterface.ICacheService CacheService; + + private readonly int TicketInsertDataDo = 1000; + + private readonly int TicketInsertDataLogDo = 5000; + + private readonly int TicketClearDataLogDo = 1000 * 60 * 60 * 24; + + private readonly int ValidClearDataLogDo = 1000 * 60 * 60 * 24 * 3; + + private readonly string[] Columns1001; + + private readonly string[] Columns1103; + + public async Task InsertData(DeviceData deviceData) + { + Logger.LogDebug($"设备数据插入队列{JsonSerializer.Serialize(deviceData)}"); + + await SetError(deviceData); + + await SetRunCount(deviceData); + + await CacheService.Set($"DeviceData:{deviceData.Id}.{Guid.NewGuid().ToString()}", deviceData, 5); + + await CacheService.Set($"CacheData:{deviceData.Id}", deviceData, 5); + } + + public async Task TimerInsertDataDo() + { + Logger.LogDebug($"启动设备数据定时任务"); + + await Task.Factory.StartNew(async () => + { + while (true) + { + try + { + await InsertDataDo(); + } + catch (Exception ex) + { + Logger.LogError(ex.ToString()); + } + finally + { + Thread.Sleep(TicketInsertDataDo); + } + } + }, TaskCreationOptions.LongRunning); + } + + public async Task InsertDataDo() + { + var Devices = await CacheService.Query("DeviceData:"); + await CacheService.BatchDelete(Devices.Keys.ToArray()); + Logger.LogDebug($"执行设备数据队列插入{JsonSerializer.Serialize(Devices)}"); + if (Devices.Count > 0) + { + var DeviceValues = Devices.Values.GroupBy(x => x == null ? null : x.Id).Select(x => x.First()); + + var Values1001 = DeviceValues.Where(x => x != null && (x.MsgType == "1001" || x.MsgType == "9104")).ToList(); + + if (Values1001.Count > 0) + { + var temp = Db.Storageable(Values1001).ToStorage(); + + await temp.AsInsertable.ExecuteCommandAsync(); + + await temp.AsUpdateable + .UpdateColumns(Columns1001) + .ExecuteCommandAsync(); + } + + var Values1103 = DeviceValues.Where(x => x != null && x.MsgType == "1103").ToList(); + + if (Values1103.Count > 0) + { + var temp = Db.Storageable(Values1103).ToStorage(); + + await temp.AsInsertable.ExecuteCommandAsync(); + + await temp.AsUpdateable + .UpdateColumns(Columns1103) + .ExecuteCommandAsync(); + } + } + } + + public async Task InsertDataLog(TcpDataLog dataLog) + { + Logger.LogDebug($"日志插入队列{JsonSerializer.Serialize(dataLog)}"); + + await CacheService.Set($"TcpDataLog:{dataLog.DTU_ID}.{Guid.NewGuid().ToString()}", dataLog, 30); + } + + public async Task TimerInsertDataLogDo() + { + Logger.LogDebug($"启动设备日志定时任务"); + await Task.Factory.StartNew(async () => + { + while (true) + { + try + { + await InsertDataLogDo(); + } + catch (Exception ex) + { + Logger.LogError(ex.ToString()); + } + finally + { + Thread.Sleep(TicketInsertDataLogDo); + } + } + }, TaskCreationOptions.LongRunning); + } + + public async Task TimerClearDataLogDo() + { + Logger.LogDebug($"启动设备日志定时清理任务"); + await Task.Factory.StartNew(async () => + { + while (true) + { + try + { + await ClearDataLogDo(); + } + catch (Exception ex) + { + Logger.LogError(ex.ToString()); + } + finally + { + Thread.Sleep(TicketClearDataLogDo); + } + } + }, TaskCreationOptions.LongRunning); + } + + public async Task InsertDataLogDo() + { + var Logs = await CacheService.Query>("TcpDataLog:"); + await CacheService.BatchDelete(Logs.Keys.ToArray()); + Logger.LogDebug($"执行日志队列插入{JsonSerializer.Serialize(Logs)}"); + if (Logs.Count > 0) + { + await Db.Insertable(Logs.Values.ToList()).SplitTable().ExecuteCommandAsync(); + } + } + + public async Task ClearDataLogDo() + { + await Db.Deleteable().Where(x => x.CreateDate < DateTime.Now.AddMilliseconds(-ValidClearDataLogDo)).SplitTable(tas => tas.Take(10)).ExecuteCommandAsync(); + } + + public async Task Offline(string id = "") + { + Logger.LogDebug($"设备离线{id}"); + if (string.IsNullOrEmpty(id)) + { + await Db.Updateable().SetColumns(x => x.Status == "offline").SetColumns(x => x.ErrCode == "").SetColumns(x => x.ErrMsg == "").SetColumns(x => x.OfflineDate == DateTime.Now).Where(x => 1 == 1).ExecuteCommandAsync(); + } + else + { + await Db.Updateable().SetColumns(x => x.Status == "offline").SetColumns(x => x.ErrCode == "").SetColumns(x => x.ErrMsg == "").SetColumns(x => x.OfflineDate == DateTime.Now).Where(x => x.Id == id).ExecuteCommandAsync(); + } + } + + public async Task ResetRunCount(string id = "") + { + Logger.LogDebug($"重置运行次数{id}"); + if (!string.IsNullOrEmpty(id)) + { + await Db.Updateable().SetColumns(x => x.RunCount == 0).Where(x => x.Id == id).ExecuteCommandAsync(); + + await CacheService.Set($"{id}_RunCount", 0); + } + } + + public async Task GetDeviceData(string id) + { + var Result = await GetDeviceData(new string[] { id }); + if (Result.Count > 0) + { + return Result[0]; + } + else + { + throw new BadRequestException("设备编号不存在"); + } + } + + public async Task> GetDeviceData(string[] ids) + { + var Result = new List(); + + var CacheIds = new List(); + ids.ToList().ForEach((x) => + { + CacheIds.Add($"CacheData:{x}"); + }); + var CacheResult = await CacheService.BatchGet(CacheIds); + + Result.AddRange(CacheResult.Where(x => x.Value != null).Select(x => x.Value)); + + var NotCacheIds = CacheResult.Where(x => x.Value == null).Select(x => x.Key.Remove(0, 10)).ToList(); + + if (NotCacheIds.Count() > 0) + { + var DbResult = await Db.Queryable().In("Id", NotCacheIds) + .IgnoreColumns(x => new + { + x.Data25_B4, + x.Data25_B0, + x.Data26_B4, + x.Data26_B0 + }) + .ToListAsync(); + + Result.AddRange(DbResult.ToList()); + + var DbCache = new Dictionary(); + + foreach (var Item in DbResult) + { + DbCache.Add($"CacheData:{Item.Id}", Item); + } + + await CacheService.BatchSet(DbCache, 60); + } + Result = JsonSerializer.Deserialize>(JsonSerializer.Serialize(Result))!; + Result.ForEach(x => + { + x.Data6 = x.Data6 / 10; + decimal Latitude = 0; + Decimal.TryParse(x.Latitude, out Latitude); + x.Latitude = (Latitude / 1000000).ToString(); + decimal Longitude = 0; + Decimal.TryParse(x.Longitude, out Longitude); + x.Longitude = (Longitude / 1000000).ToString(); + }); + + return Result; + } + + private Task SetError(DeviceData deviceData) + { + deviceData.ErrCode = ""; + deviceData.ErrMsg = ""; + + #region 一体机驱动故障 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + SetData4Error(deviceData); + } + #endregion + + #region 一体机逻辑故障 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + SetData5Error(deviceData); + } + #endregion + + #region 门机故障 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + SetData17Error(deviceData); + } + #endregion + + #region 语音码故障 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + SeteData22Error(deviceData); + } + #endregion + + #region 自定义故障 + int TempTime = 12; + + //进料门限位保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + var Data3_B7_Date = CacheService.Get($"Data3_B7_Date:{deviceData.Id}").Result; + if (Data3_B7_Date == default) + { + CacheService.Set($"Data3_B7_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data3_B7:{deviceData.Id}", deviceData.Data3_B7).Wait(); + } + else + { + var Data3_B7 = CacheService.Get($"Data3_B7:{deviceData.Id}").Result; + if (Data3_B7 == deviceData.Data3_B7) + { + TimeSpan span = DateTime.Now - Data3_B7_Date; + if (span.TotalHours > TempTime) + { + deviceData.ErrCode = "LS001"; + deviceData.ErrMsg = "进料门限位长时间未动作"; + } + } + else + { + CacheService.Set($"Data3_B7_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data3_B7:{deviceData.Id}", deviceData.Data3_B7).Wait(); + } + } + } + + //出料门限位保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + var Data3_B6_Date = CacheService.Get($"Data3_B6_Date:{deviceData.Id}").Result; + if (Data3_B6_Date == default) + { + CacheService.Set($"Data3_B6_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data3_B6:{deviceData.Id}", deviceData.Data3_B6).Wait(); + } + else + { + var Data3_B6 = CacheService.Get($"Data3_B6:{deviceData.Id}").Result; + if (Data3_B6 == deviceData.Data3_B6) + { + TimeSpan span = DateTime.Now - Data3_B6_Date; + if (span.TotalHours > TempTime) + { + deviceData.ErrCode = "LS002"; + deviceData.ErrMsg = "出料门限位长时间未动作"; + } + } + else + { + CacheService.Set($"Data3_B6_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data3_B6:{deviceData.Id}", deviceData.Data3_B6).Wait(); + } + } + } + + //进料门上限位保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + var Data15_B3_Date = CacheService.Get($"Data15_B3_Date:{deviceData.Id}").Result; + if (Data15_B3_Date == default) + { + CacheService.Set($"Data15_B3_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B3:{deviceData.Id}", deviceData.Data15_B3).Wait(); + } + else + { + var Data15_B3 = CacheService.Get($"Data15_B3:{deviceData.Id}").Result; + if (Data15_B3 == deviceData.Data15_B3) + { + TimeSpan span = DateTime.Now - Data15_B3_Date; + if (span.TotalHours > TempTime) + { + deviceData.ErrCode = "LS003"; + deviceData.ErrMsg = "进料门上限位长时间未动作"; + } + } + else + { + CacheService.Set($"Data15_B3_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B3:{deviceData.Id}", deviceData.Data3_B6).Wait(); + } + } + } + + //进料门下限位保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + var Data15_B2_Date = CacheService.Get($"Data15_B2_Date:{deviceData.Id}").Result; + if (Data15_B2_Date == default) + { + CacheService.Set($"Data15_B2_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B2:{deviceData.Id}", deviceData.Data15_B2).Wait(); + } + else + { + var Data15_B2 = CacheService.Get($"Data15_B2:{deviceData.Id}").Result; + if (Data15_B2 == deviceData.Data15_B2) + { + TimeSpan span = DateTime.Now - Data15_B2_Date; + if (span.TotalHours > TempTime) + { + deviceData.ErrCode = "LS004"; + deviceData.ErrMsg = "进料门下限位长时间未动作"; + } + } + else + { + CacheService.Set($"Data15_B2_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B2:{deviceData.Id}", deviceData.Data15_B2).Wait(); + } + } + } + + //出料门上限位保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + var Data15_B1_Date = CacheService.Get($"Data15_B1_Date:{deviceData.Id}").Result; + if (Data15_B1_Date == default) + { + CacheService.Set($"Data15_B1_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B1:{deviceData.Id}", deviceData.Data15_B1).Wait(); + } + else + { + var Data15_B1 = CacheService.Get($"Data15_B1:{deviceData.Id}").Result; + if (Data15_B1 == deviceData.Data15_B1) + { + TimeSpan span = DateTime.Now - Data15_B1_Date; + if (span.TotalHours > TempTime) + { + deviceData.ErrCode = "LS005"; + deviceData.ErrMsg = "出料门上限位长时间未动作"; + } + } + else + { + CacheService.Set($"Data15_B1_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B1:{deviceData.Id}", deviceData.Data15_B1).Wait(); + } + } + } + + //出料门下限位保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + var Data15_B0_Date = CacheService.Get($"Data15_B0_Date:{deviceData.Id}").Result; + if (Data15_B0_Date == default) + { + CacheService.Set($"Data15_B0_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B0:{deviceData.Id}", deviceData.Data15_B0).Wait(); + } + else + { + var Data15_B0 = CacheService.Get($"Data15_B0:{deviceData.Id}").Result; + if (Data15_B0 == deviceData.Data15_B0) + { + TimeSpan span = DateTime.Now - Data15_B0_Date; + if (span.TotalHours > TempTime) + { + deviceData.ErrCode = "LS007"; + deviceData.ErrMsg = "出料门下限位长时间未动作"; + } + } + else + { + CacheService.Set($"Data15_B0_Date:{deviceData.Id}", DateTime.Now).Wait(); + CacheService.Set($"Data15_B0:{deviceData.Id}", deviceData.Data15_B0).Wait(); + } + } + } + + //人数摄像头保护 + if (string.IsNullOrEmpty(deviceData.ErrCode) && string.IsNullOrEmpty(deviceData.ErrMsg)) + { + if (deviceData.Data16_B4 == 0) + { + deviceData.ErrCode = "LS008"; + deviceData.ErrMsg = "人数摄像头通讯异常"; + } + } + #endregion + + #region 故障记录 + DeviceError tempErr = CacheService.Get($"DeviceError:{deviceData.Id}").Result; + if (!string.IsNullOrEmpty(deviceData.ErrCode)) + { + if (tempErr == null || (tempErr != null && tempErr.ErrCode != deviceData.ErrCode)) + { + if (tempErr != null) + { + tempErr.EndDate = DateTime.Now; + Db.Updateable(tempErr).UpdateColumns(x => x.EndDate).SplitTable().ExecuteCommand(); + } + tempErr = new DeviceError() + { + Id = Guid.NewGuid().ToString(), + ErrCode = deviceData.ErrCode, + ErrMsg = deviceData.ErrMsg, + DeviceId = deviceData.Id, + CreateDate = DateTime.Now + }; + Db.Insertable(tempErr).SplitTable().ExecuteCommand(); + + CacheService.Set($"DeviceError:{deviceData.Id}", tempErr); + } + } + else + { + if (tempErr != null) + { + tempErr.EndDate = DateTime.Now; + Db.Updateable(tempErr).UpdateColumns(x => x.EndDate).SplitTable().ExecuteCommand(); + CacheService.Delete($"DeviceError:{deviceData.Id}"); + } + } + #endregion + return Task.CompletedTask; + } + + private void InitDeviceError() + { + Db.Updateable().SetColumns(x => x.ErrCode == "").SetColumns(x => x.ErrMsg == "").Where(x => 1 == 1).ExecuteCommand(); + Db.Updateable().SetColumns(x => x.EndDate == DateTime.Now).Where(x => x.EndDate == null).SplitTable(tas => tas.Take(2)).ExecuteCommand(); + } + + public async Task> GetDeviceErrorPage(PageYearSearch search) + { + RefAsync _Total = 0; + var Data = await Db.Queryable() + .WhereIF(!string.IsNullOrEmpty(search.Search), x => x.Id!.Contains(search.Search!) || x.DeviceId!.Contains(search.Search!) || x.ErrCode!.Contains(search.Search!) || x.ErrMsg!.Contains(search.Search!)) + .WhereIF(search.Mode != null && !string.IsNullOrEmpty(search.Mode.Id), x => x.Id == search.Mode!.Id) + .WhereIF(search.Mode != null && !string.IsNullOrEmpty(search.Mode.DeviceId), x => x.DeviceId == search.Mode!.DeviceId) + .WhereIF(search.Mode != null && !string.IsNullOrEmpty(search.Mode.ErrCode), x => x.ErrCode == search.Mode!.ErrCode) + .WhereIF(search.Mode != null && !string.IsNullOrEmpty(search.Mode.ErrMsg), x => x.ErrMsg!.Contains(search.Mode!.ErrMsg!)) + .SplitTable((DateTime)search.StartDate!, (DateTime)search.EndDate!) + .OrderByDescending(x => x.CreateDate) + .ToPageListAsync(search.Index, search.Size, _Total); + return new PageData { Total = _Total.Value, Data = Data }; + } + + private void SeteData22Error(DeviceData deviceData) + { + #region 创安处理逻辑 + if (deviceData.Id!.IndexOf("CASSH") >= 0) + { + //修复默认值传1的问题 + if (deviceData.Data22 == 1) + { + deviceData.Data22 = 0; + } + + if (deviceData.Data3_B5 == 0) + { + deviceData.Data22 = 1; + } + if (deviceData.Data15_B0 == 0 && deviceData.Data3_B6 == 0) + { + deviceData.Data22 = 2; + } + if (deviceData.Data15_B2 == 0 && deviceData.Data3_B7 == 0) + { + deviceData.Data22 = 3; + } + if (deviceData.Data3_B4 == 0) + { + deviceData.Data22 = 4; + } + //if (deviceData.Data3_B3 == 0) + //{ + // deviceData.Data22 = 5; + //} + if (deviceData.Data2_B3 == 0) + { + deviceData.Data22 = 6; + } + if (deviceData.Data2_B2 == 0) + { + deviceData.Data22 = 7; + } + if (deviceData.Data2_B1 == 0) + { + deviceData.Data22 = 8; + } + if (deviceData.Data27_B7 == 1) + { + deviceData.Data22 = 9; + } + if (deviceData.Data27_B6 == 1) + { + deviceData.Data22 = 10; + } + if (deviceData.Data2_B5 == 0) + { + deviceData.Data22 = 11; + } + if (deviceData.Data2_B4 == 0) + { + deviceData.Data22 = 12; + } + if (deviceData.Data2_B6 == 0) + { + deviceData.Data22 = 13; + } + if (deviceData.Data16_B1 == 0) + { + var ticks = CacheService.Get($"{deviceData.Id}_Data16_B1").Result; + if (ticks != 0) + { + var time = new TimeSpan(DateTime.Now.Ticks).Subtract(new TimeSpan(ticks)); + if (time.TotalSeconds > 10 && time.TotalMinutes <= 5) + { + deviceData.Data22 = 101; + } + else if (time.TotalMinutes > 5) + { + deviceData.Data22 = 102; + } + } + else + { + CacheService.Set($"{deviceData.Id}_Data16_B1", DateTime.Now.Ticks); + } + } + else + { + CacheService.Delete($"{deviceData.Id}_Data16_B1"); + } + if (deviceData.Data16_B0 == 0) + { + var ticks = CacheService.Get($"{deviceData.Id}_Data16_B0").Result; + if (ticks != 0) + { + var time = new TimeSpan(DateTime.Now.Ticks).Subtract(new TimeSpan(ticks)); + if (time.TotalSeconds > 10 && time.TotalMinutes <= 5) + { + deviceData.Data22 = 103; + } + else if (time.TotalMinutes > 5) + { + deviceData.Data22 = 104; + } + } + else + { + CacheService.Set($"{deviceData.Id}_Data16_B0", DateTime.Now.Ticks); + } + } + else + { + CacheService.Delete($"{deviceData.Id}_Data16_B0"); + } + if (deviceData.Data15_B3 == 0 && deviceData.Data15_B2 == 0) + { + deviceData.Data22 = 37; + } + if (deviceData.Data15_B1 == 0 && deviceData.Data15_B0 == 0) + { + deviceData.Data22 = 38; + } + } + if (deviceData.Data23 == 0) + { + deviceData.Data22 = 100; + } + #endregion + if (deviceData.Data22 != null && deviceData.Data22 > 0) + { + switch (deviceData.Data22) + { + case 1: + deviceData.ErrCode = "YY001"; + deviceData.ErrMsg = "天窗门未关好"; + break; + case 2: + deviceData.ErrCode = "YY002"; + deviceData.ErrMsg = "双开门未关好"; + break; + case 3: + deviceData.ErrCode = "YY003"; + deviceData.ErrMsg = "单开门未关好"; + break; + case 4: + deviceData.ErrCode = "YY004"; + deviceData.ErrMsg = "上限位已断开"; + break; + case 5: + deviceData.ErrCode = "YY005"; + deviceData.ErrMsg = "下限位已断开"; + break; + case 6: + deviceData.ErrCode = "YY006"; + deviceData.ErrMsg = "请注意防坠器限位已断开"; + break; + case 7: + deviceData.ErrCode = "YY007"; + deviceData.ErrMsg = "请注意防冲顶限位已断开"; + break; + case 8: + deviceData.ErrCode = "YY008"; + deviceData.ErrMsg = "请注意备用限位已断开"; + break; + case 9: + deviceData.ErrCode = "YY009"; + deviceData.ErrMsg = "电梯控制远程限速"; + break; + case 10: + deviceData.ErrCode = "YY010"; + deviceData.ErrMsg = "电梯控制远程锁机"; + break; + case 11: + deviceData.ErrCode = "YY011"; + deviceData.ErrMsg = "急停按钮已被按下"; + break; + case 12: + deviceData.ErrCode = "YY012"; + deviceData.ErrMsg = "笼顶急停按钮已被按下"; + break; + case 13: + deviceData.ErrCode = "YY013"; + deviceData.ErrMsg = "电锁或者IC卡未插好"; + break; + case 14: + deviceData.ErrCode = "YY014"; + deviceData.ErrMsg = "请注意编码器脉冲值异常"; + break; + case 15: + deviceData.ErrCode = "YY015"; + deviceData.ErrMsg = "请注意电梯发生逆变单元保护故障"; + break; + case 16: + deviceData.ErrCode = "YY016"; + deviceData.ErrMsg = "请注意电梯发生过流故障"; + break; + case 17: + deviceData.ErrCode = "YY017"; + deviceData.ErrMsg = "请注意电梯发生过压故障"; + break; + case 18: + deviceData.ErrCode = "YY018"; + deviceData.ErrMsg = "请注意电梯发生欠压故障"; + break; + case 19: + deviceData.ErrCode = "YY019"; + deviceData.ErrMsg = "请注意电梯发生驱动器过载故障"; + break; + case 20: + deviceData.ErrCode = "YY020"; + deviceData.ErrMsg = "请注意电梯发生模块过热故障"; + break; + case 21: + deviceData.ErrCode = "YY021"; + deviceData.ErrMsg = "请注意电梯发生对地短路故障"; + break; + case 22: + deviceData.ErrCode = "YY022"; + deviceData.ErrMsg = "请注意电梯发生输入缺相故障"; + break; + case 23: + deviceData.ErrCode = "YY023"; + deviceData.ErrMsg = "请注意电梯发生输出缺相故障"; + break; + case 24: + deviceData.ErrCode = "YY024"; + deviceData.ErrMsg = "请注意电梯自检异常"; + break; + case 25: + deviceData.ErrCode = "YY025"; + deviceData.ErrMsg = "请注意电梯已超载"; + break; + case 26: + deviceData.ErrCode = "YY026"; + deviceData.ErrMsg = "请注意编码器故障"; + break; + case 27: + deviceData.ErrCode = "YY027"; + deviceData.ErrMsg = "请注意刹车电流过大"; + break; + case 28: + deviceData.ErrCode = "YY028"; + deviceData.ErrMsg = "请注意刹车信号故障"; + break; + case 29: + deviceData.ErrCode = "YY029"; + deviceData.ErrMsg = "请注意刹车电流较小"; + break; + case 30: + deviceData.ErrCode = "YY030"; + deviceData.ErrMsg = "请注意刹车片磨损严重"; + break; + case 31: + deviceData.ErrCode = "YY031"; + deviceData.ErrMsg = "请注意电梯超速"; + break; + case 32: + deviceData.ErrCode = "YY032"; + deviceData.ErrMsg = "进料门有异物卡住"; + break; + case 33: + deviceData.ErrCode = "YY033"; + deviceData.ErrMsg = "出料门有异物卡住"; + break; + case 34: + deviceData.ErrCode = "YY034"; + deviceData.ErrMsg = "门机发生故障"; + break; + case 35: + deviceData.ErrCode = "YY035"; + deviceData.ErrMsg = "人数超载请自觉退出"; + break; + case 36: + deviceData.ErrCode = "WR036"; + deviceData.ErrMsg = "请勿遮挡光幕"; + break; + case 37: + deviceData.ErrCode = "YY037"; + deviceData.ErrMsg = "进料门上下限位异常"; + break; + case 38: + deviceData.ErrCode = "YY038"; + deviceData.ErrMsg = "出料门上下限位异常"; + break; + case 39: + deviceData.ErrCode = "YY039"; + deviceData.ErrMsg = "请勿遮挡光幕"; + break; + case 40: + deviceData.ErrCode = "YY040"; + deviceData.ErrMsg = "上行通道限位断开"; + break; + case 41: + deviceData.ErrCode = "YY041"; + deviceData.ErrMsg = "下行通道限位断开"; + break; + case 100: + deviceData.ErrCode = "YY100"; + deviceData.ErrMsg = "请打开自动平层开关"; + break; + case 101: + deviceData.ErrCode = "WR101"; + deviceData.ErrMsg = "请勿遮挡进料门光幕"; + break; + case 102: + deviceData.ErrCode = "YY102"; + deviceData.ErrMsg = "请勿遮挡进料门光幕"; + break; + case 103: + deviceData.ErrCode = "WR103"; + deviceData.ErrMsg = "请勿遮挡出料门光幕"; + break; + case 104: + deviceData.ErrCode = "YY104"; + deviceData.ErrMsg = "请勿遮挡出料门光幕"; + break; + default: + break; + } + } + } + + private void SetData17Error(DeviceData deviceData) + { + switch (deviceData.Data17) + { + case 2: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "加速过电流"; + break; + case 3: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "减速过电流"; + break; + case 4: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "恒速过电流"; + break; + case 5: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "加速过电压"; + break; + case 6: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "减速过电压"; + break; + case 7: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "恒速过电压"; + break; + case 8: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "控制电源异常"; + break; + case 9: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "欠电压"; + break; + case 10: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "变频器过载"; + break; + case 11: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "电机过载"; + break; + case 12: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "输入缺相"; + break; + case 13: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "输出缺相"; + break; + case 14: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "模块过热"; + break; + case 15: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "外部故障"; + break; + case 16: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "通讯异常"; + break; + case 17: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "接触器异常"; + break; + case 18: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "电流检测异常"; + break; + case 19: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "电机调谐异常"; + break; + case 20: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "编码器/PG卡异常"; + break; + case 21: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "EPPROM读写异常"; + break; + case 22: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "变频器硬件故障"; + break; + case 23: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "电机对地短路"; + break; + case 26: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "累计运行时间到达"; + break; + case 29: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "累计上电时间到达"; + break; + case 30: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "掉载"; + break; + case 31: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "运行时PID反馈丢失"; + break; + case 40: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "CBC限流保护"; + break; + case 42: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "速度偏差过大"; + break; + case 43: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "过速度"; + break; + case 45: + deviceData.ErrCode = "门机故障"; + deviceData.ErrMsg = "电机过热"; + break; + default: + break; + } + } + + private void SetData5Error(DeviceData deviceData) + { + switch (deviceData.Data5) + { + case 1: + deviceData.ErrCode = "Pb01"; + deviceData.ErrMsg = "超载"; + break; + case 2: + deviceData.ErrCode = "Pb02"; + deviceData.ErrMsg = "超载报警"; + break; + case 3: + deviceData.ErrCode = "Pb03"; + deviceData.ErrMsg = "EEPROM 存储故障"; + break; + case 4: + deviceData.ErrCode = "Pb04"; + deviceData.ErrMsg = "编码器故障"; + break; + case 5: + deviceData.ErrCode = "Pb05"; + deviceData.ErrMsg = "刹车电流过大"; + break; + case 6: + deviceData.ErrCode = "Pb06"; + deviceData.ErrMsg = "刹车信号故障"; + break; + case 7: + deviceData.ErrCode = "Pb07"; + deviceData.ErrMsg = "运行时抱闸未及时打开"; + break; + case 8: + deviceData.ErrCode = "Pb08"; + deviceData.ErrMsg = "停机时抱闸未及时断开"; + break; + case 9: + deviceData.ErrCode = "Pb09"; + deviceData.ErrMsg = "刹车片磨损较大"; + break; + case 10: + deviceData.ErrCode = "Pb10"; + deviceData.ErrMsg = "变频器通讯故障"; + break; + case 11: + deviceData.ErrCode = "Pb11"; + deviceData.ErrMsg = "运行超速故障"; + break; + case 13: + deviceData.ErrCode = "Pb13"; + deviceData.ErrMsg = "输入缺相"; + break; + case 41: + deviceData.ErrCode = "Pb41"; + deviceData.ErrMsg = "工频输出接触器未吸合"; + break; + case 42: + deviceData.ErrCode = "Pb42"; + deviceData.ErrMsg = "工频输出接触器异常吸合"; + break; + case 43: + deviceData.ErrCode = "Pb43"; + deviceData.ErrMsg = "工频输入电源相序错误"; + break; + case 44: + deviceData.ErrCode = "Pb44"; + deviceData.ErrMsg = "工频上升接触器黏连"; + break; + case 45: + deviceData.ErrCode = "Pb45"; + deviceData.ErrMsg = "工频下降接触器黏连"; + break; + default: + break; + } + } + + private void SetData4Error(DeviceData deviceData) + { + switch (deviceData.Data4) + { + case 1: + deviceData.ErrCode = "ERR01"; + deviceData.ErrMsg = "逆变单元保护"; + break; + case 2: + deviceData.ErrCode = "ERR02"; + deviceData.ErrMsg = "硬件过流"; + break; + case 3: + deviceData.ErrCode = "ERR03"; + deviceData.ErrMsg = "硬件过压"; + break; + case 4: + deviceData.ErrCode = "ERR04"; + deviceData.ErrMsg = "加速过电流"; + break; + case 5: + deviceData.ErrCode = "ERR05"; + deviceData.ErrMsg = "减速过电流"; + break; + case 6: + deviceData.ErrCode = "ERR06"; + deviceData.ErrMsg = "恒速过电流"; + break; + case 7: + deviceData.ErrCode = "ERR07"; + deviceData.ErrMsg = "停止过电流"; + break; + case 8: + deviceData.ErrCode = "ERR08"; + deviceData.ErrMsg = "加速过电压"; + break; + case 9: + deviceData.ErrCode = "ERR09"; + deviceData.ErrMsg = "减速过电压"; + break; + case 10: + deviceData.ErrCode = "ERR10"; + deviceData.ErrMsg = "恒速过电压"; + break; + case 11: + deviceData.ErrCode = "ERR11"; + deviceData.ErrMsg = "停止过电压"; + break; + case 12: + deviceData.ErrCode = "ERR12"; + deviceData.ErrMsg = "欠压故障"; + break; + case 13: + deviceData.ErrCode = "ERR13"; + deviceData.ErrMsg = "驱动器过载"; + break; + case 14: + deviceData.ErrCode = "ERR14"; + deviceData.ErrMsg = "电机过载"; + break; + case 15: + deviceData.ErrCode = "ERR15"; + deviceData.ErrMsg = "模块过热"; + break; + case 16: + deviceData.ErrCode = "ERR16"; + deviceData.ErrMsg = "AD转换故障"; + break; + case 17: + deviceData.ErrCode = "ERR17"; + deviceData.ErrMsg = "IU电流检测故障"; + break; + case 18: + deviceData.ErrCode = "ERR18"; + deviceData.ErrMsg = "IV电流检测故障"; + break; + case 19: + deviceData.ErrCode = "ERR19"; + deviceData.ErrMsg = "IW电流检测故障"; + break; + case 20: + deviceData.ErrCode = "ERR20"; + deviceData.ErrMsg = "对地短路故障"; + break; + case 21: + deviceData.ErrCode = "ERR21"; + deviceData.ErrMsg = "电机参数调谐故障"; + break; + case 23: + deviceData.ErrCode = "ERR23"; + deviceData.ErrMsg = "输入缺相"; + break; + case 24: + deviceData.ErrCode = "ERR24"; + deviceData.ErrMsg = "输出缺相"; + break; + case 25: + deviceData.ErrCode = "ERR25"; + deviceData.ErrMsg = "存储器故障"; + break; + case 26: + deviceData.ErrCode = "ERR26"; + deviceData.ErrMsg = "密码输入错误超过3次"; + break; + case 27: + deviceData.ErrCode = "ERR27"; + deviceData.ErrMsg = "通信故障"; + break; + case 28: + deviceData.ErrCode = "ERR28"; + deviceData.ErrMsg = "外部故障"; + break; + default: + break; + } + } + + private Task SetRunCount(DeviceData deviceData) + { + deviceData.RunCount = CacheService.Get($"{deviceData.Id}_RunCount").Result; + if (deviceData.RunCount == 0) + { + var temp = Db.Queryable().Single(x => x.Id == deviceData.Id); + deviceData.RunCount = temp == null ? 0 : temp.RunCount; + if (deviceData.RunCount != null) + { + CacheService.Set($"{deviceData.Id}_RunCount", (int)deviceData.RunCount!); + } + } + + if (deviceData.MsgType == "1103" && deviceData.Data11 == 1) + { + + var OldData11 = CacheService.Get($"{deviceData.Id}_Data11").Result; + + if (OldData11 > 1) + { + Db.Updateable().SetColumns(x => x.RunCount == x.RunCount + 1).Where(x => x.Id == deviceData.Id).ExecuteCommand(); + deviceData.RunCount = Db.Queryable().Single(x => x.Id == deviceData.Id).RunCount; + if (deviceData.RunCount != null) + { + CacheService.Set($"{deviceData.Id}_RunCount", (int)deviceData.RunCount!); + } + } + } + if (deviceData.Data11 != null) + { + CacheService.Set($"{deviceData.Id}_Data11", (int)deviceData.Data11!); + } + return Task.CompletedTask; + } + + #region 故障统计 + /// + /// 获取设备故障报表 + /// + /// 报表筛选 + /// + public async Task GetDeviceErrorReport(DeviceErrorReport report) + { + #region 有效校验 + var TempDate = DateTime.Now; + if (report.StartDate == null) + { + report.StartDate = TempDate.AddDays(-TempDate.Day); + } + if (report.EndDate == null) + { + report.EndDate = TempDate; + } + var TempUnits = new string[] { "year", "month", "day" }; + if (!string.IsNullOrEmpty(report.Unit) && !TempUnits.Any(x => x == report.Unit.ToLower())) + { + throw new ArgumentException("单元无效"); + } + + + #endregion + + } + #endregion + } +} diff --git a/LanSheng/LanShengService/LanShengService.cs b/LanSheng/LanShengService/LanShengService.cs new file mode 100644 index 0000000..8e8e8ef --- /dev/null +++ b/LanSheng/LanShengService/LanShengService.cs @@ -0,0 +1,52 @@ +using CacheService; +using CommonExtend; +using Dapr.Client; +using LanShengInterface; +using LanShengService.Tcp; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengService +{ + public static class LanShengServiceExtend + { + public static IServiceCollection InitLanShengService(this IServiceCollection services, IConfiguration configuration) + { + + SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig() + { + DbType = SqlSugar.DbType.MySql, + ConnectionString = configuration.GetConnectionString("Default"), + IsAutoCloseConnection = true, + }); + + services.AddSingleton(sqlSugar); + services.AddSingleton(); + services.AddSingleton(); + services.InitMemoryCacheService(); + return services; + } + + public static IApplicationBuilder CreateLanShengService(this IApplicationBuilder app) + { + Task.Run(() => + { + app.ApplicationServices.GetRequiredService(); + }); + + return app; + } + } + + public class LanShengService + { + } +} diff --git a/LanSheng/LanShengService/LanShengService.csproj b/LanSheng/LanShengService/LanShengService.csproj new file mode 100644 index 0000000..860fae2 --- /dev/null +++ b/LanSheng/LanShengService/LanShengService.csproj @@ -0,0 +1,33 @@ + + + + net7.0 + enable + enable + false + true + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LanSheng/LanShengService/Tcp/ChannelHandler.cs b/LanSheng/LanShengService/Tcp/ChannelHandler.cs new file mode 100644 index 0000000..9815c63 --- /dev/null +++ b/LanSheng/LanShengService/Tcp/ChannelHandler.cs @@ -0,0 +1,119 @@ +using CommonModel; +using DotNetty.Transport.Channels; +using DotNetty.Transport.Channels.Groups; +using Google.Api; +using LanShengInterface; +using LanShengModel; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace LanShengService.Tcp +{ + public class ChannelHandler : ChannelHandlerAdapter + { + public ChannelHandler(IServiceProvider services) + { + Services = services; + Logger = Services.GetRequiredService>(); + DeviceService = Services.GetRequiredService(); + TcpService = Services.GetRequiredService(); + } + + private readonly IServiceProvider Services; + + private readonly IDeviceService DeviceService; + + private readonly ILogger Logger; + + private readonly ITcpService TcpService; + + private int TryCount = 0; + + private string DTU_Id = ""; + + public override async void ChannelRead(IChannelHandlerContext context, object message) + { + var packet = message as TcpDataLog; + DTU_Id = packet!.DTU_ID!; + Logger.LogDebug($"接收到数据:{JsonSerializer.Serialize>(packet!)}"); + await TcpService.AddChannel(packet!.DTU_ID!, context); + await DeviceService.InsertDataLog(packet!); + + if (packet!.Content != null) + { + await DeviceService.InsertData(packet!.Content); + } + + if (packet.Msg_ID == "1001" || packet.Msg_ID == "1103") + { + var Reply = new TcpDataLog + { + Frame_START = packet.Frame_START, + Frame_number = packet.Frame_number, + DTU_ID = packet.DTU_ID, + Frame_END = packet.Frame_END + }; + if (packet.Msg_ID == "1001") + { + Reply.Msg_ID = "9001"; + } + if (packet.Msg_ID == "1103") + { + Reply.Msg_ID = "9103"; + } + try + { + await context.WriteAndFlushAsync(Reply); + } + catch + { + await context.CloseAsync(); + } + } + if (packet.Msg_ID == "9104") + { + await TcpService.RemoveMessageItem(packet); + } + TryCount = 0; + } + + public override void ChannelReadComplete(IChannelHandlerContext context) + { + context.Flush(); + } + + public override void ExceptionCaught(IChannelHandlerContext context, Exception exception) + { + TryCount++; + + Logger.LogError(exception.ToString()); + + if (TryCount >= 5) + { + context.CloseAsync(); + } + } + + public override async void ChannelActive(IChannelHandlerContext context) + { + await TcpService.AddChannel("all", context); + base.ChannelActive(context); + } + + public override async void ChannelInactive(IChannelHandlerContext context) + { + if (!string.IsNullOrEmpty(DTU_Id)) + { + await DeviceService.Offline(DTU_Id); + } + await context.CloseAsync(); + base.ChannelInactive(context); + } + } +} diff --git a/LanSheng/LanShengService/Tcp/DecoderHandler.cs b/LanSheng/LanShengService/Tcp/DecoderHandler.cs new file mode 100644 index 0000000..0bd7227 --- /dev/null +++ b/LanSheng/LanShengService/Tcp/DecoderHandler.cs @@ -0,0 +1,178 @@ +using DotNetty.Buffers; +using DotNetty.Codecs; +using DotNetty.Transport.Channels; +using LanShengModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CommonExtend; +using CommonModel; + +namespace LanShengService.Tcp +{ + public class DecoderHandler : ByteToMessageDecoder + { + protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) + { + var request = new TcpDataLog(); + if (!input.HasArray) + { + return; + } + while (input.ReadableBytes >= 2) + { + if (input.ReadHex(1) == "FA") + { + if (input.ReadHex(1) == "AA") + { + request.Frame_START = "FAAA"; + break; + } + else + { + input.SetReaderIndex(input.ReaderIndex - 1); + } + } + } + if (request.Frame_START != "FAAA") + { + return; + } + int ReadableBytes = input.ReadableBytes + 2; + if (ReadableBytes < 4) + { + input.SetReaderIndex(input.ReaderIndex - 2); + return; + } + request.Frame_Length = input.ReadInt(2); + if (ReadableBytes < request.Frame_Length) + { + input.ResetReaderIndex(); + return; + } + request.Frame_number = input.ReadInt(2); + request.DTU_ID = input.ReadString(17, Encoding.ASCII); + request.Msg_ID = input.ReadHex(2); + IByteBuffer Content = Unpooled.Buffer((int)request.Frame_Length - 25 - 4); + input.ReadBytes(Content, (int)request.Frame_Length - 25 - 4); + try + { + request.Content = new DeviceData(); + request.Content.Id = request.DTU_ID; + request.Content.Status = "online"; + request.Content.UpdateDate = DateTime.Now; + request.Content.MsgType = request.Msg_ID; + switch (request.Msg_ID) + { + case "1001": + case "9104": + request.Content.AgreementVersion = Content.ReadInt(1); + request.Content.DataTick = Content.ReadInt(2); + request.Content.ICCID = Content.ReadString(20, Encoding.ASCII); + Content.SkipBytes(4); + request.Content.Longitude = Content.ReadString(9, Encoding.ASCII); + request.Content.Latitude = Content.ReadString(8, Encoding.ASCII); + request.Content.ConnectStrLength = Content.ReadInt(1); + request.Content.ConnectString = Content.ReadString((int)request.Content.ConnectStrLength, Encoding.ASCII); + break; + case "1103": + request.Content.Version = Content.ReadInt(1); + var Data2 = Content.ReadBitArray(); + request.Content.Data2_B7 = Data2[0]; + request.Content.Data2_B6 = Data2[1]; + request.Content.Data2_B5 = Data2[2]; + request.Content.Data2_B4 = Data2[3]; + request.Content.Data2_B3 = Data2[4]; + request.Content.Data2_B2 = Data2[5]; + request.Content.Data2_B1 = Data2[6]; + request.Content.Data2_B0 = Data2[7]; + var Data3 = Content.ReadBitArray(); + request.Content.Data3_B7 = Data3[0]; + request.Content.Data3_B6 = Data3[1]; + request.Content.Data3_B5 = Data3[2]; + request.Content.Data3_B4 = Data3[3]; + request.Content.Data3_B3 = Data3[4]; + request.Content.Data3_B2 = Data3[5]; + request.Content.Data3_B1 = Data3[6]; + request.Content.Data3_B0 = Data3[7]; + request.Content.Data4 = Content.ReadInt(1); + request.Content.Data5 = Content.ReadInt(1); + request.Content.Data6 = Content.ReadInt(1); + request.Content.Data7 = Content.ReadInt(1); + request.Content.Data8 = Content.ReadInt(2); + request.Content.Data10 = Content.ReadInt(1); + request.Content.Data11 = Content.ReadInt(1); + request.Content.Data12 = Content.ReadInt(1); + request.Content.Data13 = Content.ReadInt(1); + var Data14 = Content.ReadBitArray(); + request.Content.Data14_B6 = Convert.ToInt32($"{Data14[1]}{Data14[0]}", 2); + request.Content.Data14_B5 = Data14[2]; + request.Content.Data14_B4 = Data14[3]; + request.Content.Data14_B3 = Data14[4]; + request.Content.Data14_B2 = Data14[5]; + request.Content.Data14_B1 = Data14[6]; + request.Content.Data14_B0 = Data14[7]; + var Data15 = Content.ReadBitArray(); + request.Content.Data15_B6 = Convert.ToInt32($"{Data15[1]}{Data15[0]}", 2); + request.Content.Data15_B4 = Convert.ToInt32($"{Data15[3]}{Data15[2]}", 2); + request.Content.Data15_B3 = Data15[4]; + request.Content.Data15_B2 = Data15[5]; + request.Content.Data15_B1 = Data15[6]; + request.Content.Data15_B0 = Data15[7]; + var Data16 = Content.ReadBitArray(); + request.Content.Data16_B7 = Data16[0]; + request.Content.Data16_B6 = Data16[1]; + request.Content.Data16_B5 = Data16[2]; + request.Content.Data16_B4 = Data16[3]; + request.Content.Data16_B2 = Convert.ToInt32($"{Data16[5]}{Data16[4]}", 2); + request.Content.Data16_B1 = Data16[6]; + request.Content.Data16_B0 = Data16[7]; + request.Content.Data17 = Content.ReadInt(1); + request.Content.Data18 = Content.ReadInt(1); + request.Content.Data19 = Content.ReadInt(1); + request.Content.Data20 = Content.ReadInt(1); + request.Content.Data21 = Content.ReadInt(1); + request.Content.Data22 = Content.ReadInt(1); + request.Content.Data23 = Content.ReadInt(1); + request.Content.Data24 = Content.ReadInt(1); + var Data25 = Content.ReadBitArray(); + request.Content.Data25_B4 = Convert.ToInt32($"{Data25[3]}{Data25[2]}{Data25[1]}{Data25[0]}", 2); + request.Content.Data25_B0 = Convert.ToInt32($"{Data25[7]}{Data25[6]}{Data25[5]}{Data25[4]}", 2); + var Data26 = Content.ReadBitArray(); + request.Content.Data26_B4 = Convert.ToInt32($"{Data26[3]}{Data26[2]}{Data26[1]}{Data26[0]}", 2); + request.Content.Data26_B0 = Convert.ToInt32($"{Data26[7]}{Data26[6]}{Data26[5]}{Data26[4]}", 2); + var Data27 = Content.ReadBitArray(); + request.Content.Data27_B7 = Data27[0]; + request.Content.Data27_B6 = Data27[1]; + request.Content.Data27_B5 = Data27[2]; + request.Content.Data27_B4 = Data27[3]; + request.Content.Data27_B3 = Data27[4]; + request.Content.Data27_B0 = Data27[7]; + break; + default: + break; + } + request.Content = request.Content; + } + catch + { + request.Content = null; + } + request.Checksum = input.ReadInt(2); + request.Frame_END = input.ReadHex(2); + request.CreateDate = DateTime.Now; + if (request.Frame_END == "BBFB") + { + output.Add(request); + Content.Clear(); + input.Clear(); + } + else + { + return; + } + } + } +} diff --git a/LanSheng/LanShengService/Tcp/EncoderHandler.cs b/LanSheng/LanShengService/Tcp/EncoderHandler.cs new file mode 100644 index 0000000..cca8324 --- /dev/null +++ b/LanSheng/LanShengService/Tcp/EncoderHandler.cs @@ -0,0 +1,72 @@ +using CommonExtend; +using CommonModel; +using DotNetty.Buffers; +using DotNetty.Codecs; +using DotNetty.Transport.Channels; +using LanShengModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengService.Tcp +{ + public class EncoderHandler : MessageToByteEncoder> + { + protected override void Encode(IChannelHandlerContext context, TcpDataLog message, IByteBuffer output) + { + List Temp = new List(); + Temp.AddRange(message.Frame_START!.HexString2Byte().BytePadLeft(2)); + Temp.AddRange(((int)message.Frame_number!).Int2Byte().BytePadLeft(2)); + Temp.AddRange(Encoding.ASCII.GetBytes(message.DTU_ID!).BytePadLeft(17)); + Temp.AddRange(message.Msg_ID!.HexString2Byte().BytePadLeft(2)); + switch (message.Msg_ID) + { + case "1104": + Temp.AddRange(((int)message.Content!.Version!).Int2Byte().BytePadLeft(1)); + Temp.AddRange(((int)message.Content!.DataTick!).Int2Byte().BytePadLeft(2)); + int[] Data1 = new int[] { + (int)message.Content!.Data27_B7!, + (int)message.Content!.Data27_B6!, + (int)message.Content!.Data27_B5!, + (int)message.Content!.Data27_B4!, + (int)message.Content!.Data27_B3!, + 0, + 0, + (int)message.Content!.Data27_B0!, + }; + Temp.AddRange(Data1.BitArray2Byte()); + int[] Data2 = new int[] { + (int)message.Content!.Data23!, + (int)message.Content!.Data20!, + (int)message.Content!.Data19!, + (int)message.Content!.Data18!, + ((int)message.Content!.Data16_B2!).Int2Bit(2)[1], + ((int)message.Content!.Data16_B2!).Int2Bit(2)[0], + 0, + 0 + }; + Temp.AddRange(Data2.BitArray2Byte()); + Temp.AddRange(((int)message.Content.Data25_B4!).Int2Byte().BytePadLeft(1)); + Temp.AddRange(((int)message.Content.Data25_B0!).Int2Byte().BytePadLeft(1)); + Temp.AddRange(((int)message.Content.Data26_B4!).Int2Byte().BytePadLeft(1)); + Temp.AddRange(((int)message.Content.Data26_B0!).Int2Byte().BytePadLeft(1)); + Temp.AddRange(((int)message.Content.UpdateTag!).Int2Byte().BytePadLeft(1)); + var ConnectByte = Encoding.ASCII.GetBytes(message.Content.ConnectString!); + message.Content.ConnectStrLength = message.Content.ConnectString!.Length; + Temp.AddRange(((int)message.Content.ConnectStrLength!).Int2Byte().BytePadLeft(1)); + Temp.AddRange(ConnectByte); + break; + default: + break; + } + message.Frame_Length = Temp.Count + 6; + Temp.InsertRange(2, ((int)message.Frame_Length!).Int2Byte().BytePadLeft(2)); + message.Checksum = Temp.ToArray().Byte2HexSum(); + Temp.AddRange(((int)message.Checksum!).Int2Byte().BytePadLeft(2)); + Temp.AddRange(message.Frame_END!.HexString2Byte().BytePadLeft(2)); + output.WriteBytes(Temp.ToArray()); + } + } +} diff --git a/LanSheng/LanShengService/Tcp/HeartBeatHandler.cs b/LanSheng/LanShengService/Tcp/HeartBeatHandler.cs new file mode 100644 index 0000000..d5a05c1 --- /dev/null +++ b/LanSheng/LanShengService/Tcp/HeartBeatHandler.cs @@ -0,0 +1,40 @@ +using DotNetty.Handlers.Timeout; +using DotNetty.Transport.Channels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LanShengService.Tcp +{ + public class HeartBeatHandler : ChannelHandlerAdapter + { + /// + /// Heart Beat Handler. + /// + /// + /// + public override async void UserEventTriggered(IChannelHandlerContext context, object evt) + { + var eventState = evt as IdleStateEvent; + if (eventState != null) + { + if (eventState.State == IdleState.ReaderIdle) + { + await context.CloseAsync(); + } + else if (eventState.State == IdleState.WriterIdle) + { + } + else if (eventState.State == IdleState.AllIdle) + { + } + } + else + { + base.UserEventTriggered(context, evt); + } + } + } +} diff --git a/LanSheng/LanShengService/TcpService.cs b/LanSheng/LanShengService/TcpService.cs new file mode 100644 index 0000000..6e9eda2 --- /dev/null +++ b/LanSheng/LanShengService/TcpService.cs @@ -0,0 +1,340 @@ +using Dapr.Actors.Client; +using Dapr.Actors; +using DotNetty.Buffers; +using DotNetty.Handlers.Logging; +using DotNetty.Handlers.Tls; +using DotNetty.Transport.Bootstrapping; +using DotNetty.Transport.Channels; +using DotNetty.Transport.Channels.Sockets; +using LanShengInterface; +using LanShengModel; +using LanShengService.Tcp; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Text.Json; +using System.Data; +using Microsoft.AspNetCore.DataProtection.KeyManagement; +using Dapr.Client; +using DotNetty.Transport.Channels.Groups; +using CommonModel; +using DotNetty.Handlers.Timeout; +using System.Diagnostics; + +namespace LanShengService +{ + public class TcpService : ITcpService + { + public TcpService(IServiceProvider services) + { + Services = services; + + Logger = services.GetRequiredService>(); + + Logger.LogDebug("创建Tcp服务"); + + DeviceService = services.GetRequiredService(); + + Db = services.GetRequiredService(); + + Db.CodeFirst.SplitTables().InitTables(typeof(TcpDataLog)); + + Logger.LogDebug("加载Tcp服务数据结构"); + + IConfiguration configuration = services.GetRequiredService()!; + + if (configuration.GetSection("DotNetty").Exists()) + { + + if (configuration.GetSection("DotNetty:Use").Exists()) + { + Use = configuration.GetSection("DotNetty:Use").Value!; + } + if (configuration.GetSection("DotNetty:ThreadPool").Exists()) + { + ThreadPool = Convert.ToInt32(configuration.GetSection("DotNetty:ThreadPool").Value!); + } + if (configuration.GetSection("DotNetty:Port").Exists()) + { + Port = Convert.ToInt32(configuration.GetSection("DotNetty:Port").Value!); + } + Logger.LogDebug("加载Tcp服务参数"); + } + + OpenTcpPort(); + } + + private readonly IServiceProvider Services; + + private readonly ILogger Logger; + + private readonly string Use = "N"; + + private readonly int ThreadPool = 1; + + private readonly int Port = 8888; + + private readonly ISqlSugarClient Db; + + private readonly IDeviceService DeviceService; + + private ServerBootstrap? Bootstrap; + + private IEventLoopGroup? BossGroup; + + private IEventLoopGroup? WorkerGroup; + + private Dictionary? ChannelGroups; + + private List>? MessageQueue; + + private async Task OpenTcpPort() + { + if (Use == "Y") + { + ChannelGroups = new Dictionary(); + + MessageQueue = new List>(); + + Bootstrap = new ServerBootstrap(); + + BossGroup = new MultithreadEventLoopGroup(ThreadPool); + + WorkerGroup = new MultithreadEventLoopGroup(); + + Logger.LogDebug("加载Tcp端口参数"); + + Bootstrap!.Group(BossGroup, WorkerGroup); + + Bootstrap.Channel(); + + Bootstrap + .Option(ChannelOption.SoBacklog, 1024) + .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) + .Option(ChannelOption.RcvbufAllocator,new AdaptiveRecvByteBufAllocator()) + .ChildOption(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) + .ChildOption(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator()) + .ChildOption(ChannelOption.SoKeepalive, true) + .ChildOption(ChannelOption.TcpNodelay, true) + .ChildOption(ChannelOption.SoReuseport, true) + .ChildHandler(new ActionChannelInitializer(channel => + { + IChannelPipeline Pipeline = channel.Pipeline; + Pipeline.AddLast(new IdleStateHandler(10, 0, 0));//心跳 + Pipeline.AddLast("encoder", new EncoderHandler()); + Pipeline.AddLast("decoder", new DecoderHandler()); + Pipeline.AddLast(new HeartBeatHandler()); + Pipeline.AddLast(new ChannelHandler(Services)); + })); + await Bootstrap.BindAsync(Port); + Logger.LogInformation($"启动Tcp端口监听{Port}"); + + DeviceService.TimerInsertDataDo(); + DeviceService.TimerInsertDataLogDo(); + AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; + } + } + + private void CurrentDomain_ProcessExit(object? sender, EventArgs e) + { + Logger.LogDebug("程序关闭"); + if (Use == "Y") + { + Task.WaitAll( + BossGroup!.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(0), TimeSpan.FromSeconds(0)), + WorkerGroup!.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(0), TimeSpan.FromSeconds(0))); + } + DeviceService.Offline().Wait(); + } + + public Task AddChannel(string id, IChannelHandlerContext context) + { + if (!ChannelGroups!.ContainsKey(id)) + { + lock (this) + { + if (!ChannelGroups!.ContainsKey(id)) + { + ChannelGroups.Add(id, new DefaultChannelGroup(context.Executor)); + } + } + } + if (!ChannelGroups[id].Contains(context.Channel)) + { + lock (this) + { + if (!ChannelGroups[id].Contains(context.Channel)) + { + ChannelGroups[id].Add(context.Channel); + Logger.LogDebug($"添加通道{id}:{context.Channel.Id.AsLongText()}"); + } + } + } + + return Task.CompletedTask; + } + + public async Task PushParams(DeviceData deviceData) + { + Logger.LogDebug($"下发指令{JsonSerializer.Serialize(deviceData)}"); + if (ChannelGroups == null) + { + throw new BadRequestException("连接服务器失败"); + } + else + { + if (!ChannelGroups.ContainsKey(deviceData.Id!)) + { + throw new BadRequestException("设备不在线"); + } + else + { + await ReloadPush(deviceData); + Random random = new Random(); + var Frame_number = 0; + do + { + Frame_number = random.Next(0, 20); + } + while (MessageQueue!.Any(x => x.DTU_ID == deviceData.Id && x.Frame_number == Frame_number)); + TcpDataLog packet = new TcpDataLog() + { + Frame_START = "FAAA", + Frame_number = Frame_number, + DTU_ID = deviceData.Id, + Msg_ID = "1104", + Frame_END = "BBFB", + Content = deviceData + }; + try + { + MessageQueue!.Add(packet); + await ChannelGroups[packet.DTU_ID!].WriteAndFlushAsync(packet); + } + catch + { + MessageQueue!.Remove(packet); + throw new BadRequestException("发送指令失败"); + } + await WaitPushReply(packet); + } + } + } + + private Task ReloadPush(DeviceData deviceData) + { + var oldData = Db.Queryable().Where(x => x.Id == deviceData.Id).First(); + + if (deviceData.Version == null) + { + deviceData.Version = oldData.Version; + } + if (deviceData.DataTick == null) + { + deviceData.DataTick = oldData.DataTick; + } + if (deviceData.Data27_B7 == null) + { + deviceData.Data27_B7 = oldData.Data27_B7; + } + if (deviceData.Data27_B6 == null) + { + deviceData.Data27_B6 = oldData.Data27_B6; + } + if (deviceData.Data27_B5 == null) + { + deviceData.Data27_B5 = oldData.Data27_B5; + } + if (deviceData.Data27_B4 == null) + { + deviceData.Data27_B4 = oldData.Data27_B4; + } + if (deviceData.Data27_B3 == null) + { + deviceData.Data27_B3 = oldData.Data27_B3; + } + if (deviceData.ConnectString != null && deviceData.ConnectString != oldData.ConnectString) + { + deviceData.Data27_B0 = 1; + } + else + { + deviceData.Data27_B0 = 0; + } + if (deviceData.Data23 == null) + { + deviceData.Data23 = oldData.Data23; + } + if (deviceData.Data20 == null) + { + deviceData.Data20 = oldData.Data20; + } + if (deviceData.Data19 == null) + { + deviceData.Data19 = oldData.Data19; + } + if (deviceData.Data18 == null) + { + deviceData.Data18 = oldData.Data18; + } + if (deviceData.Data16_B2 == null) + { + deviceData.Data16_B2 = oldData.Data16_B2; + } + if (deviceData.Data25_B4 == null) + { + deviceData.Data25_B4 = oldData.Data25_B4; + } + if (deviceData.Data25_B0 == null) + { + deviceData.Data25_B0 = oldData.Data25_B0; + } + if (deviceData.Data26_B4 == null) + { + deviceData.Data26_B4 = oldData.Data26_B4; + } + if (deviceData.Data26_B0 == null) + { + deviceData.Data26_B0 = oldData.Data26_B0; + } + if (deviceData.UpdateTag == null) + { + deviceData.UpdateTag = 0; + } + if (deviceData.ConnectString == null) + { + deviceData.ConnectString = oldData.ConnectString; + } + return Task.CompletedTask; + } + + private Task WaitPushReply(TcpDataLog packet) + { + var tryCount = 20; + while (MessageQueue!.Any((x => x.DTU_ID == packet.DTU_ID && x.Frame_number == packet.Frame_number))) + { + if (tryCount <= 0) + { + MessageQueue!.Remove(packet); + throw new BadRequestException("设备应答超时"); + } + Thread.Sleep(500); + tryCount--; + } + return Task.CompletedTask; + } + + public Task RemoveMessageItem(TcpDataLog packet) + { + Logger.LogDebug($"删除消息{JsonSerializer.Serialize(packet)}"); + MessageQueue!.RemoveAll((x) => x.DTU_ID == packet.DTU_ID && x.Frame_number == packet.Frame_number); + return Task.CompletedTask; + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce31bf0 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# FYCore \ No newline at end of file diff --git a/ZhongLian/ZhongLianAPI/Controllers/DriveController.cs b/ZhongLian/ZhongLianAPI/Controllers/DriveController.cs new file mode 100644 index 0000000..bed69de --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Controllers/DriveController.cs @@ -0,0 +1,71 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using ZhongLianInterface; +using ZhongLianModel; +using ZhongLianService; + +namespace ZhongLianAPI.Controllers +{ + /// + /// 文件接口 + /// + [Route("api/[controller]")] + [ApiController] + public class DriveController : ControllerBase + { + public DriveController(IDriveService driveService) + { + DriveService = driveService; + } + + private readonly IDriveService DriveService; + + /// + /// 上传文件 + /// + /// + /// + [DisableRequestSizeLimit] + [HttpPost("upload")] + public async Task Upload(IFormFile file) + { + if (file == null) + { + return BadRequest("上传失败"); + } + var File = new FileDO(); + File.FileName = file.FileName; + File.ContentType = file.ContentType; + File.Data = new byte[file.Length]; + file.OpenReadStream().Read(File.Data, 0, (int)file.Length); + var Msg = DriveService.InsertCheck(File); + if (string.IsNullOrEmpty(Msg)) + { + return Ok(await DriveService.Insert(File)); + } + else + { + return BadRequest(Msg); + } + } + + /// + /// 获取文件 + /// + /// 编号 + /// + [HttpGet("get")] + public async Task Get([FromQuery] string id) + { + var FileItem = await DriveService.Get(id); + if (FileItem != null) + { + return File(FileItem.Data!, FileItem.ContentType!); + } + else + { + return BadRequest("下载失败"); + } + } + } +} diff --git a/ZhongLian/ZhongLianAPI/Controllers/InstallController.cs b/ZhongLian/ZhongLianAPI/Controllers/InstallController.cs new file mode 100644 index 0000000..2294183 --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Controllers/InstallController.cs @@ -0,0 +1,107 @@ +using CommonModel; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using ZhongLianInterface; +using ZhongLianModel; +using ZhongLianService; + +namespace ZhongLianAPI.Controllers +{ + /// + /// 安装单接口 + /// + [Route("api/[controller]")] + [ApiController] + public class InstallController : ControllerBase + { + public InstallController(IInstallService installService) + { + InstallService = installService; + } + + private readonly IInstallService InstallService; + + /// + /// 创建安装单 + /// + /// 安装单 + /// + [HttpPost("insert")] + public async Task Insert(InstallDO install) + { + var _CheckMSG = InstallService.InsertCheck(install); + if (string.IsNullOrEmpty(_CheckMSG)) + { + return Ok(await InstallService.Insert(install)); + } + else + { + return BadRequest(_CheckMSG); + } + } + + /// + /// 更新安装单 + /// + /// 安装单 + /// + [HttpPost("update")] + public async Task Update(InstallDO install) + { + var _CheckMSG = InstallService.UpdateCheck(install); + if (string.IsNullOrEmpty(_CheckMSG)) + { + return Ok(await InstallService.Update(install)); + } + else + { + return BadRequest(_CheckMSG); + } + } + + /// + /// 删除安装单 + /// + /// 编号数组 + /// + [HttpPost("delete")] + public async Task Delete(string[] ids) + { + await InstallService.Delete(ids); + return Ok(); + } + + /// + /// 获取安装单列表 + /// + /// 查询条件 + /// + [HttpPost("list")] + public async Task List(PageYearSearch pageSearch) + { + return Ok(await InstallService.List(pageSearch)); + } + + /// + /// 获取安装单详情 + /// + /// 编号 + /// + [HttpGet("get")] + public async Task Get([FromQuery] string id) + { + return Ok(await InstallService.Get(id)); + } + + /// + /// 获取安装单步骤 + /// + /// 编号 + /// + [HttpGet("getsteps")] + public async Task GetSteps([FromQuery] string installId) + { + return Ok(await InstallService.GetStepsDO(installId)); + } + } +} diff --git a/ZhongLian/ZhongLianAPI/Controllers/MaintenanceController.cs b/ZhongLian/ZhongLianAPI/Controllers/MaintenanceController.cs new file mode 100644 index 0000000..0ef9a80 --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Controllers/MaintenanceController.cs @@ -0,0 +1,67 @@ +using CommonModel; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using ZhongLianInterface; +using ZhongLianModel; +using ZhongLianService; + +namespace ZhongLianAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class MaintenanceController : ControllerBase + { + public MaintenanceController(IMaintenanceService maintenanceService) { + MaintenanceService = maintenanceService; + } + + private readonly IMaintenanceService MaintenanceService; + + [HttpPost("insert")] + public async Task Insert(MaintenanceDO maintenance) + { + var _CheckMSG = MaintenanceService.InsertCheck(maintenance); + if (string.IsNullOrEmpty(_CheckMSG)) + { + return Ok(await MaintenanceService.InserDO(maintenance)); + } + else + { + return BadRequest(_CheckMSG); + } + } + + [HttpPost("update")] + public async Task Update(MaintenanceDO maintenance) + { + var _CheckMSG = MaintenanceService.UpdateCheck(maintenance); + if (string.IsNullOrEmpty(_CheckMSG)) + { + return Ok(await MaintenanceService.UpdateDO(maintenance)); + } + else + { + return BadRequest(_CheckMSG); + } + } + + [HttpPost("delete")] + public async Task Delete(string[] ids) + { + await MaintenanceService.DeleteDO(ids); + return Ok(); + } + + [HttpPost("list")] + public async Task List(PageYearSearch pageSearch) + { + return Ok(await MaintenanceService.ListDO(pageSearch)); + } + + [HttpGet("get")] + public async Task Get([FromQuery] string id) + { + return Ok(await MaintenanceService.GetDO(id)); + } + } +} diff --git a/ZhongLian/ZhongLianAPI/Controllers/ParamController.cs b/ZhongLian/ZhongLianAPI/Controllers/ParamController.cs new file mode 100644 index 0000000..09b7b26 --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Controllers/ParamController.cs @@ -0,0 +1,70 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using ZhongLianInterface; +using ZhongLianModel; +using ZhongLianService; + +namespace ZhongLianAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ParamController : ControllerBase + { + public ParamController(IParamService productService) { + + ProductService = productService; + + } + + private readonly IParamService ProductService; + + /// + /// 创建设备分类 + /// + /// 设备分类 + /// + [HttpPost("insert")] + public async Task Insert(ParamDO product) + { + var _CheckMSG = ProductService.InsertCheck(product); + if (string.IsNullOrEmpty(_CheckMSG)) + { + return Ok(await ProductService.Insert(product)); + } + else + { + return BadRequest(_CheckMSG); + } + } + + /// + /// 更新设备分类 + /// + /// 设备分类 + /// + [HttpPost("update")] + public async Task Update(ParamDO product) + { + var _CheckMSG = ProductService.UpdateCheck(product); + if (string.IsNullOrEmpty(_CheckMSG)) + { + return Ok(await ProductService.Update(product)); + } + else + { + return BadRequest(_CheckMSG); + } + } + + [HttpPost("delete")] + public async Task Delete(string[] ids) { + await ProductService.Delete(ids); + return Ok(); + } + + [HttpPost("list")] + public async Task List(ParamDO param) { + return Ok(await ProductService.List(param)); + } + } +} diff --git a/ZhongLian/ZhongLianAPI/Controllers/ProjectController.cs b/ZhongLian/ZhongLianAPI/Controllers/ProjectController.cs new file mode 100644 index 0000000..0efa561 --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Controllers/ProjectController.cs @@ -0,0 +1,87 @@ +using CommonModel; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using ZhongLianInterface; +using ZhongLianModel; + +namespace ZhongLianAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ProjectController : ControllerBase + { + public ProjectController(IProjectService projectService) + { + ProjectService = projectService; + } + + private readonly IProjectService ProjectService; + + /// + /// 插入新工程 + /// + /// 工程对象 + /// 工程对象 + [HttpPost("insert")] + public async Task insert(ProjectDO project) + { + return Ok(await ProjectService.Insert(project)); + } + + /// + /// 更新工程 + /// + /// 工程对象 + /// 工程对象 + [HttpPost("update")] + [HttpPut("update")] + public async Task update(ProjectDO project) + { + return Ok(await ProjectService.Update(project)); + } + + /// + /// 删除工程 + /// + /// 工程编号数组 + /// + [HttpDelete("delete")] + [HttpPost("delete")] + public async Task delete(string[] ids) + { + await ProjectService.Delete(ids); + return Ok(); + } + + /// + /// 根据编号查询工程详情 + /// + /// 编号 + /// 工程 + [HttpGet("get/{id}")] + [HttpPost("get/{id}")] + [AllowAnonymous] + public async Task get(string id) + { + return Ok(await ProjectService.Get(id)); + } + + /// + /// 分页查询工程 + /// + /// 分页对象 + /// 分页数据 + [HttpPost("list")] + [AllowAnonymous] + public async Task list(PageSearch page) + { + return Ok(await ProjectService.List(page)); + } + + [HttpGet("geo")] + public async Task geo() { + return Ok(await ProjectService.GeoCount()); + } + } +} diff --git a/ZhongLian/ZhongLianAPI/Dockerfile b/ZhongLian/ZhongLianAPI/Dockerfile new file mode 100644 index 0000000..e677f4b --- /dev/null +++ b/ZhongLian/ZhongLianAPI/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:7.0 AS base +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" >/etc/timezone +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj", "ZhongLian/ZhongLianAPI/"] +COPY ["ZhongLian/ZhongLianService/ZhongLianService.csproj", "ZhongLian/ZhongLianService/"] +COPY ["CommonModel/CommonModel.csproj", "CommonModel/"] +COPY ["ZhongLian/ZhongLianModel/ZhongLianModel.csproj", "ZhongLian/ZhongLianModel/"] +RUN dotnet restore "ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj" +COPY . . +WORKDIR "/src/ZhongLian/ZhongLianAPI" +RUN dotnet build "ZhongLianAPI.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "ZhongLianAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "ZhongLianAPI.dll"] \ No newline at end of file diff --git a/ZhongLian/ZhongLianAPI/Program.cs b/ZhongLian/ZhongLianAPI/Program.cs new file mode 100644 index 0000000..ff20b47 --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Program.cs @@ -0,0 +1,52 @@ +using ZhongLianService; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers().AddNewtonsoftJson(options => +{ + options.SerializerSettings.ContractResolver = new DefaultContractResolver(); + + options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; +}).AddDapr(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.InitZhongLianService(builder.Configuration); +#region Cors���� +#if DEBUG +builder.Services.AddCors(options => +{ + options.AddPolicy("all", builder => + { + builder.SetIsOriginAllowed(origin => true) //�����κ���Դ���������� + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials();//ָ������cookie + }); +}); +#endif +#endregion + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +#region Cors���� +#if DEBUG +app.UseCors("all"); +#endif +#endregion +app.UseSwagger(); +app.UseSwaggerUI(); +app.UseHttpsRedirection(); +app.UseRouting(); +app.UseAuthorization(); +app.UseStaticFiles(); +#if !DEBUG +app.MapActorsHandlers(); +#endif +app.MapControllers(); +app.Run(); diff --git a/ZhongLian/ZhongLianAPI/Properties/launchSettings.json b/ZhongLian/ZhongLianAPI/Properties/launchSettings.json new file mode 100644 index 0000000..f65518e --- /dev/null +++ b/ZhongLian/ZhongLianAPI/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "profiles": { + "ZhongLianAPI": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5027" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52302", + "sslPort": 0 + } + } +} \ No newline at end of file diff --git a/ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj b/ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj new file mode 100644 index 0000000..bec1ed6 --- /dev/null +++ b/ZhongLian/ZhongLianAPI/ZhongLianAPI.csproj @@ -0,0 +1,23 @@ + + + + net7.0 + enable + enable + Linux + ..\.. + + + + + + + + + + + + + + + diff --git a/ZhongLian/ZhongLianAPI/appsettings.Development.json b/ZhongLian/ZhongLianAPI/appsettings.Development.json new file mode 100644 index 0000000..a6e86ac --- /dev/null +++ b/ZhongLian/ZhongLianAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ZhongLian/ZhongLianAPI/appsettings.json b/ZhongLian/ZhongLianAPI/appsettings.json new file mode 100644 index 0000000..6a9273f --- /dev/null +++ b/ZhongLian/ZhongLianAPI/appsettings.json @@ -0,0 +1,12 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "Default": "Data Source=124.71.176.44;database=lsdb;User Id=root;Pwd=root;charset=utf8;pooling=true;" + } +} diff --git a/ZhongLian/ZhongLianInterface/IDriveService.cs b/ZhongLian/ZhongLianInterface/IDriveService.cs new file mode 100644 index 0000000..9b9e219 --- /dev/null +++ b/ZhongLian/ZhongLianInterface/IDriveService.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; + +namespace ZhongLianInterface +{ + public interface IDriveService + { + /// + /// 创建 + /// + /// 文件 + /// + Task Insert(FileDO file); + + /// + /// 创建插入 + /// + /// 文件 + /// + Task InsertDO(FileDO file); + + /// + /// 创建检查 + /// + /// 文件 + /// + string InsertCheck(FileDO file); + + /// + /// 查询 + /// + /// 编号 + /// + Task Get(string id); + + /// + /// 查询数据 + /// + /// 编号 + /// + Task GetDO(string id); + } +} diff --git a/ZhongLian/ZhongLianInterface/IInstallActor.cs b/ZhongLian/ZhongLianInterface/IInstallActor.cs new file mode 100644 index 0000000..d816a4d --- /dev/null +++ b/ZhongLian/ZhongLianInterface/IInstallActor.cs @@ -0,0 +1,35 @@ +using CommonModel; +using Dapr.Actors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; + +namespace ZhongLianInterface +{ + public interface IInstallActor : IActor + { + /// + /// 创建 + /// + /// 安装单 + /// + Task Insert(InstallDO install); + + /// + /// 更新 + /// + /// 安装单 + /// + Task Update(InstallDO install); + + /// + /// 删除 + /// + /// 编号数组 + /// + Task Delete(string[] ids); + } +} diff --git a/ZhongLian/ZhongLianInterface/IInstallService.cs b/ZhongLian/ZhongLianInterface/IInstallService.cs new file mode 100644 index 0000000..46b36ea --- /dev/null +++ b/ZhongLian/ZhongLianInterface/IInstallService.cs @@ -0,0 +1,111 @@ +using CommonModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; + +namespace ZhongLianInterface +{ + public interface IInstallService + { + /// + /// 创建 + /// + /// 安装单 + /// + Task Insert(InstallDO install); + + /// + /// 创建数据 + /// + /// 安装单 + /// + Task InserDO(InstallDO install); + + /// + /// 创建校验 + /// + /// 安装单 + /// + string InsertCheck(InstallDO install); + + /// + /// 更新 + /// + /// 安装单 + /// + Task Update(InstallDO install); + + /// + /// 更新数据 + /// + /// 安装单 + /// + Task UpdateDO(InstallDO install); + + /// + /// 更新校验 + /// + /// 安装单 + /// + string UpdateCheck(InstallDO install); + + /// + /// 删除 + /// + /// 编号数组 + /// + Task Delete(string[] ids); + + /// + /// 删除数据 + /// + /// + /// + Task DeleteDO(string[] ids); + + /// + /// 查询列表 + /// + /// 查询条件 + /// + Task> List(PageYearSearch pageSearch); + + /// + /// 查询列表数据 + /// + /// 查询条件 + /// + Task> ListDO(PageYearSearch pageSearch); + + /// + /// 查询详情 + /// + /// 编号 + /// + Task Get(string id); + + /// + /// 查询详情数据 + /// + /// 编号 + /// + Task GetDO(string id); + + /// + /// 查询步骤 + /// + /// 编号 + /// + Task GetSteps(string installId); + + /// + /// 查询步骤数据 + /// + /// 编号 + /// + Task GetStepsDO(string installId); + } +} diff --git a/ZhongLian/ZhongLianInterface/IMaintenanceService.cs b/ZhongLian/ZhongLianInterface/IMaintenanceService.cs new file mode 100644 index 0000000..789e0c9 --- /dev/null +++ b/ZhongLian/ZhongLianInterface/IMaintenanceService.cs @@ -0,0 +1,27 @@ +using CommonModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; + +namespace ZhongLianInterface +{ + public interface IMaintenanceService + { + Task InserDO(MaintenanceDO maintenance); + + string InsertCheck(MaintenanceDO maintenance); + + Task UpdateDO(MaintenanceDO maintenance); + + string UpdateCheck(MaintenanceDO maintenance); + + Task DeleteDO(string[] ids); + + Task GetDO(string id); + + Task> ListDO(PageYearSearch pageSearch); + } +} diff --git a/ZhongLian/ZhongLianInterface/IParamService.cs b/ZhongLian/ZhongLianInterface/IParamService.cs new file mode 100644 index 0000000..6e308e9 --- /dev/null +++ b/ZhongLian/ZhongLianInterface/IParamService.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; + +namespace ZhongLianInterface +{ + public interface IParamService + { + Task Insert(ParamDO param); + + string InsertCheck(ParamDO param); + + Task Update(ParamDO param); + + Task Use(string id); + + string UpdateCheck(ParamDO param); + + Task Delete(string[] ids); + + Task> List(ParamDO param); + } +} diff --git a/ZhongLian/ZhongLianInterface/IProjectService.cs b/ZhongLian/ZhongLianInterface/IProjectService.cs new file mode 100644 index 0000000..33af70c --- /dev/null +++ b/ZhongLian/ZhongLianInterface/IProjectService.cs @@ -0,0 +1,55 @@ +using CommonModel; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; + +namespace ZhongLianInterface +{ + /// + /// 工程服务 + /// + public interface IProjectService + { + /// + /// 插入 + /// + /// 工程实体 + /// 工程实体 + Task Insert(ProjectDO project); + + /// + /// 更新 + /// + /// 工程实体 + /// 工程实体 + Task Update(ProjectDO project); + + /// + /// 删除 + /// + /// Id数组 + /// + + Task Delete(string[] ids); + + /// + /// 根据编号查询 + /// + /// 编号 + /// 工程 + Task Get(string id); + + /// + /// 分页查询 + /// + /// 分页对象 + /// 分页对象 + Task> List(PageSearch page); + + Task> GeoCount(); + } +} diff --git a/ZhongLian/ZhongLianInterface/ZhongLianInterface.csproj b/ZhongLian/ZhongLianInterface/ZhongLianInterface.csproj new file mode 100644 index 0000000..ee59066 --- /dev/null +++ b/ZhongLian/ZhongLianInterface/ZhongLianInterface.csproj @@ -0,0 +1,18 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + diff --git a/ZhongLian/ZhongLianModel/CompanyDO.cs b/ZhongLian/ZhongLianModel/CompanyDO.cs new file mode 100644 index 0000000..e9baa84 --- /dev/null +++ b/ZhongLian/ZhongLianModel/CompanyDO.cs @@ -0,0 +1,92 @@ +using SqlSugar; + +namespace ZhongLianModel +{ + /// + /// 公司实体类 + /// + [SugarTable("CRM_Company_zl")] + public class CompanyDO + { + /// + /// 唯一键 + /// + [SugarColumn(IsPrimaryKey = true, Length = 64)] + public string? Id { get; set; } + + /// + /// 编号 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? Code { get; set; } + + [SugarColumn(IsIgnore = true, IsNullable = true)] + public string? System { get; set; } + + /// + /// 名称 + /// + [SugarColumn(Length = 250, IsNullable = true)] + public string? Name { get; set; } + + /// + /// 法人代表 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? LegalPerson { get; set; } + + /// + /// 社会信用代码 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? SCCode { get; set; } + + /// + /// 人员规模 + /// + [SugarColumn(Length = 60, IsNullable = true)] + public string? Scale { get; set; } + + /// + /// 公司性质 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? Character { get; set; } + + /// + /// 地址 + /// + [SugarColumn(Length = 500, IsNullable = true)] + public string? Address { get; set; } + + /// + /// 定位 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? Location { get; set; } + + /// + /// 联系电话 + /// + [SugarColumn(Length = 60, IsNullable = true)] + public string? Tel { get; set; } + + /// + /// 简介 + /// + [SugarColumn(Length = 500,IsNullable = true)] + public string? BriefIntroduction { get; set; } + + /// + /// 创建日期 + /// + [SugarColumn(Length = 24, IsNullable = true)] + public string? CreateDate { get; set; } + + /// + /// 删除标识 + /// + [SugarColumn(Length = 1, IsNullable = true)] + public int? Deleted { get; set; } + } +} \ No newline at end of file diff --git a/ZhongLian/ZhongLianModel/DeviceDO.cs b/ZhongLian/ZhongLianModel/DeviceDO.cs new file mode 100644 index 0000000..63efdf6 --- /dev/null +++ b/ZhongLian/ZhongLianModel/DeviceDO.cs @@ -0,0 +1,34 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + /// + /// 设备实体 + /// + [SugarTable("TPRZ_Device")] + public class DeviceDO + { + /// + /// 设备编号 + /// + [SugarColumn(IsPrimaryKey = true, Length = 64)] + public string? Id { get; set; } + + /// + /// 工程 + /// + [SugarColumn(Length = 64, IsNullable = true)] + public string? ProjectId { get; set; } + + /// + /// 删除标识 + /// + [SugarColumn(Length = 1, IsNullable = true)] + public int? Deleted { get; set; } + } +} diff --git a/ZhongLian/ZhongLianModel/FileDO.cs b/ZhongLian/ZhongLianModel/FileDO.cs new file mode 100644 index 0000000..87aa7ca --- /dev/null +++ b/ZhongLian/ZhongLianModel/FileDO.cs @@ -0,0 +1,48 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + /// + /// 文件 + /// + [SugarTable("ZL_File_{year}{month}{day}")] + [SplitTable(SplitType.Year)] + public class FileDO + { + /// + /// 编号 + /// + [SugarColumn(IsPrimaryKey = true,Length = 100)] + public string? Id { get; set; } + + /// + /// 文件名称 + /// + [SugarColumn(IsNullable = true,Length = 200)] + public string? FileName { get; set; } + + /// + /// 文件类型 + /// + [SugarColumn(IsNullable = true,Length = 50)] + public string? ContentType { get; set; } + + /// + /// 数据 + /// + [SugarColumn(IsNullable = true,ColumnDataType = "LONGBLOB")] + public byte[]? Data { get; set; } + + /// + /// 创建日期 + /// + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + } +} diff --git a/ZhongLian/ZhongLianModel/GeoProjectDTO.cs b/ZhongLian/ZhongLianModel/GeoProjectDTO.cs new file mode 100644 index 0000000..1e3e14a --- /dev/null +++ b/ZhongLian/ZhongLianModel/GeoProjectDTO.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + public class GeoProjectDTO + { + public string? Code { get; set; } + + public int? Count { get; set; } + + public string? ParentCode { get; set; } + } +} diff --git a/ZhongLian/ZhongLianModel/GroupDO.cs b/ZhongLian/ZhongLianModel/GroupDO.cs new file mode 100644 index 0000000..b6e3049 --- /dev/null +++ b/ZhongLian/ZhongLianModel/GroupDO.cs @@ -0,0 +1,66 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + /// + /// 组实体类 + /// + [SugarTable("AT_Group_zl")] + public class GroupDO + { + /// + /// 唯一键 + /// + [SugarColumn(IsPrimaryKey = true, Length = 64)] + public string? Id { get; set; } + + /// + /// 父键 + /// + [SugarColumn(Length = 64,IsNullable = true)] + public string? PId { get; set; } + + /// + /// 编号 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? Code { get; set; } + + /// + /// 系统 + /// + + [SugarColumn(IsIgnore = true, IsNullable = true)] + public string? System { get; set; } + + /// + /// 名称 + /// + [SugarColumn(Length = 250, IsNullable = true)] + public string? Name { get; set; } + + /// + /// 类型{0:组织结构} + /// + [SugarColumn(Length = 2, IsNullable = true)] + public int? Type { get; set; } + + /// + /// 创建日期 + /// + [SugarColumn(Length = 24, IsNullable = true)] + public string? CreateDate { get; set; } + + /// + /// 删除标识 + /// + [SugarColumn(Length = 1, IsNullable = true)] + public int? Deleted { get; set; } + + } +} diff --git a/ZhongLian/ZhongLianModel/InstallDO.cs b/ZhongLian/ZhongLianModel/InstallDO.cs new file mode 100644 index 0000000..98e2a59 --- /dev/null +++ b/ZhongLian/ZhongLianModel/InstallDO.cs @@ -0,0 +1,171 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Nodes; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + [SugarTable("ZL_Install_{year}{month}{day}")] + [SplitTable(SplitType.Year)] + public class InstallDO + { + /// + /// 编号 + /// + [SugarColumn(IsPrimaryKey = true, Length = 100)] + public string? Id { get; set; } + + /// + /// 安装地点 + /// + [SugarColumn(IsNullable = true, Length = 200)] + public string? Address { get; set; } + + /// + /// 设备编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? DeviceId { get; set; } + + /// + /// 设备信息 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public Dictionary? Device { get; set; } + + /// + /// 工作内容:安装,加节,拆卸 + /// + [SugarColumn(IsNullable = true, Length = 50)] + public string? Action { get; set; } + + /// + /// 安装人员编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? InstallUid { get; set; } + + /// + /// 安装人员信息 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public Dictionary? InstallUser { get; set; } + + /// + /// 安装时间 + /// + [SugarColumn(IsNullable = true)] + public DateTime? InstallDate { get; set; } + + /// + /// 巡检人员编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? PatrolUid { get; set; } + + /// + /// 巡检人员信息 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public Dictionary? PatrolUser { get; set; } + + /// + /// 巡检时间 + /// + [SugarColumn(IsNullable = true)] + public DateTime? PatrolDate { get; set; } + + /// + /// 安装单状态,0:未完成,1:安装人员已提交,2:巡检人员未通过,3:已完成 + /// + [SugarColumn(IsNullable = true, Length = 2)] + public int? State { get; set; } + + /// + /// 备注 + /// + [SugarColumn(IsNullable = true, ColumnDataType = "Text")] + public string? Remark { get; set; } + + /// + /// 创建日期 + /// + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + + /// + /// 最后更新日期 + /// + [SugarColumn(IsNullable = true)] + public DateTime? LastDate { get; set; } + + #region 业务字段 + /// + /// 创建日期文字 + /// + [SugarColumn(IsIgnore = true)] + public string? CreateDateText + { + get + { + if (CreateDate == null) + { + return null; + } + else + { + return ((DateTime)CreateDate).ToString("yyyyMMddHHmmss"); + } + } + } + + /// + /// 安装日期文字 + /// + [SugarColumn(IsIgnore = true)] + public string? InstallDateDateText + { + get + { + if (InstallDate == null) + { + return null; + } + else + { + return ((DateTime)InstallDate).ToString("yyyyMMddHHmmss"); + } + } + } + + /// + /// 巡检日期文字 + /// + [SugarColumn(IsIgnore = true)] + public string? PatrolDateText + { + get + { + if (PatrolDate == null) + { + return null; + } + else + { + return ((DateTime)PatrolDate).ToString("yyyyMMdd"); + } + } + } + + /// + /// 安装步骤 + /// + [SugarColumn(IsIgnore = true)] + public InstallStepDO[]? Steps { get; set; } + #endregion + } +} diff --git a/ZhongLian/ZhongLianModel/InstallStepDO.cs b/ZhongLian/ZhongLianModel/InstallStepDO.cs new file mode 100644 index 0000000..d75231d --- /dev/null +++ b/ZhongLian/ZhongLianModel/InstallStepDO.cs @@ -0,0 +1,70 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Nodes; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + [SugarTable("ZL_InstallStep_{year}{month}{day}")] + [SplitTable(SplitType.Year)] + public class InstallStepDO + { + /// + /// 安装单编号 + /// + [SugarColumn(Length = 100, IsPrimaryKey = true)] + public string? InstallId { get; set; } + + /// + /// 键 + /// + [SugarColumn(Length = 50, IsPrimaryKey = true)] + public string? Key { get; set; } + + /// + /// 值 + /// + [SugarColumn(IsJson = true,IsNullable = true, ColumnDataType = "Text")] + public dynamic[]? Value { get; set; } + + /// + /// 序号 + /// + [SugarColumn(IsNullable = true, Length = 2)] + public int? Index { get; set; } + + /// + /// 自定义数据 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public Dictionary? Data { get; set; } + + /// + /// 巡检状态 0:未巡检,1:已通过,2:未通过 + /// + [SugarColumn(IsNullable = true, Length = 2)] + public int? State { get; set; } + + /// + /// 巡检评论 + /// + [SugarColumn(IsNullable = true, Length = 500)] + public string? Comment { get; set; } + + /// + /// 创建日期 + /// + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + + /// + /// 最后更新日期 + /// + [SugarColumn(IsNullable = true)] + public DateTime? LastDate { get; set; } + } +} diff --git a/ZhongLian/ZhongLianModel/MaintenanceDO.cs b/ZhongLian/ZhongLianModel/MaintenanceDO.cs new file mode 100644 index 0000000..bcdb999 --- /dev/null +++ b/ZhongLian/ZhongLianModel/MaintenanceDO.cs @@ -0,0 +1,161 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + [SugarTable("ZL_Maintenance_{year}{month}{day}")] + [SplitTable(SplitType.Year)] + public class MaintenanceDO + { + public MaintenanceDO() { + BomCodes = new string[0]; + Boms = new string[0]; + ErrorRemarkPhoto = new string[0]; + ProcessResultPhoto = new string[0]; + } + + /// + /// 编号 + /// + [SugarColumn(IsPrimaryKey = true, Length = 100)] + public string? Id { get; set; } + + /// + /// 标题 + /// + [SugarColumn(IsNullable = true, Length = 200)] + public string? Title { get; set; } + + /// + /// 单据类型 + /// + [SugarColumn(IsNullable = true, Length = 50)] + public string? Type { get; set; } + + /// + /// 维修人员编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? MaintenanceUid { get; set; } + + /// + /// 维修人员信息 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public Dictionary? MaintenanceUser { get; set; } + + /// + /// 设备分类编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? DeviceTypeCode { get; set; } + + /// + /// 设备分类 + /// + [SugarColumn(IsNullable = true, Length = 200)] + public string? DeviceType { get; set; } + + /// + /// 维修日期 + /// + [SugarColumn(IsNullable = true)] + public DateTime? MaintenanceDate { get; set; } + + /// + /// 安装单状态,0:未完成,1:维修人员已提交,2:审核未通过,3:已完成 + /// + [SugarColumn(IsNullable = true, Length = 2)] + public int? State { get; set; } + + /// + /// 备注 + /// + [SugarColumn(IsNullable = true, ColumnDataType = "Text")] + public string? Remark { get; set; } + + /// + /// 故障归类编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? ErrorTypeCode { get; set; } + + /// + /// 故障归类 + /// + [SugarColumn(IsNullable = true, Length = 200)] + public string? ErrorType { get; set; } + + + /// + /// 配件清单编号 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public string[]? BomCodes { get; set; } + + /// + /// 配件清单 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public string[]? Boms { get; set; } + + /// + /// 处理方式编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? ErrorActionCode { get; set; } + + /// + /// 处理方式 + /// + [SugarColumn(IsNullable = true, Length = 200)] + public string? ErrorAction { get; set; } + + /// + /// 故障代码编号 + /// + [SugarColumn(IsNullable = true, Length = 100)] + public string? ErrorCodeCode { get; set; } + + /// + /// 故障代码 + /// + [SugarColumn(IsNullable = true, Length = 200)] + public string? ErrorCode { get; set; } + + /// + /// 故障分析 + /// + [SugarColumn(IsNullable = true, Length = 500)] + public string? ErrorRemark { get; set; } + + /// + /// 故障分析图片 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public string[]? ErrorRemarkPhoto { get; set; } + + /// + /// 处理结果 + /// + [SugarColumn(IsNullable = true, Length = 500)] + public string? ProcessResult { get; set; } + + /// + /// 处理结果图片 + /// + [SugarColumn(IsJson = true, IsNullable = true, ColumnDataType = "Text")] + public string[]? ProcessResultPhoto { get; set; } + + /// + /// 创建日期 + /// + [SplitField] + [SugarColumn(IsNullable = true)] + public DateTime? CreateDate { get; set; } + } +} diff --git a/ZhongLian/ZhongLianModel/ParamDO.cs b/ZhongLian/ZhongLianModel/ParamDO.cs new file mode 100644 index 0000000..2cbcc36 --- /dev/null +++ b/ZhongLian/ZhongLianModel/ParamDO.cs @@ -0,0 +1,25 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + [SugarTable("ZL_Param")] + public class ParamDO + { + [SugarColumn(IsPrimaryKey = true,Length = 100)] + public string? Id { get; set; } + + [SugarColumn(IsNullable = true,Length = 200)] + public string? Name { get; set; } + + [SugarColumn(IsNullable = true,Length = 100)] + public string? Category { get; set; } + + [SugarColumn(IsNullable = true)] + public int? UseCount { get; set; } + } +} diff --git a/ZhongLian/ZhongLianModel/ProjectDO.cs b/ZhongLian/ZhongLianModel/ProjectDO.cs new file mode 100644 index 0000000..4188b16 --- /dev/null +++ b/ZhongLian/ZhongLianModel/ProjectDO.cs @@ -0,0 +1,201 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ZhongLianModel +{ + /// + /// 工程实体 + /// + [SugarTable("TPRZ_Project")] + public class ProjectDO + { + /// + /// 编号 + /// + [SugarColumn(IsPrimaryKey = true, Length = 64)] + public string? Id { get; set; } + + /// + /// 编码 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? Code { get; set; } + + /// + /// 公司编号 + /// + [SugarColumn(Length = 64, IsNullable = true)] + public string? CompanyId { get; set; } + + /// + /// 工程名称 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? Name { get; set; } + + /// + /// 区域 + /// + [SugarColumn(Length = 60, IsNullable = true)] + public string? Area { get; set; } + + /// + /// 工地名称 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? AddressName { get; set; } + + /// + /// 地址 + /// + [SugarColumn(Length = 500, IsNullable = true)] + public string? Address { get; set; } + + /// + /// 定位 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? Location { get; set; } + + /// + /// 施工单位 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? CU { get; set; } + + /// + /// 施工许可证 + /// + [SugarColumn(Length = 100, IsNullable = true)] + public string? CC { get; set; } + + /// + /// 监理单位 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? SU { get; set; } + + /// + /// 项目经理 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? PM { get; set; } + + /// + /// 项目经理联系方式 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? PT { get; set; } + + /// + /// 现场负责人 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? SM { get; set; } + + /// + /// 现场负责人联系方式 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? ST { get; set; } + + /// + /// 资料员 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? DR { get; set; } + + /// + /// 资料员联系方式 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? DT { get; set; } + + /// + /// 工地财务 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? FA { get; set; } + + /// + /// 工地财务联系方式 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? FT { get; set; } + + /// + /// 监理 + /// + [SugarColumn(Length = 200, IsNullable = true)] + public string? SP { get; set; } + + /// + /// 监理联系方式 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? SPT { get; set; } + + /// + /// 备注 + /// + [SugarColumn(Length = 500, IsNullable = true)] + public string? Remark { get; set; } + + /// + /// 创建日期 + /// + [SugarColumn(Length = 24, IsNullable = true)] + public string? CreateDate { get; set; } + + /// + /// 删除标识 + /// + [SugarColumn(Length = 1, IsNullable = true)] + public int? Deleted { get; set; } + + /// + /// 省份码 + /// + [SugarColumn(Length = 10,IsNullable = true)] + public string? ProvinceCode { get; set; } + + /// + /// 省份名 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? ProvinceName { get; set; } + + /// + /// 市级码 + /// + [SugarColumn(Length = 10, IsNullable = true)] + public string? CityCode { get; set; } + + /// + /// 市级名 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? CityName { get; set; } + + /// + /// 区域码 + /// + [SugarColumn(Length = 10, IsNullable = true)] + public string? AreaCode { get; set; } + + /// + /// 区域名 + /// + [SugarColumn(Length = 20, IsNullable = true)] + public string? AreaName { get; set; } + + #region 业务字段 + [SugarColumn(IsIgnore = true, IsNullable = true)] + public string? CompanyName { get; set; } + #endregion + } +} diff --git a/ZhongLian/ZhongLianModel/Properties/launchSettings.json b/ZhongLian/ZhongLianModel/Properties/launchSettings.json new file mode 100644 index 0000000..254dd16 --- /dev/null +++ b/ZhongLian/ZhongLianModel/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "ZhongLianModel": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:64277;http://localhost:64280" + } + } +} \ No newline at end of file diff --git a/ZhongLian/ZhongLianModel/ZhongLianModel.csproj b/ZhongLian/ZhongLianModel/ZhongLianModel.csproj new file mode 100644 index 0000000..dbe121a --- /dev/null +++ b/ZhongLian/ZhongLianModel/ZhongLianModel.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/ZhongLian/ZhongLianService/DriveService.cs b/ZhongLian/ZhongLianService/DriveService.cs new file mode 100644 index 0000000..2bd17a6 --- /dev/null +++ b/ZhongLian/ZhongLianService/DriveService.cs @@ -0,0 +1,103 @@ +using CommonModel; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianModel; +using ZhongLianInterface; + +namespace ZhongLianService +{ + /// + /// 文件服务 + /// + public class DriveService : IDriveService + { + public DriveService(IServiceProvider services, ISqlSugarClient sqlSugarClient) + { + Services = services; + Db = sqlSugarClient; + + Db.CodeFirst.SplitTables().InitTables(typeof(FileDO)); + } + + private readonly IServiceProvider Services; + + private readonly ISqlSugarClient Db; + + #region 创建 + /// + /// 创建 + /// + /// 文件 + /// + public async Task Insert(FileDO file) + { + return await InsertDO(file); + } + + /// + /// 创建插入 + /// + /// 文件 + /// + public async Task InsertDO(FileDO file) + { + + await Db.Insertable(file).SplitTable().ExecuteCommandAsync(); + + file.Data = null; + + return file; + } + + /// + /// 创建检查 + /// + /// 文件 + /// + public string InsertCheck(FileDO file) + { + + var _MaxId = Db.Queryable().SplitTable(DateTime.Today, DateTime.Today.AddDays(1)).Max(x => x.Id); + if (string.IsNullOrEmpty(_MaxId)) + { + file.Id = $"FL{DateTime.Now.ToString("yyyyMMdd")}000001"; + } + else + { + file.Id = $"FL{DateTime.Now.ToString("yyyyMMdd")}{(Convert.ToInt32(_MaxId.Substring(10, 6)) + 1).ToString().PadLeft(6, '0')}"; + } + + file.CreateDate = DateTime.Now; + + return ""; + } + #endregion + + #region 查询 + /// + /// 查询 + /// + /// 编号 + /// + public async Task Get(string id) + { + return await GetDO(id); + } + + /// + /// 查询数据 + /// + /// 编号 + /// + public async Task GetDO(string id) + { + SplitDateId SplitDateId = new SplitDateId(id, 2); + return await Db.Queryable().Where(x => x.Id == id).SplitTable(SplitDateId.StartDate, SplitDateId.EndDate).SingleAsync(); + } + #endregion + } +} diff --git a/ZhongLian/ZhongLianService/InstallActor.cs b/ZhongLian/ZhongLianService/InstallActor.cs new file mode 100644 index 0000000..d349f6f --- /dev/null +++ b/ZhongLian/ZhongLianService/InstallActor.cs @@ -0,0 +1,55 @@ +using CommonModel; +using Dapr.Actors.Runtime; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianInterface; +using ZhongLianModel; + +namespace ZhongLianService +{ + /// + /// 安装单Actor + /// + public class InstallActor : Actor, IInstallActor + { + public InstallActor(ActorHost host, IInstallService installService) : base(host) + { + InstallService = installService; + } + + private readonly IInstallService InstallService; + + /// + /// 创建 + /// + /// 安装单 + /// + public async Task Insert(InstallDO install) + { + return await InstallService.InserDO(install); + } + + /// + /// 更新 + /// + /// 安装单 + /// + public async Task Update(InstallDO install) + { + return await InstallService.UpdateDO(install); + } + + /// + /// 删除 + /// + /// 编号数组 + /// + public async Task Delete(string[] ids) + { + await InstallService.DeleteDO(ids); + } + } +} diff --git a/ZhongLian/ZhongLianService/InstallService.cs b/ZhongLian/ZhongLianService/InstallService.cs new file mode 100644 index 0000000..1dd81e3 --- /dev/null +++ b/ZhongLian/ZhongLianService/InstallService.cs @@ -0,0 +1,385 @@ +using CommonModel; +using Dapr.Actors; +using Dapr.Actors.Client; +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianInterface; +using ZhongLianModel; + +namespace ZhongLianService +{ + public class InstallService : IInstallService + { + public InstallService(IServiceProvider services, ISqlSugarClient sqlSugarClient) + { + Services = services; + Db = sqlSugarClient; + + Db.CodeFirst.SplitTables().InitTables(typeof(InstallDO)); + Db.CodeFirst.SplitTables().InitTables(typeof(InstallStepDO)); + } + + private readonly IServiceProvider Services; + + private readonly ISqlSugarClient Db; + + #region 创建 + /// + /// 创建 + /// + /// 安装单 + /// + public async Task Insert(InstallDO install) + { +#if DEBUG + return await InserDO(install); +#else + var _ActorProxy = Services.GetRequiredService(); + + var _Proxy = _ActorProxy.CreateActorProxy(new ActorId(install.Id), "InstallActor"); + + return await _Proxy.Insert(install); +#endif + } + + /// + /// 创建数据 + /// + /// 安装单 + /// + public async Task InserDO(InstallDO install) + { + try + { + + Db.Ado.BeginTran(); + + await Db.Insertable(install).SplitTable().ExecuteCommandAsync(); + + if (install.Steps != null && install.Steps.Length > 0) + { + await Db.Insertable(install.Steps).SplitTable().ExecuteCommandAsync(); + } + + Db.Ado.CommitTran(); + } + catch + { + Db.Ado.RollbackTran(); + + throw; + } + return install; + } + + /// + /// 创建校验 + /// + /// 安装单 + /// + public string InsertCheck(InstallDO install) + { + + var _MaxId = Db.Queryable().SplitTable(DateTime.Today, DateTime.Today.AddDays(1)).Max(x => x.Id); + if (string.IsNullOrEmpty(_MaxId)) + { + install.Id = $"IS{DateTime.Now.ToString("yyyyMMdd")}000001"; + } + else + { + install.Id = $"IS{DateTime.Now.ToString("yyyyMMdd")}{(Convert.ToInt32(_MaxId.Substring(10, 6)) + 1).ToString().PadLeft(6, '0')}"; + } + + install.State = 0; + + install.CreateDate = DateTime.Now; + + if (install.Steps != null && install.Steps.Length > 0) + { + foreach (var step in install.Steps) + { + step.InstallId = install.Id; + step.CreateDate = install.CreateDate; + step.State = 0; + } + } + return ""; + } + #endregion + + #region 更新 + /// + /// 更新 + /// + /// 安装单 + /// + public async Task Update(InstallDO install) + { +#if DEBUG + return await UpdateDO(install); +#else + var _ActorProxy = Services.GetRequiredService(); + + var _Proxy = _ActorProxy.CreateActorProxy(new ActorId(install.Id), "InstallActor"); + + return await _Proxy.Update(install); +#endif + } + + /// + /// 更新数据 + /// + /// 安装单 + /// + public async Task UpdateDO(InstallDO install) + { + try + { + + Db.Ado.BeginTran(); + + await Db.Updateable(install).IgnoreColumns(ignoreAllNullColumns: true).Where(x => x.Id == install.Id).SplitTable().ExecuteCommandAsync(); + + if (install.Steps != null && install.Steps.Length > 0) + { + SplitDateId SplitDateId = new SplitDateId(install.Id!, 2); + foreach (var step in install.Steps) + { + if (Db.Queryable().SplitTable(SplitDateId.StartDate, SplitDateId.EndDate).Any(x => x.InstallId == install.Id && x.Key == step.Key)) + { + await Db.Updateable(step).IgnoreColumns(ignoreAllNullColumns: true).Where(x => x.InstallId == install.Id && x.Key == step.Key).SplitTable().ExecuteCommandAsync(); + } + else + { + await Db.Insertable(step).SplitTable().ExecuteCommandAsync(); + } + } + + } + + Db.Ado.CommitTran(); + } + catch + { + Db.Ado.RollbackTran(); + + throw; + } + return install; + } + + /// + /// 更新校验 + /// + /// 安装单 + /// + public string UpdateCheck(InstallDO install) + { + + if (string.IsNullOrEmpty(install.Id)) + { + return "安装单编号不存在"; + } + SplitDateId SplitDateId = new SplitDateId(install.Id!, 2); + if (!Db.Queryable().SplitTable(SplitDateId.StartDate, SplitDateId.EndDate).Any(x => x.Id == install.Id)) { + return "安装单编号不存在"; + } + + var _Install = Db.Queryable().SplitTable(SplitDateId.StartDate, SplitDateId.EndDate).Where(x => x.Id == install.Id).Single(); + + if (install.Steps != null && install.Steps.Length > 0) + { + foreach (var step in install.Steps) + { + step.InstallId = install.Id; + if (step.State == null) + { + step.State = 0; + } + if (step.State == 1) + { + step.Comment = ""; + } + if (install.State == 3 && step.State == 2) + { + install.State = 2; + } + step.CreateDate = _Install.CreateDate; + step.LastDate = DateTime.Now; + } + } + + if (install.State == 1) + { + install.InstallDate = DateTime.Now; + } + + if (install.State == 2 || install.State == 3) + { + install.PatrolDate = DateTime.Now; + } + + install.LastDate = DateTime.Now; + + return ""; + } + #endregion + + #region 删除 + /// + /// 删除 + /// + /// 编号数组 + /// + public async Task Delete(string[] ids) + { +#if DEBUG + await DeleteDO(ids); +#else + var _ActorProxy = Services.GetRequiredService(); + + var _Proxy = _ActorProxy.CreateActorProxy(new ActorId(Guid.NewGuid().ToString()), "InstallActor"); + + await _Proxy.Delete(ids); +#endif + } + + /// + /// 删除数据 + /// + /// + /// + public async Task DeleteDO(string[] ids) + { + try + { + + Db.Ado.BeginTran(); + foreach(var id in ids) + { + InstallDO InstallDO = new InstallDO() { + Id = id, + State = -1 + }; + await Db.Updateable(InstallDO).IgnoreColumns(ignoreAllNullColumns: true).Where(x => x.Id == InstallDO.Id).SplitTable().ExecuteCommandAsync(); + } + Db.Ado.CommitTran(); + } + catch + { + Db.Ado.RollbackTran(); + + throw; + } + } + #endregion + + #region 列表 + /// + /// 查询列表 + /// + /// 查询条件 + /// + public async Task> List(PageYearSearch pageSearch) + { + return await ListDO(pageSearch); + } + + /// + /// 查询列表数据 + /// + /// 查询条件 + /// + public async Task> ListDO(PageYearSearch pageSearch) + { + RefAsync _Total = 0; + var _Result = await Db.Queryable() + .Where(x => x.State != -1) + .WhereIF(!string.IsNullOrEmpty(pageSearch.Search), x => + x.Id!.Contains(pageSearch.Search!) || + x.Address!.Contains(pageSearch.Search!) || + SqlFunc.JsonLike(x.InstallUser, pageSearch.Search!) || + SqlFunc.JsonLike(x.PatrolUser, pageSearch.Search!) + ) + .WhereIF(pageSearch.Mode != null && pageSearch.Mode.State != null, x => x.State == pageSearch.Mode!.State) + .WhereIF(pageSearch.Mode != null && !string.IsNullOrEmpty(pageSearch.Mode.InstallUid), x => + x.InstallUid == pageSearch.Mode!.InstallUid + ) + .WhereIF(pageSearch.Mode != null && !string.IsNullOrEmpty(pageSearch.Mode.PatrolUid), x => + x.PatrolUid == pageSearch.Mode!.PatrolUid + ) + .OrderByDescending(x => x.Id) + .SplitTable((DateTime)pageSearch.StartDate!, (DateTime)pageSearch.EndDate!) + .ToPageListAsync(pageSearch.Index, pageSearch.Size, _Total); + return new PageData() + { + Index = pageSearch.Index, + Size = pageSearch.Size, + Data = _Result, + Total = _Total.Value + }; + } + #endregion + + #region 查询 + /// + /// 查询详情 + /// + /// 编号 + /// + public async Task Get(string id) + { + return await GetDO(id); + } + + /// + /// 查询详情数据 + /// + /// 编号 + /// + public async Task GetDO(string id) + { + SplitDateId SplitDateId = new SplitDateId(id, 2); + return await Db.Queryable().Where(x => x.Id == id).SplitTable(SplitDateId.StartDate, SplitDateId.EndDate) + .Mapper((x) => + { + x.Steps = Db.Queryable() + .Where(y => y.InstallId == id) + .OrderBy(y => y.Index) + .SplitTable(SplitDateId.StartDate, SplitDateId.EndDate) + .ToArray(); + }) + .SingleAsync(); + } + #endregion + + #region 查询步骤 + /// + /// 查询步骤 + /// + /// 编号 + /// + public async Task GetSteps(string installId) + { + return await GetStepsDO(installId); + } + + /// + /// 查询步骤数据 + /// + /// 编号 + /// + public async Task GetStepsDO(string installId) + { + SplitDateId SplitDateId = new SplitDateId(installId, 2); + return await Db.Queryable().Where(x => x.InstallId == installId).OrderBy(x => x.Index).SplitTable(SplitDateId.StartDate, SplitDateId.EndDate) + .ToArrayAsync(); + } + #endregion + } +} diff --git a/ZhongLian/ZhongLianService/MaintenanceService.cs b/ZhongLian/ZhongLianService/MaintenanceService.cs new file mode 100644 index 0000000..6def416 --- /dev/null +++ b/ZhongLian/ZhongLianService/MaintenanceService.cs @@ -0,0 +1,162 @@ +using CommonModel; +using Google.Api; +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianInterface; +using ZhongLianModel; + +namespace ZhongLianService +{ + public class MaintenanceService: IMaintenanceService + { + public MaintenanceService(IServiceProvider services, ISqlSugarClient sqlSugarClient) + { + Services = services; + Db = sqlSugarClient; + + Db.CodeFirst.SplitTables().InitTables(typeof(MaintenanceDO)); + } + + private readonly IServiceProvider Services; + + private readonly ISqlSugarClient Db; + + public async Task InserDO(MaintenanceDO maintenance) + { + await Db.Insertable(maintenance).SplitTable().ExecuteCommandAsync(); + return maintenance; + } + + public string InsertCheck(MaintenanceDO maintenance) + { + var _MaxId = Db.Queryable().SplitTable(DateTime.Today, DateTime.Today.AddDays(1)).Max(x => x.Id); + if (string.IsNullOrEmpty(_MaxId)) + { + maintenance.Id = $"MTC{DateTime.Now.ToString("yyyyMMdd")}000001"; + } + else + { + maintenance.Id = $"MTC{DateTime.Now.ToString("yyyyMMdd")}{(Convert.ToInt32(_MaxId.Substring(11, 6)) + 1).ToString().PadLeft(6, '0')}"; + } + + maintenance.State = 0; + + maintenance.CreateDate = DateTime.Now; + + return ""; + } + + public async Task UpdateDO(MaintenanceDO maintenance) + { + var paramService = Services.GetRequiredService(); + + if (maintenance.BomCodes != null && maintenance.BomCodes.Length > 0) + { + foreach(var code in maintenance.BomCodes) + { + await paramService.Use(code); + } + } + + if (!string.IsNullOrEmpty(maintenance.ErrorCodeCode)) + { + await paramService.Use(maintenance.ErrorCodeCode); + } + + if (maintenance.State > 1) { + maintenance.BomCodes = null; + maintenance.Boms = null; + maintenance.ErrorRemarkPhoto = null; + maintenance.ProcessResultPhoto = null; + } + + await Db.Updateable(maintenance).IgnoreColumns(ignoreAllNullColumns: true).Where(x => x.Id == maintenance.Id).SplitTable().ExecuteCommandAsync(); + + return maintenance; + } + + public string UpdateCheck(MaintenanceDO maintenance) + { + if (string.IsNullOrEmpty(maintenance.Id)) + { + return "维保单编号不存在"; + } + SplitDateId SplitDateId = new SplitDateId(maintenance.Id!, 3); + if (!Db.Queryable().SplitTable(SplitDateId.StartDate, SplitDateId.EndDate).Any(x => x.Id == maintenance.Id)) + { + return "维保单编号不存在"; + } + + if (maintenance.State == 1) + { + maintenance.MaintenanceDate = DateTime.Now; + } + + return ""; + } + + public async Task DeleteDO(string[] ids) + { + try + { + + Db.Ado.BeginTran(); + foreach (var id in ids) + { + MaintenanceDO Maintenance = new MaintenanceDO() + { + Id = id, + State = -1 + }; + await Db.Updateable(Maintenance).IgnoreColumns(ignoreAllNullColumns: true).Where(x => x.Id == Maintenance.Id).SplitTable().ExecuteCommandAsync(); + } + Db.Ado.CommitTran(); + } + catch + { + Db.Ado.RollbackTran(); + + throw; + } + } + + public async Task GetDO(string id) + { + SplitDateId SplitDateId = new SplitDateId(id, 3); + return await Db.Queryable().Where(x => x.Id == id).SplitTable(SplitDateId.StartDate, SplitDateId.EndDate) + .SingleAsync(); + } + + public async Task> ListDO(PageYearSearch pageSearch) + { + RefAsync _Total = 0; + var _Result = await Db.Queryable() + .Where(x => x.State != -1) + .WhereIF(!string.IsNullOrEmpty(pageSearch.Search), x => + x.Id!.Contains(pageSearch.Search!) || + x.Title!.Contains(pageSearch.Search!) || + SqlFunc.JsonLike(x.MaintenanceUser, pageSearch.Search!) + ) + .WhereIF(pageSearch.Mode != null && pageSearch.Mode.State != null, x => x.State == pageSearch.Mode!.State) + .WhereIF(pageSearch.Mode != null && !string.IsNullOrEmpty(pageSearch.Mode.MaintenanceUid), x => + x.MaintenanceUid == pageSearch.Mode!.MaintenanceUid + ) + .OrderBy("(CASE State WHEN 2 THEN 0 ELSE State END) ASC") + .OrderByDescending(x => x.Id) + .SplitTable((DateTime)pageSearch.StartDate!, (DateTime)pageSearch.EndDate!) + .ToPageListAsync(pageSearch.Index, pageSearch.Size, _Total); + return new PageData() + { + Index = pageSearch.Index, + Size = pageSearch.Size, + Data = _Result, + Total = _Total.Value + }; + } + } +} diff --git a/ZhongLian/ZhongLianService/ParamService.cs b/ZhongLian/ZhongLianService/ParamService.cs new file mode 100644 index 0000000..2e4cd28 --- /dev/null +++ b/ZhongLian/ZhongLianService/ParamService.cs @@ -0,0 +1,113 @@ +using CommonModel; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianInterface; +using ZhongLianModel; + +namespace ZhongLianService +{ + public class ParamService : IParamService + { + public ParamService(IServiceProvider services, ISqlSugarClient sqlSugarClient) + { + Services = services; + Db = sqlSugarClient; + + Db.CodeFirst.InitTables(typeof(ParamDO)); + } + + private readonly IServiceProvider Services; + + private readonly ISqlSugarClient Db; + + /// + /// 创建 + /// + /// 参数 + /// + public async Task Insert(ParamDO param) + { + await Db.Insertable(param).ExecuteCommandAsync(); + return param; + } + + /// + /// 创建校验 + /// + /// 参数 + /// + public string InsertCheck(ParamDO param) + { + + if (string.IsNullOrEmpty(param.Name)) + { + return "参数不能为空"; + } + + if (string.IsNullOrEmpty(param.Id)) + { + var _MaxId = Db.Queryable().Max(x => x.Id); + + if (string.IsNullOrEmpty(_MaxId)) + { + param.Id = $"PM000001"; + } + else + { + param.Id = $"PM{(Convert.ToInt32(_MaxId.Substring(2, 6)) + 1).ToString().PadLeft(6, '0')}"; + } + } + else + { + if (Db.Queryable().Any(x => x.Id == param.Id)) + { + return "编号已存在"; + } + } + + param.UseCount = 0; + + return ""; + } + + public async Task Update(ParamDO param) + { + await Db.Updateable(param).IgnoreColumns(ignoreAllNullColumns: true).Where(x => x.Id == param.Id).ExecuteCommandAsync(); + return param; + } + + public async Task Use(string id) { + await Db.Updateable().SetColumns(x => x.UseCount == (x.UseCount + 1)).Where(x => x.Id == id).ExecuteCommandAsync(); + } + + public string UpdateCheck(ParamDO param) + { + if (string.IsNullOrEmpty(param.Id) || !Db.Queryable().Any(x => x.Id == param.Id)) + { + return "参数不存在"; + } + + return ""; + } + + public async Task Delete(string[] ids) + { + await Db.Deleteable().In(ids).ExecuteCommandAsync(); + } + + public async Task> List(ParamDO param) + { + var _Result = await Db.Queryable() + .WhereIF(!string.IsNullOrEmpty(param.Category), x => x.Category == param.Category) + .WhereIF(!string.IsNullOrEmpty(param.Id), x => x.Id == param.Id) + .WhereIF(!string.IsNullOrEmpty(param.Name), x => x.Name!.Contains(param.Name!)) + .OrderByDescending(x => x.UseCount) + .ToListAsync(); + return _Result; + } + } +} diff --git a/ZhongLian/ZhongLianService/ProjectService.cs b/ZhongLian/ZhongLianService/ProjectService.cs new file mode 100644 index 0000000..e76453b --- /dev/null +++ b/ZhongLian/ZhongLianService/ProjectService.cs @@ -0,0 +1,266 @@ +using CommonModel; +using Dapr.Actors; +using Dapr.Actors.Client; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianInterface; +using ZhongLianModel; + +namespace ZhongLianService +{ + /// + /// 工程服务 + /// + public class ProjectService : IProjectService + { + public ProjectService(IServiceProvider services, ISqlSugarClient sqlSugarClient) + { + Services = services; + Db = sqlSugarClient; + + //创建表 + Db.CodeFirst.SetStringDefaultLength(200).InitTables(typeof(ProjectDO)); + //Db.CodeFirst.InitTables(typeof(GroupDO), typeof(CompanyDO), typeof(DeviceDO)); + } + + private readonly IServiceProvider Services; + + private readonly ISqlSugarClient Db; + + /// + /// 插入 + /// + /// 工程实体 + /// 工程实体 + public Task Insert(ProjectDO project) + { + try + { + Db.Ado.BeginTran(); + var group = new GroupDO + { + Id = Guid.NewGuid().ToString(), + Name = project.Name, + System = "ZL", + Type = 0, + PId = project.CompanyId + }; + if (string.IsNullOrEmpty(group.Code)) + { + var _MaxCode = Db.Queryable().MaxAsync(x => x.Code).Result; + if (string.IsNullOrEmpty(_MaxCode)) + { + group.Code = "GP00001"; + } + else + { + group.Code = $"GP{(Convert.ToInt32(_MaxCode.Substring(2, 5)) + 1).ToString().PadLeft(5, '0')}"; + } + } + group.CreateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + group.Deleted = 0; + Db.Insertable(group).ExecuteCommand(); + + project.Id = group.Id; + if (string.IsNullOrEmpty(project.Code)) + { + //生成用户编号 + var _MaxCode = Db.Queryable().MaxAsync(x => x.Code).Result; + if (string.IsNullOrEmpty(_MaxCode)) + { + project.Code = "PJ00001"; + } + else + { + project.Code = $"PJ{(Convert.ToInt32(_MaxCode.Substring(2, 5)) + 1).ToString().PadLeft(5, '0')}"; + } + } + project.CreateDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + project.Deleted = 0; + Db.Insertable(project).ExecuteCommand(); + Db.Ado.CommitTran(); + return Task.FromResult(project); + } + catch + { + Db.Ado.RollbackTran(); + throw; + } + } + + /// + /// 更新 + /// + /// 工程实体 + /// 工程实体 + public Task Update(ProjectDO project) + { + try + { + Db.Ado.BeginTran(); + Db.Updateable(new GroupDO + { + Id = project.Id, + Name = project.Name, + System = "ZL", + Type = 0, + PId = project.CompanyId + }).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand(); + + Db.Updateable(project) + .IgnoreColumns(ignoreAllNullColumns: true) + .ExecuteCommand(); + + Db.Ado.CommitTran(); + return Task.FromResult(project); + } + catch + { + Db.Ado.RollbackTran(); + throw; + } + } + + /// + /// 删除 + /// + /// Id数组 + /// + + public Task Delete(string[] ids) + { + try + { + Db.Ado.BeginTran(); + Db.Deleteable().In(ids).ExecuteCommand(); + Db.Deleteable().In(ids).ExecuteCommand(); + Db.Ado.CommitTran(); + return Task.CompletedTask; + } + catch + { + Db.Ado.RollbackTran(); + throw; + } + } + + /// + /// 根据编号查询 + /// + /// 编号 + /// 工程 + public Task Get(string id) + { + var result = Db.Queryable() + .LeftJoin((a, b) => a.CompanyId == b.Id) + .Select((a, b) => new ProjectDO + { + Id = a.Id.SelectAll(), + CompanyName = b.Name + }).First(); + return Task.FromResult(result); + } + + /// + /// 分页查询 + /// + /// 分页对象 + /// 分页对象 + public Task> List(PageSearch page) + { + RefAsync total = 0; + + string _Search = page.Search!; + + + string _Code = page.Mode!.Code!; + + string _Name = page.Mode!.Name!; + + string _CompanyId = page.Mode!.CompanyId!; + + string _Area = page.Mode!.Area!; + + string _AddressName = page.Mode!.AddressName!; + + string _CU = page.Mode!.CU!; + + string _SU = page.Mode!.SU!; + + string _PM = page.Mode!.PM!; + + var result = Db.Queryable() + .LeftJoin((x, y) => x.CompanyId == y.Id) + .Where(x => x.Deleted == 0) + .WhereIF(!string.IsNullOrEmpty(_Search), + x => x.Name!.Contains(_Search) || x.Code!.Contains(_Search) + ) + .WhereIF(!string.IsNullOrEmpty(_Code), x => x.Code!.Contains(_Code)) + .WhereIF(!string.IsNullOrEmpty(_Name), x => x.Name!.Contains(_Name)) + .WhereIF(!string.IsNullOrEmpty(_CompanyId), x => x.CompanyId!.Contains(_CompanyId)) + .WhereIF(!string.IsNullOrEmpty(_Area), x => x.Area!.Contains(_Area)) + .WhereIF(!string.IsNullOrEmpty(_AddressName), x => x.AddressName!.Contains(_AddressName)) + .WhereIF(!string.IsNullOrEmpty(_CU), x => x.CU!.Contains(_CU)) + .WhereIF(!string.IsNullOrEmpty(_SU), x => x.SU!.Contains(_SU)) + .WhereIF(!string.IsNullOrEmpty(_PM), x => x.PM!.Contains(_PM)) + .Select((x, y) => new ProjectDO + { + Id = x.Id.SelectAll(), + CompanyName = y.Name + }) + .OrderBy((x) => new { NameF = "CONVERT(Name USING GBK) ASC", x.Name }) + .ToPageListAsync(page.Index!, page.Size!, total).Result; + return Task.FromResult(new PageData + { + Data = result, + Total = total.Value + }); + + } + + /// + /// 3D地图设备数量获取 + /// + /// + public Task> GeoCount() + { + var Province = Db.Queryable() + .LeftJoin((x, y) => x.Id == y.ProjectId) + .Where((x,y)=>x.Deleted == 0 && y.Deleted == 0) + .GroupBy((x, y) => x.ProvinceCode) + .Select((x, y) => new GeoProjectDTO + { + Code = x.ProvinceCode, + ParentCode = "100000", + Count = SqlFunc.AggregateCount(y.ProjectId) + }); + var City = Db.Queryable() + .LeftJoin((x, y) => x.Id == y.ProjectId) + .Where((x, y) => x.Deleted == 0 && y.Deleted == 0) + .GroupBy((x, y) => new { x.CityCode, x.ProvinceCode }) + .Select((x, y) => new GeoProjectDTO + { + Code = x.CityCode, + ParentCode = x.ProvinceCode, + Count = SqlFunc.AggregateCount(y.ProjectId) + }); + var Area = Db.Queryable() + .LeftJoin((x, y) => x.Id == y.ProjectId) + .Where((x, y) => x.Deleted == 0 && y.Deleted == 0) + .GroupBy((x, y) => new { x.AreaCode, x.CityCode }) + .Select((x, y) => new GeoProjectDTO + { + Code = x.AreaCode, + ParentCode = x.CityCode, + Count = SqlFunc.AggregateCount(y.ProjectId) + }); + return Task.FromResult(Db.Union(Province, City, Area).ToList()); + } + } +} diff --git a/ZhongLian/ZhongLianService/Properties/launchSettings.json b/ZhongLian/ZhongLianService/Properties/launchSettings.json new file mode 100644 index 0000000..c16ccfd --- /dev/null +++ b/ZhongLian/ZhongLianService/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "ZhongLianService": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:64278;http://localhost:64281" + } + } +} \ No newline at end of file diff --git a/ZhongLian/ZhongLianService/ZhongLianService.cs b/ZhongLian/ZhongLianService/ZhongLianService.cs new file mode 100644 index 0000000..15f429d --- /dev/null +++ b/ZhongLian/ZhongLianService/ZhongLianService.cs @@ -0,0 +1,42 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ZhongLianInterface; + +namespace ZhongLianService +{ + public static class ZhongLianServiceExtend + { + public static IServiceCollection InitZhongLianService(this IServiceCollection services, IConfiguration configuration) + { +#if !DEBUG + services.AddActors(option => + { + option.Actors.RegisterActor(); + }); +#endif + SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig() + { + DbType = SqlSugar.DbType.MySql, + ConnectionString = configuration.GetConnectionString("Default"), + IsAutoCloseConnection = true, + }); + services.AddSingleton(sqlSugar); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + return services; + } + } + + public class ZhongLianService + { + } +} diff --git a/ZhongLian/ZhongLianService/ZhongLianService.csproj b/ZhongLian/ZhongLianService/ZhongLianService.csproj new file mode 100644 index 0000000..2d61623 --- /dev/null +++ b/ZhongLian/ZhongLianService/ZhongLianService.csproj @@ -0,0 +1,22 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + + + +