From 1aa01264547ffd2fb33c9dc88a894b17b2779d0e Mon Sep 17 00:00:00 2001 From: liguoyang Date: Mon, 15 Apr 2024 17:06:07 +0800 Subject: [PATCH 01/13] fix dir --- Dlhis.Jinko.Face.sln | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Dlhis.Jinko.Face.sln b/Dlhis.Jinko.Face.sln index fcddfbee..377d7609 100644 --- a/Dlhis.Jinko.Face.sln +++ b/Dlhis.Jinko.Face.sln @@ -25,8 +25,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.User", "Src\Dlhis.Use EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys", "Src\Dlhis.Sys\Dlhis.Sys.csproj", "{925048C9-5940-4B51-8480-4DC908C754A1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{8317C526-3523-4195-9B19-2F17CFD71927}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj", "{85A345C7-913E-4C1B-BE1C-600DE408A02F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}" @@ -37,10 +35,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{48 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.External", "Src\Dlhis.External\Dlhis.External.csproj", "{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{961523DE-51BF-42A0-A294-708752C5718D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Scheduled.Api", "Src\Dlhis.Scheduled.Api\Dlhis.Scheduled.Api.csproj", "{9EA85FB2-F320-4F97-B278-00652CF35BD8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{D4043506-7247-4DDC-9751-927403515669}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,10 +75,6 @@ Global {925048C9-5940-4B51-8480-4DC908C754A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {925048C9-5940-4B51-8480-4DC908C754A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {925048C9-5940-4B51-8480-4DC908C754A1}.Release|Any CPU.Build.0 = Release|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Release|Any CPU.Build.0 = Release|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.Build.0 = Debug|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -95,14 +91,18 @@ Global {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.Build.0 = Release|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Release|Any CPU.Build.0 = Release|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.Build.0 = Release|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.Build.0 = Release|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,12 +114,12 @@ Global {D1F81CB7-F3EF-4196-A751-468248368020} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A} {9F9BC299-3CDD-4CCE-80CA-5FE57332B1F0} = {57074FD8-1A2F-40C7-8476-001778A3F65D} {925048C9-5940-4B51-8480-4DC908C754A1} = {57074FD8-1A2F-40C7-8476-001778A3F65D} - {8317C526-3523-4195-9B19-2F17CFD71927} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {85A345C7-913E-4C1B-BE1C-600DE408A02F} = {57074FD8-1A2F-40C7-8476-001778A3F65D} {1F337648-8A22-4601-A842-0F634FBA2825} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A} {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5} = {489252FB-A44B-46EE-B065-21CDCB724441} - {961523DE-51BF-42A0-A294-708752C5718D} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {9EA85FB2-F320-4F97-B278-00652CF35BD8} = {AA987BDF-EF63-467B-AD04-59F9B10D9000} + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} + {D4043506-7247-4DDC-9751-927403515669} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0} From a24b3a02941eea0ebe800fa8bd691d58cee87bcd Mon Sep 17 00:00:00 2001 From: liguoyang Date: Mon, 15 Apr 2024 17:06:07 +0800 Subject: [PATCH 02/13] fix dir --- Dlhis.Jinko.Face.sln | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Dlhis.Jinko.Face.sln b/Dlhis.Jinko.Face.sln index fcddfbee..377d7609 100644 --- a/Dlhis.Jinko.Face.sln +++ b/Dlhis.Jinko.Face.sln @@ -25,8 +25,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.User", "Src\Dlhis.Use EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys", "Src\Dlhis.Sys\Dlhis.Sys.csproj", "{925048C9-5940-4B51-8480-4DC908C754A1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{8317C526-3523-4195-9B19-2F17CFD71927}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj", "{85A345C7-913E-4C1B-BE1C-600DE408A02F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}" @@ -37,10 +35,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{48 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.External", "Src\Dlhis.External\Dlhis.External.csproj", "{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{961523DE-51BF-42A0-A294-708752C5718D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Scheduled.Api", "Src\Dlhis.Scheduled.Api\Dlhis.Scheduled.Api.csproj", "{9EA85FB2-F320-4F97-B278-00652CF35BD8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{D4043506-7247-4DDC-9751-927403515669}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,10 +75,6 @@ Global {925048C9-5940-4B51-8480-4DC908C754A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {925048C9-5940-4B51-8480-4DC908C754A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {925048C9-5940-4B51-8480-4DC908C754A1}.Release|Any CPU.Build.0 = Release|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Release|Any CPU.Build.0 = Release|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.Build.0 = Debug|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -95,14 +91,18 @@ Global {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.Build.0 = Release|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Release|Any CPU.Build.0 = Release|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.Build.0 = Release|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.Build.0 = Release|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,12 +114,12 @@ Global {D1F81CB7-F3EF-4196-A751-468248368020} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A} {9F9BC299-3CDD-4CCE-80CA-5FE57332B1F0} = {57074FD8-1A2F-40C7-8476-001778A3F65D} {925048C9-5940-4B51-8480-4DC908C754A1} = {57074FD8-1A2F-40C7-8476-001778A3F65D} - {8317C526-3523-4195-9B19-2F17CFD71927} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {85A345C7-913E-4C1B-BE1C-600DE408A02F} = {57074FD8-1A2F-40C7-8476-001778A3F65D} {1F337648-8A22-4601-A842-0F634FBA2825} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A} {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5} = {489252FB-A44B-46EE-B065-21CDCB724441} - {961523DE-51BF-42A0-A294-708752C5718D} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {9EA85FB2-F320-4F97-B278-00652CF35BD8} = {AA987BDF-EF63-467B-AD04-59F9B10D9000} + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} + {D4043506-7247-4DDC-9751-927403515669} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0} From baa1439e91e20d6176e388db56c505e73d7f7e5c Mon Sep 17 00:00:00 2001 From: liguoyang Date: Mon, 15 Apr 2024 17:06:07 +0800 Subject: [PATCH 03/13] fix dir --- Dlhis.Jinko.Face.sln | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Dlhis.Jinko.Face.sln b/Dlhis.Jinko.Face.sln index fcddfbee..377d7609 100644 --- a/Dlhis.Jinko.Face.sln +++ b/Dlhis.Jinko.Face.sln @@ -25,8 +25,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.User", "Src\Dlhis.Use EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys", "Src\Dlhis.Sys\Dlhis.Sys.csproj", "{925048C9-5940-4B51-8480-4DC908C754A1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{8317C526-3523-4195-9B19-2F17CFD71927}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj", "{85A345C7-913E-4C1B-BE1C-600DE408A02F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}" @@ -37,10 +35,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{48 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.External", "Src\Dlhis.External\Dlhis.External.csproj", "{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{961523DE-51BF-42A0-A294-708752C5718D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Scheduled.Api", "Src\Dlhis.Scheduled.Api\Dlhis.Scheduled.Api.csproj", "{9EA85FB2-F320-4F97-B278-00652CF35BD8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{D4043506-7247-4DDC-9751-927403515669}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,10 +75,6 @@ Global {925048C9-5940-4B51-8480-4DC908C754A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {925048C9-5940-4B51-8480-4DC908C754A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {925048C9-5940-4B51-8480-4DC908C754A1}.Release|Any CPU.Build.0 = Release|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8317C526-3523-4195-9B19-2F17CFD71927}.Release|Any CPU.Build.0 = Release|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.Build.0 = Debug|Any CPU {85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -95,14 +91,18 @@ Global {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.Build.0 = Release|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {961523DE-51BF-42A0-A294-708752C5718D}.Release|Any CPU.Build.0 = Release|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU {9EA85FB2-F320-4F97-B278-00652CF35BD8}.Release|Any CPU.Build.0 = Release|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35}.Release|Any CPU.Build.0 = Release|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,12 +114,12 @@ Global {D1F81CB7-F3EF-4196-A751-468248368020} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A} {9F9BC299-3CDD-4CCE-80CA-5FE57332B1F0} = {57074FD8-1A2F-40C7-8476-001778A3F65D} {925048C9-5940-4B51-8480-4DC908C754A1} = {57074FD8-1A2F-40C7-8476-001778A3F65D} - {8317C526-3523-4195-9B19-2F17CFD71927} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {85A345C7-913E-4C1B-BE1C-600DE408A02F} = {57074FD8-1A2F-40C7-8476-001778A3F65D} {1F337648-8A22-4601-A842-0F634FBA2825} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A} {8472596E-0DE7-4A17-93D6-F0FC7D44FDF5} = {489252FB-A44B-46EE-B065-21CDCB724441} - {961523DE-51BF-42A0-A294-708752C5718D} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {9EA85FB2-F320-4F97-B278-00652CF35BD8} = {AA987BDF-EF63-467B-AD04-59F9B10D9000} + {A54426E2-1CA0-48AB-BBA6-07CDE2807E35} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} + {D4043506-7247-4DDC-9751-927403515669} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0} From 1276c53305b79bc8b6e44ed2463d975991bfe6bb Mon Sep 17 00:00:00 2001 From: liguoyang Date: Wed, 17 Apr 2024 15:38:25 +0800 Subject: [PATCH 04/13] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 528cdd51c05d26437f0b23f415e06311b667e9f7 Author: liguoyang Date: Wed Apr 17 15:37:30 2024 +0800 feat 访客预约 commit e73a3fcd9307f86aba2c39578495c03cde1d41f9 Author: liguoyang Date: Tue Apr 16 16:15:16 2024 +0800 feat 业务curd commit b98b6e2764fea875866e11f790f388ccf3c234b5 Merge: a3dcec3 965e84b Author: liguoyang Date: Tue Apr 16 14:56:30 2024 +0800 Merge branch 'feat-visitorAppointments' of https://git.dlhis.com/liguoyang/jinko.yikatong into feat-visitorAppointments commit a3dcec30e1289fbb09de8f85009d3931d971337a Author: liguoyang Date: Fri Apr 12 17:57:49 2024 +0800 fix appsettings commit 766fbec0c45a3852a75a7a37686b885ac3b0a77a Author: liguoyang Date: Fri Apr 12 17:37:01 2024 +0800 add dockerfile commit 86731d41fee97ba073065ed1b807987760a371a7 Author: liguoyang Date: Sun Apr 14 20:11:56 2024 +0800 fix 测试websocket链接 commit 1301b126a9ba9a7d97cf45967cf2915e1169c505 Author: liguoyang Date: Fri Apr 12 17:57:49 2024 +0800 fix appsettings commit 081f3a67896c67891c3f80edde82a440b8736851 Author: liguoyang Date: Fri Apr 12 17:37:01 2024 +0800 add dockerfile commit 271b6c5898b5732a35ccfa0629ce89442ac49143 Author: liguoyang Date: Fri Apr 12 17:34:26 2024 +0800 test 提交测试代码 commit 965e84b6f3b7f925f8021c9b996cce961b896dea Merge: 578eb6a 6a6fad1 Author: liguoyang Date: Mon Apr 15 17:06:45 2024 +0800 Merge branch 'feat-visitorAppointments' of https://git.dlhis.com/liguoyang/jinko.yikatong into feat-visitorAppointments commit 578eb6afbd96f0bfe4aaf8058fd4743309c74d62 Author: liguoyang Date: Sun Apr 14 20:11:56 2024 +0800 fix 测试websocket链接 commit 114511f1daea64b7dbf9c3c38b73e28b6d0301e6 Author: liguoyang Date: Fri Apr 12 17:57:49 2024 +0800 fix appsettings commit 5eacfa8af8087eade8553266a12a2cf42305716b Author: liguoyang Date: Fri Apr 12 17:37:01 2024 +0800 add dockerfile commit b2ffff1f099be343d89690014d05cb859776acbb Author: liguoyang Date: Fri Apr 12 17:34:26 2024 +0800 test 提交测试代码 commit 6a6fad1d1b8772eebf5df12cd74cfd5c955ff560 Author: liguoyang Date: Sun Apr 14 20:11:56 2024 +0800 fix 测试websocket链接 commit 9ce3c4d6f63957c175d65370d9a6b80e10f4254f Author: liguoyang Date: Fri Apr 12 17:57:49 2024 +0800 fix appsettings commit c637fd89850cf289d7da457c6c6f47354b5beed3 Author: liguoyang Date: Fri Apr 12 17:37:01 2024 +0800 add dockerfile commit 58c39815b1c45a99aea0caf503fcb1365c957f03 Author: liguoyang Date: Fri Apr 12 17:34:26 2024 +0800 test 提交测试代码 --- Dlhis.Jinko.Face.sln | 18 +- Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj | 4 - Src/Dlhis.Basic.Api/IDeviceGroupApi.cs | 20 + .../Response/DeviceUnderGroupResponse.cs | 21 + .../Controllers/DeviceGroupsController.cs | 10 + Src/Dlhis.Basic/Device/Dtos/IPPortDto.cs | 8 - .../Device/Request/DeviceGroupSaveRequest.cs | 18 +- .../Device/Response/DeviceGroupResponse.cs | 19 + .../Device/Services/IDeviceGroupService.cs | 2 + .../Implements/DeviceConnectService.cs | 3 +- .../Services/Implements/DeviceGroupService.cs | 37 +- .../Controllers/GainfoFacesController.cs | 32 -- .../Controllers/GainfosController.cs | 39 +- .../Request/GainfoCheckIdNoAndNameRequest.cs | 19 + .../Organization/Services/IGainfoService.cs | 10 +- .../Services/Implements/GainfoService.cs | 111 +---- Src/Dlhis.Basic/Packs/SqlSugarPack.cs | 4 +- Src/Dlhis.Basic/appsettings.Development.json | 1 - Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs | 20 +- .../Device/Entities/DeviceGroupEntity.cs | 6 + .../Device/Entities/DeviceTaskEntity.cs | 6 +- Src/Dlhis.Entity/Dlhis.Entity.csproj | 4 - .../Entity/AppointmentAreaAssignmentEntity.cs | 28 ++ .../Visitor/Entity/AppointmentAreaEntity.cs | 54 +++ .../Visitor/Entity/ApponintmentAreaEntity.cs | 44 ++ .../Entity/VisitorAppointmentDetailEntity.cs | 73 +++ .../Entity/VisitorAppointmentEntity.cs | 30 ++ .../Visitor/Enums/AppointmentAreaEnumType.cs | 22 + .../Enums/AppointmentDetailEnumType.cs | 35 ++ .../Visitor/Enums/ApponintmentAreaEnumType.cs | 19 + .../Enums/VisitorAppointmentDetailEnumType.cs | 22 + .../Controllers/AppointmentPushController.cs | 26 ++ Src/Dlhis.Message/Dlhis.Message.csproj | 16 + Src/Dlhis.Message/Dockerfile | 23 + Src/Dlhis.Message/Packs/SignalRPack.cs | 22 + Src/Dlhis.Message/Program.cs | 20 + .../Properties/launchSettings.json | 15 + .../Services/IVisitorAppointmentService.cs | 6 + Src/Dlhis.Message/TestBackgroundService.cs | 26 ++ Src/Dlhis.Message/VisitorAppointmentHub.cs | 19 + .../appsettings.Development.json | 25 + Src/Dlhis.Message/appsettings.json | 72 +++ Src/Dlhis.ScheduledTask/BaseJob.cs | 4 +- .../TaskAssignment/Dto/TaskDto.cs | 25 + .../Services/Implements/AssignmentService.cs | 436 +++++++++--------- .../Controllers/AppointmentsController.cs | 84 ++++ .../ApponintmentAreasController.cs | 68 +++ .../Dto/AppointmentReceiveItemDto.cs | 31 ++ .../Request/AppointmentAreaAssignRequest.cs | 18 + .../Request/AppointmentAreaSaveRequest.cs | 35 ++ .../Request/AppointmentConfirmRequest.cs | 6 + .../Request/AppointmentIdNoPageRequest.cs | 14 + .../Request/AppointmentPageRequest.cs | 9 + .../Request/AppointmentReceiveRequest.cs | 83 ++++ .../Request/ApponintmentAreaSaveRequest.cs | 18 + .../Response/AppointmentDetailResponse.cs | 56 +++ .../Response/AppointmentPageResponse.cs | 22 + .../Response/ApponintmentAreaPageResponse.cs | 34 ++ .../Services/IAppointmentService.cs | 42 ++ .../Services/IApponintmentAreaService.cs | 17 + .../Services/Implements/AppointmentService.cs | 189 ++++++++ .../Implements/ApponintmentAreaService.cs | 93 ++++ Src/Dlhis.Visitor/Dlhis.Visitor.csproj | 23 + Src/Dlhis.Visitor/Packs/SqlSugarPack.cs | 36 ++ Src/Dlhis.Visitor/Program.cs | 21 + .../Properties/launchSettings.json | 15 + .../appsettings.Development.json | 35 ++ Src/Dlhis.Visitor/appsettings.json | 75 +++ 68 files changed, 2086 insertions(+), 412 deletions(-) create mode 100644 Src/Dlhis.Basic.Api/IDeviceGroupApi.cs create mode 100644 Src/Dlhis.Basic.Api/Response/DeviceUnderGroupResponse.cs delete mode 100644 Src/Dlhis.Basic/Device/Dtos/IPPortDto.cs create mode 100644 Src/Dlhis.Basic/Device/Response/DeviceGroupResponse.cs delete mode 100644 Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs create mode 100644 Src/Dlhis.Basic/Organization/Request/GainfoCheckIdNoAndNameRequest.cs create mode 100644 Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs create mode 100644 Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaEntity.cs create mode 100644 Src/Dlhis.Entity/Visitor/Entity/ApponintmentAreaEntity.cs create mode 100644 Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs create mode 100644 Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentEntity.cs create mode 100644 Src/Dlhis.Entity/Visitor/Enums/AppointmentAreaEnumType.cs create mode 100644 Src/Dlhis.Entity/Visitor/Enums/AppointmentDetailEnumType.cs create mode 100644 Src/Dlhis.Entity/Visitor/Enums/ApponintmentAreaEnumType.cs create mode 100644 Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailEnumType.cs create mode 100644 Src/Dlhis.Message/Controllers/AppointmentPushController.cs create mode 100644 Src/Dlhis.Message/Dlhis.Message.csproj create mode 100644 Src/Dlhis.Message/Dockerfile create mode 100644 Src/Dlhis.Message/Packs/SignalRPack.cs create mode 100644 Src/Dlhis.Message/Program.cs create mode 100644 Src/Dlhis.Message/Properties/launchSettings.json create mode 100644 Src/Dlhis.Message/Services/IVisitorAppointmentService.cs create mode 100644 Src/Dlhis.Message/TestBackgroundService.cs create mode 100644 Src/Dlhis.Message/VisitorAppointmentHub.cs create mode 100644 Src/Dlhis.Message/appsettings.Development.json create mode 100644 Src/Dlhis.Message/appsettings.json create mode 100644 Src/Dlhis.ScheduledTask/TaskAssignment/Dto/TaskDto.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Controllers/AppointmentsController.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Dto/AppointmentReceiveItemDto.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaSaveRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/AppointmentConfirmRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/AppointmentIdNoPageRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/AppointmentPageRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/AppointmentReceiveRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Request/ApponintmentAreaSaveRequest.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Response/AppointmentDetailResponse.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Response/AppointmentPageResponse.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Response/ApponintmentAreaPageResponse.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Services/IAppointmentService.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Services/IApponintmentAreaService.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs create mode 100644 Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs create mode 100644 Src/Dlhis.Visitor/Dlhis.Visitor.csproj create mode 100644 Src/Dlhis.Visitor/Packs/SqlSugarPack.cs create mode 100644 Src/Dlhis.Visitor/Program.cs create mode 100644 Src/Dlhis.Visitor/Properties/launchSettings.json create mode 100644 Src/Dlhis.Visitor/appsettings.Development.json create mode 100644 Src/Dlhis.Visitor/appsettings.json diff --git a/Dlhis.Jinko.Face.sln b/Dlhis.Jinko.Face.sln index 377d7609..f8c00af7 100644 --- a/Dlhis.Jinko.Face.sln +++ b/Dlhis.Jinko.Face.sln @@ -35,12 +35,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{48 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.External", "Src\Dlhis.External\Dlhis.External.csproj", "{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Scheduled.Api", "Src\Dlhis.Scheduled.Api\Dlhis.Scheduled.Api.csproj", "{9EA85FB2-F320-4F97-B278-00652CF35BD8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Scheduled.Api", "Src\Dlhis.Scheduled.Api\Dlhis.Scheduled.Api.csproj", "{9EA85FB2-F320-4F97-B278-00652CF35BD8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.Canteen\Dlhis.Canteen.csproj", "{A54426E2-1CA0-48AB-BBA6-07CDE2807E35}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen.Api", "Src\Dlhis.Canteen.Api\Dlhis.Canteen.Api.csproj", "{D4043506-7247-4DDC-9751-927403515669}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Visitor", "Src\Dlhis.Visitor\Dlhis.Visitor.csproj", "{69E8A91A-5D05-4327-BC24-038523C7628C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Message", "Message", "{65E76F97-E78A-4C95-B788-4091236B1A79}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Message", "Src\Dlhis.Message\Dlhis.Message.csproj", "{053BF7B2-B1A0-435F-9C77-2EF5622CC5C5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -103,6 +109,14 @@ Global {D4043506-7247-4DDC-9751-927403515669}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.ActiveCfg = Release|Any CPU {D4043506-7247-4DDC-9751-927403515669}.Release|Any CPU.Build.0 = Release|Any CPU + {69E8A91A-5D05-4327-BC24-038523C7628C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69E8A91A-5D05-4327-BC24-038523C7628C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69E8A91A-5D05-4327-BC24-038523C7628C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69E8A91A-5D05-4327-BC24-038523C7628C}.Release|Any CPU.Build.0 = Release|Any CPU + {053BF7B2-B1A0-435F-9C77-2EF5622CC5C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {053BF7B2-B1A0-435F-9C77-2EF5622CC5C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {053BF7B2-B1A0-435F-9C77-2EF5622CC5C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {053BF7B2-B1A0-435F-9C77-2EF5622CC5C5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -120,6 +134,8 @@ Global {9EA85FB2-F320-4F97-B278-00652CF35BD8} = {AA987BDF-EF63-467B-AD04-59F9B10D9000} {A54426E2-1CA0-48AB-BBA6-07CDE2807E35} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} {D4043506-7247-4DDC-9751-927403515669} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B} + {69E8A91A-5D05-4327-BC24-038523C7628C} = {489252FB-A44B-46EE-B065-21CDCB724441} + {053BF7B2-B1A0-435F-9C77-2EF5622CC5C5} = {65E76F97-E78A-4C95-B788-4091236B1A79} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0} diff --git a/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj b/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj index 2311965f..ae3784a1 100644 --- a/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj +++ b/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj @@ -10,8 +10,4 @@ - - - - diff --git a/Src/Dlhis.Basic.Api/IDeviceGroupApi.cs b/Src/Dlhis.Basic.Api/IDeviceGroupApi.cs new file mode 100644 index 00000000..790d3024 --- /dev/null +++ b/Src/Dlhis.Basic.Api/IDeviceGroupApi.cs @@ -0,0 +1,20 @@ +using Dlhis.Basic.Api.Response; +using Kurisu.Core.Result; +using Kurisu.RemoteCall.Attributes; + +namespace Dlhis.Basic.Api; + + +[EnableRemoteClient(Name = "basic-service", BaseUrl = "${InternalRequest:BasicRequestUrl}")] +public interface IDeviceGroupApi +{ + + /// + /// 获取分组下的设备 + /// + /// + /// + [Auth] + [Get("/api/deviceGroups/devices")] + Task>> GetDevicesByCodeAsync(Guid code); +} diff --git a/Src/Dlhis.Basic.Api/Response/DeviceUnderGroupResponse.cs b/Src/Dlhis.Basic.Api/Response/DeviceUnderGroupResponse.cs new file mode 100644 index 00000000..a2e8a5ea --- /dev/null +++ b/Src/Dlhis.Basic.Api/Response/DeviceUnderGroupResponse.cs @@ -0,0 +1,21 @@ +namespace Dlhis.Basic.Api.Response; + +public class DeviceUnderGroupResponse +{ + public Guid Code { get; set; } + + /// + /// 设备唯一码,IP/MAC/SNO + /// + public string UniqueNo { get; set; } + + /// + /// 品牌 + /// + public string Brand { get; set; } + + /// + /// 是否启用 + /// + public bool Enable { get; set; } +} diff --git a/Src/Dlhis.Basic/Device/Controllers/DeviceGroupsController.cs b/Src/Dlhis.Basic/Device/Controllers/DeviceGroupsController.cs index 8781919a..bfd389b3 100644 --- a/Src/Dlhis.Basic/Device/Controllers/DeviceGroupsController.cs +++ b/Src/Dlhis.Basic/Device/Controllers/DeviceGroupsController.cs @@ -71,4 +71,14 @@ public class DeviceGroupsController : ControllerBase { await _deviceGroupService.AssignDevicesAsync(request); } + + /// + /// 获取用于预约的设备组 + /// + /// + [HttpGet("type/appointment")] + public async Task> GetAppointmentGroupsAsync() + { + return await _deviceGroupService.GetAppointmentGroupsAsync(); + } } diff --git a/Src/Dlhis.Basic/Device/Dtos/IPPortDto.cs b/Src/Dlhis.Basic/Device/Dtos/IPPortDto.cs deleted file mode 100644 index 60ba4f46..00000000 --- a/Src/Dlhis.Basic/Device/Dtos/IPPortDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Dlhis.Basic.Device.Dtos -{ - public class IPPortDto - { - public string IP { get; set; } - public int Port { get; set; } - } -} diff --git a/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs b/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs index 73bf5281..b4812e81 100644 --- a/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs +++ b/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs @@ -1,9 +1,10 @@ using Dlhis.Entity.Device.Enums; +using Kurisu.AspNetCore.Utils.Extensions; using System.ComponentModel.DataAnnotations; namespace Dlhis.Basic.Device.Request; -public class DeviceGroupSaveRequest +public class DeviceGroupSaveRequest : IValidatableObject { public long? Id { get; set; } @@ -22,10 +23,23 @@ public class DeviceGroupSaveRequest /// 分类类型 DeviceTypeEnumType /// [EnumDataType(typeof(DeviceTypeEnumType))] - public DeviceTypeEnumType? Type { get; set; } + public DeviceTypeEnumType Type { get; set; } + + /// + /// 可作为预约分组 + /// + public bool AsAppointment { get; set; } /// /// 备注 /// public string Remark { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + if (AsAppointment && Type != DeviceTypeEnumType.Door) + { + yield return new ValidationResult($"作为预约分组必要为{DeviceTypeEnumType.Door.GetDescription()}类型", new[] { nameof(Type) }); + } + } } diff --git a/Src/Dlhis.Basic/Device/Response/DeviceGroupResponse.cs b/Src/Dlhis.Basic/Device/Response/DeviceGroupResponse.cs new file mode 100644 index 00000000..af01c809 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Response/DeviceGroupResponse.cs @@ -0,0 +1,19 @@ +namespace Dlhis.Basic.Device.Response; + +public class DeviceGroupResponse +{ + /// + /// id + /// + public long Id { get; set; } + + /// + /// code + /// + public Guid Code { get; set; } + + /// + /// 分组名 + /// + public string Name { get; set; } +} diff --git a/Src/Dlhis.Basic/Device/Services/IDeviceGroupService.cs b/Src/Dlhis.Basic/Device/Services/IDeviceGroupService.cs index 4335fce8..9772a7ea 100644 --- a/Src/Dlhis.Basic/Device/Services/IDeviceGroupService.cs +++ b/Src/Dlhis.Basic/Device/Services/IDeviceGroupService.cs @@ -13,4 +13,6 @@ public interface IDeviceGroupService : IScopeDependency Task> GetDevicesAsync(Guid code); Task AssignDevicesAsync(DeviceAssignRequest requests); + + Task> GetAppointmentGroupsAsync(); } diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs index 85b68b72..d735172e 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceConnectService.cs @@ -1,15 +1,14 @@ using System.Net; using System.Net.Sockets; -using Dlhis.Basic.Device.Dtos; using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Enums; using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.CustomClass; using Kurisu.SqlSugar.Services; using Mapster; -using Newtonsoft.Json; namespace Dlhis.Basic.Device.Services.Implements; diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs index 3c8797d6..e883ef88 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs @@ -78,14 +78,6 @@ public class DeviceGroupService : IDeviceGroupService } } - public async Task DeleteAsync(long id) - { - var deviceGroup = await _dbContext.Queryable().Where(x => x.Id == id).FirstAsync(); - deviceGroup.ThrowIfNull("设备分组不存在,无需删除"); - - await _dbContext.DeleteAsync(deviceGroup); - } - public async Task AssignDevicesAsync(DeviceAssignRequest request) { @@ -117,14 +109,39 @@ public class DeviceGroupService : IDeviceGroupService public async Task> GetDevicesAsync(Guid code) { - var relationships = await _dbContext.Queryable().Where(x => x.GroupCode == code).ToListAsync(); + var relationships = await _dbContext.Queryable() + .Where(x => x.GroupCode == code) + .ToListAsync(); + var deviceCodes = relationships.Select(x => x.DeviceCode); return await _dbContext.Queryable() + .LeftJoin((x, dt) => x.TemplateCode == dt.Code) .Where(x => deviceCodes.Contains(x.Code)) - .Select() + .Select((x, dt) => new DeviceUnderGroupResponse + { + UniqueNo = x.UniqueNo, + Type = x.Type, + Code = x.Code, + Enable = x.Enable, + Brand = dt.Brand + }) .ToListAsync(); + } + + public async Task> GetAppointmentGroupsAsync() + { + return await _dbContext.Queryable() + .Where(x => x.AsAppointment) + .Where(x => x.Type == DeviceTypeEnumType.Door) + .Select(x => new DeviceGroupResponse + { + Id = x.Id, + Code = x.Code, + Name = x.Name, + }) + .ToListAsync(); } /****************************************************** help methods *********************************************************/ diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs deleted file mode 100644 index 124b041d..00000000 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Dlhis.Basic.Organization.Request; -using Dlhis.Basic.Organization.Services; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; - -namespace Dlhis.Basic.Organization.Controllers; - -/// -/// 人员face -/// -[Route("api/[controller]")] -[ApiController] -public class GainfoFacesController : ControllerBase -{ - private readonly IGainfoFaceService _gainfoFaceService; - - public GainfoFacesController(IGainfoFaceService gainfoFaceService) - { - _gainfoFaceService = gainfoFaceService; - } - - /// - /// 上传外部人员人脸照片 - /// - /// - [AllowAnonymous] - [HttpPost("external/face")] - public async Task UploadExternalFaceAsync(GainfoUploadFaceRequest request) - { - await _gainfoFaceService.UploadExternalFaceAsync(request); - } -} diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs index 84068abb..e5c23141 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs @@ -18,21 +18,12 @@ namespace Dlhis.Basic.MealUser.Controllers; public class GainfosController : ControllerBase { private readonly IGainfoService _gainfoService; + private readonly IGainfoFaceService _gainfoFaceService; - public GainfosController(IGainfoService gainfoService) + public GainfosController(IGainfoService gainfoService, IGainfoFaceService gainfoFaceService) { _gainfoService = gainfoService; - } - - /// - /// 档案表保存 - /// - /// - /// - [HttpPost("save")] - public async Task SaveAsync(List requests) - { - await _gainfoService.SaveAsync(requests); + _gainfoFaceService = gainfoFaceService; } /// @@ -80,6 +71,17 @@ public class GainfosController : ControllerBase await _gainfoService.UploadFaceAsync(request); } + /// + /// 上传外部人员人脸照片 + /// + /// + [AllowAnonymous] + [HttpPost("external/face")] + public async Task UploadExternalFaceAsync(GainfoUploadFaceRequest request) + { + await _gainfoFaceService.UploadExternalFaceAsync(request); + } + /// /// 批量上传人脸照片 /// @@ -161,5 +163,18 @@ public class GainfosController : ControllerBase { await _gainfoService.MigrationAsync(request); } + + + /// + /// 检查idno和名称是否匹配 + /// + /// + /// + [AllowAnonymous] + [HttpPost("check/idnoWithName")] + public async Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request) + { + await _gainfoService.CheckIdNoAndNameMatchAsync(request); + } } diff --git a/Src/Dlhis.Basic/Organization/Request/GainfoCheckIdNoAndNameRequest.cs b/Src/Dlhis.Basic/Organization/Request/GainfoCheckIdNoAndNameRequest.cs new file mode 100644 index 00000000..c1a1124f --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Request/GainfoCheckIdNoAndNameRequest.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.Basic.Organization.Request; + +public class GainfoCheckIdNoAndNameRequest +{ + /// + /// 身份证 + /// + [Required(ErrorMessage = "身份证不可为空")] + [StringLength(18, ErrorMessage = "身份证位数错误", MinimumLength = 18)] + public string IdNo { get; set; } + + /// + /// 姓名 + /// + [Required(ErrorMessage = "姓名不可为空")] + public string Name { get; set; } +} diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs index 6fca4a02..7624acfc 100644 --- a/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs @@ -11,14 +11,6 @@ public interface IGainfoService : IScopeDependency Task> GetPageByCodeAsync(string code); - Task SaveAsync(List requests); - - Task UpdateAsync(GainfoSaveRequest request); - - Task DimissionAsync(GainfoDimissionRequest request); - - Task OnboardingAsync(GainfoDimissionRequest request); - Task CurrentUserInfoAsync(); Task UploadFaceAsync(GainfoUploadFaceRequest request); @@ -37,4 +29,6 @@ public interface IGainfoService : IScopeDependency Task MigrationAsync(MigrationRequest request); + + Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request); } diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs index 778b96fd..f0f9f9cd 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs @@ -1,4 +1,5 @@ -using Dlhis.Basic.Device.Services; +using System.Text.RegularExpressions; +using Dlhis.Basic.Device.Services; using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Entity.Basic.Entity; @@ -13,7 +14,6 @@ using Kurisu.Core.DataAccess.Dto; using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; -using Mapster; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; @@ -23,10 +23,10 @@ public class GainfoService : IGainfoService { private readonly IGainfoStore _gainfoStore; private readonly IDbContext _dbContext; + private readonly IDataProtectionProvider _dataProtectionProvider; private readonly ICurrentUser _currentUser; private readonly IDevicePermissionService _devicePermissionService; private readonly RedisCache _redisCache; - private readonly IServiceProvider _serviceProvider; private readonly IConfiguration _configuration; private readonly ITenantApi _tenantApi; private readonly IHangfireApi _hangfireApi; @@ -34,10 +34,10 @@ public class GainfoService : IGainfoService public GainfoService(IGainfoStore gainfoStore, IDbContext dbContext, + IDataProtectionProvider dataProtectionProvider, ICurrentUser currentUser, IDevicePermissionService devicePermissionService, RedisCache redisCache, - IServiceProvider serviceProvider, IConfiguration configuration, ITenantApi tenantApi, IHangfireApi hangfireApi, @@ -45,10 +45,10 @@ public class GainfoService : IGainfoService { _gainfoStore = gainfoStore; _dbContext = dbContext; + _dataProtectionProvider = dataProtectionProvider; _currentUser = currentUser; _devicePermissionService = devicePermissionService; _redisCache = redisCache; - _serviceProvider = serviceProvider; _configuration = configuration; _tenantApi = tenantApi; _hangfireApi = hangfireApi; @@ -80,10 +80,8 @@ public class GainfoService : IGainfoService .WhereIF(request.DepartmentSelections.IsEmpty(), gainfo => gainfo.Factory == currentTenantId) .WhereIF(request.Search.IsPresent(), gainfo => gainfo.Name.Contains(request.Search) - || gainfo.Code.Contains(request.Search) - || gainfo.IdNo.Contains(request.Search) - || gainfo.Werks.Contains(request.Search) - ) + || gainfo.Code == request.Search + || gainfo.IdNo == request.Search) .Select() .ToPageListAsync(request); @@ -109,78 +107,6 @@ public class GainfoService : IGainfoService return page; } - /// - ///保存档案号 - /// - /// - /// - public async Task SaveAsync(List request) - { - //todo check - var entities = request.Adapt>(); - entities.ForEach(x => - { - if (x.No.IsEmpty()) - { - x.No = "F" + Guid.NewGuid().ToString(); - } - }); - - await _gainfoStore.InsertAsync(entities); - } - - - /// - ///修改档案号 - /// - /// - /// - public async Task UpdateAsync(GainfoSaveRequest request) - { - var gainfo = await _gainfoStore.Queryable(request.GainfoStatus).Where(x => x.Id == request.Id).FirstAsync(); - gainfo.ThrowIfNull("档案数据不存在,无法更新"); - - request.Adapt(gainfo); - await _gainfoStore.UpdateAsync(gainfo); - } - - /// - /// 正式转离职 - /// - /// - /// - public async Task DimissionAsync(GainfoDimissionRequest request) - { - var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) - .Where(x => x.No == request.UserNo) - .FirstAsync(); - - gainfo.ThrowIfNull("该档案不存在"); - - //添加到离职表 - await _gainfoStore.InsertAsync(gainfo, GainfoStatusEnumType.Leave); - //删除原数据 - await _gainfoStore.DeleteAsync(gainfo, GainfoStatusEnumType.Working); - } - - /// - /// 临时转正式 - /// - /// - /// - /// - public async Task OnboardingAsync(GainfoDimissionRequest request) - { - var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External) - .Where(x => x.No == request.UserNo) - .FirstAsync(); - - gainfo.ThrowIfNull($"该档案不存在"); - - //添加到正式表,不删除原数据,留档处理 - await _gainfoStore.InsertAsync(gainfo); - } - public async Task CurrentUserInfoAsync() { var code = _currentUser.GetUserClaim("jinko-code"); @@ -239,9 +165,7 @@ public class GainfoService : IGainfoService public async Task GetFaceAsync(string token) { - var timeLimitedDataProtector = _serviceProvider.GetService() - .CreateProtector("down:face") - .ToTimeLimitedDataProtector(); + var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); try { @@ -263,7 +187,6 @@ public class GainfoService : IGainfoService return new NotFoundResult(); } - await _redisCache.HashSetAsync("faces", userCode, face.Face); return new FileContentResult(Convert.FromBase64String(face.Face), "image/png"); } catch (Exception ex) @@ -373,9 +296,7 @@ public class GainfoService : IGainfoService face.ThrowIfNull("人脸照片尚未录入"); - var timeLimitedDataProtector = _serviceProvider.GetService() - .CreateProtector("down:face") - .ToTimeLimitedDataProtector(); + var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value; var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get(); @@ -404,6 +325,20 @@ public class GainfoService : IGainfoService return faceDictionary; } + + public async Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request) + { + var match = await _gainfoStore.Queryable(GainfoStatusEnumType.External).AnyAsync(x => x.IdNo == request.IdNo && x.Name == request.Name); + if (!match) + { + match = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).AnyAsync(x => x.IdNo == request.IdNo && x.Name == request.Name); + } + + match.ThrowIfFalse("验证失败!"); + + return request.IdNo; + } + /// /// 档案列表 /// diff --git a/Src/Dlhis.Basic/Packs/SqlSugarPack.cs b/Src/Dlhis.Basic/Packs/SqlSugarPack.cs index 9e6d5ca3..9df2950d 100644 --- a/Src/Dlhis.Basic/Packs/SqlSugarPack.cs +++ b/Src/Dlhis.Basic/Packs/SqlSugarPack.cs @@ -53,8 +53,8 @@ public class SqlSugarPack : BaseAppPack public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) { - var siGenerate = Configuration.GetSection("SqlSugarOptions").GetValue("Generate"); - if (siGenerate) + var isGenerate = Configuration.GetSection("SqlSugarOptions").GetValue("Generate"); + if (isGenerate) { using var scope = app.ApplicationServices.CreateScope(); var db = scope.ServiceProvider.GetService(); diff --git a/Src/Dlhis.Basic/appsettings.Development.json b/Src/Dlhis.Basic/appsettings.Development.json index e3e356f0..8af9df4f 100644 --- a/Src/Dlhis.Basic/appsettings.Development.json +++ b/Src/Dlhis.Basic/appsettings.Development.json @@ -5,7 +5,6 @@ "Microsoft.AspNetCore": "Warning" } }, - "EightThirtyPM": "20:30:00", "InternalRequest": { "CommonRequestUrl": "http://localhost:5001", "SysRequestUrl": "http://localhost:5003", diff --git a/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs index 26296b5a..6ae4192d 100644 --- a/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoEntity.cs @@ -62,7 +62,7 @@ public class GainfoEntity : SugarBaseEntity /// /// 身份证号 /// - [SugarColumn(ColumnDescription = "身份证号")] + [SugarColumn(ColumnDescription = "身份证号", UniqueGroupNameList = new[] { "idx_Gainfo_IdNo" })] public string IdNo { get; set; } /// @@ -211,22 +211,4 @@ public class GainfoExternalEntity : GainfoEntity /// [SugarColumn(ColumnDescription = "公司", IsNullable = false)] public string Company { get; set; } - - /// - /// 到达时间 - /// - [SugarColumn(ColumnDescription = "到达时间")] - public DateTime From { get; set; } - - /// - /// 离开时间 - /// - [SugarColumn(ColumnDescription = "离开时间")] - public DateTime To { get; set; } - - /// - /// 对接人No - /// - [SugarColumn(ColumnDescription = "对接人", IsNullable = false)] - public string JinkoNo { get; set; } } diff --git a/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs b/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs index 0d22dc00..c54f9911 100644 --- a/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs +++ b/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs @@ -55,6 +55,12 @@ public class DeviceGroupEntity : SugarBaseEntity, ITenantId, ISoftDeleted [SugarColumn(IsNullable = true)] public string Remark { get; set; } + /// + /// 可作为预约分组 + /// + [SugarColumn(ColumnDataType = "bit", DefaultValue = "0")] + public bool AsAppointment { get; set; } = false; + public string TenantId { get; set; } diff --git a/Src/Dlhis.Entity/Device/Entities/DeviceTaskEntity.cs b/Src/Dlhis.Entity/Device/Entities/DeviceTaskEntity.cs index d1c9ace1..56af07d6 100644 --- a/Src/Dlhis.Entity/Device/Entities/DeviceTaskEntity.cs +++ b/Src/Dlhis.Entity/Device/Entities/DeviceTaskEntity.cs @@ -15,7 +15,7 @@ public class DeviceTaskEntity : SugarBaseEntity, ITenantId, IVersion /// /// 任务类型 /// - [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] + [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), IndexGroupNameList = new[] { "idx_DeviceTask_Type" })] public DeviceTaskEnumType Type { get; set; } /// @@ -44,7 +44,7 @@ public class DeviceTaskEntity : SugarBaseEntity, ITenantId, IVersion /// /// 任务下发状态 /// - [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] + [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), IndexGroupNameList = new[] { "idx_DeviceTask_Status" })] public DeviceTaskStatusEnumType Status { get; set; } /// @@ -69,7 +69,7 @@ public class DeviceTaskEntity : SugarBaseEntity, ITenantId, IVersion /// 优先级 /// [SugarColumn(IsNullable = true, DefaultValue = "0")] - public int Priority { get; set; } = 0; + public int Priority { get; set; } = 0; public string TenantId { get; set; } diff --git a/Src/Dlhis.Entity/Dlhis.Entity.csproj b/Src/Dlhis.Entity/Dlhis.Entity.csproj index 31994a94..36c0cf47 100644 --- a/Src/Dlhis.Entity/Dlhis.Entity.csproj +++ b/Src/Dlhis.Entity/Dlhis.Entity.csproj @@ -6,10 +6,6 @@ disable - - - - diff --git a/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs new file mode 100644 index 00000000..3635b96b --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs @@ -0,0 +1,28 @@ +using Kurisu.Core.DataAccess.Entity; +using Kurisu.SqlSugar; +using SqlSugar; + +namespace Dlhis.Entity.Visitor.Entity; + +/// +/// 预约区域分配 +/// +[SugarTable(TableName = "AppointmentAreaAssignment", TableDescription = "预约区域分配")] +public class AppointmentAreaAssignmentEntity : SugarBaseEntity, ITenantId +{ + /// + /// 预约区域编码 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "预约区域编码")] + public string CustomCode { get; set; } + + /// + /// 分组code + /// + [SugarColumn(IsNullable = false, ColumnDescription = "分组code")] + public Guid GroupCode { get; set; } + //UniqueGroupNameList = new[] { "idx_aaa_cc_grpc_tid" } + + [SugarColumn()] + public string TenantId { get; set; } +} diff --git a/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaEntity.cs new file mode 100644 index 00000000..704969a0 --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaEntity.cs @@ -0,0 +1,54 @@ +using Dlhis.Entity.Visitor.Enums; +using Kurisu.Core.DataAccess.Entity; +using Kurisu.SqlSugar; +using Mapster; +using SqlSugar; +using SqlSugar.DbConvert; + +namespace Dlhis.Entity.Visitor.Entity; + +/// +/// 预约区域 +/// +[SugarTable(TableName = "AppointmentArea", TableDescription = "预约区域")] +public class AppointmentAreaEntity : SugarBaseEntity, ITenantId, ISoftDeleted +{ + /// + /// 区域类型 + /// + [AdaptIgnore(MemberSide.Destination)] + [SugarColumn(IsNullable = false, ColumnDescription = "区域类型", ColumnDataType = "varchar(50)", + SqlParameterDbType = typeof(EnumToStringConvert), + UniqueGroupNameList = new[] { "idx_ApponintmentArea_t_cc_tid" })] + public AppointmentAreaEnumType Type { get; set; } + + /// + /// 自定义编码 + /// + [AdaptIgnore(MemberSide.Destination)] + [SugarColumn(IsNullable = false, ColumnDescription = "自定义编码", + UniqueGroupNameList = new[] { "idx_ApponintmentArea_t_cc_tid" })] + public string CustomCode { get; set; } + + /// + /// 名称 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "名称")] + public string Name { get; set; } + + /// + /// 备注 + /// + [SugarColumn(IsNullable = true, ColumnDescription = "备注")] + public string Remark { get; set; } + + /// + /// 基地/租户 + /// + [SugarColumn(IsNullable = false, ColumnDescription = " 基地/租户", + UniqueGroupNameList = new[] { "idx_ApponintmentArea_t_cc_tid" })] + public string TenantId { get; set; } + + + public bool IsDeleted { get; set; } +} diff --git a/Src/Dlhis.Entity/Visitor/Entity/ApponintmentAreaEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/ApponintmentAreaEntity.cs new file mode 100644 index 00000000..9b006faf --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Entity/ApponintmentAreaEntity.cs @@ -0,0 +1,44 @@ +using Dlhis.Entity.Visitor.Enums; +using Kurisu.Core.DataAccess.Entity; +using Kurisu.SqlSugar; +using SqlSugar; +using SqlSugar.DbConvert; + +namespace Dlhis.Entity.Visitor.Entity; + +/// +/// 预约区域 +/// +[SugarTable(TableName = "ApponintmentArea", TableDescription = "预约区域")] +public class ApponintmentAreaEntity : SugarBaseEntity, ITenantId +{ + /// + /// 区域类型 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "区域类型", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] + public AppointmentAreaEnumType Type { get; set; } + + /// + /// 自定义编码 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "自定义编码", UniqueGroupNameList = new[] { "idx_aa_cc_tid" })] + public string CustomCode { get; set; } + + /// + /// 名称 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "名称")] + public string Name { get; set; } + + /// + /// 备注 + /// + [SugarColumn(IsNullable = true, ColumnDescription = "备注")] + public string Remark { get; set; } + + /// + /// 基地/租户 + /// + [SugarColumn(IsNullable = false, ColumnDescription = " 基地/租户", UniqueGroupNameList = new[] { "idx_aa_cc_tid" })] + public string TenantId { get; set; } +} diff --git a/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs new file mode 100644 index 00000000..48f6a32b --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentDetailEntity.cs @@ -0,0 +1,73 @@ +using Dlhis.Entity.Visitor.Enums; +using Kurisu.SqlSugar; +using SqlSugar; +using SqlSugar.DbConvert; + +namespace Dlhis.Entity.Visitor.Entity; + +/// +/// 预约明细 +/// +[SugarTable(TableName = "VisitorAppointmentDetail", TableDescription = "访客预约")] +public class VisitorAppointmentDetailEntity : SugarBaseEntity +{ + [SugarColumn(IsNullable = false, ColumnDescription = "父id")] + public long AppointmentId { get; set; } + + /// + /// 流水号 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "流水号")] + public string FlowId { get; set; } + + /// + /// 访客名称 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "访客名称")] + public string Name { get; set; } + + /// + /// 手机号 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "手机号")] + public string Phone { get; set; } + + /// + /// 是否外部人员 + /// + [SugarColumn(IsNullable = false, ColumnDataType = "bit")] + public bool IsExternal { get; set; } + + /// + /// 身份证 + /// + /// + /// 使用身份证字段作为申请人唯一标识 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "身份证")] + public string IdNo { get; set; } + + /// + /// 预计到达 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "预计到达")] + public DateTime Start { get; set; } + + /// + /// 预计离开 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "预计离开")] + public DateTime End { get; set; } + + /// + /// 状态 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "状态", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] + public AppointmentDetailEnumType Status { get; set; } + + /// + /// 备注 + /// + [SugarColumn(IsNullable = true, ColumnDescription = "备注")] + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentEntity.cs new file mode 100644 index 00000000..55cc53cb --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Entity/VisitorAppointmentEntity.cs @@ -0,0 +1,30 @@ +using Kurisu.SqlSugar; +using SqlSugar; + +namespace Dlhis.Entity.Visitor.Entity; + +[SugarTable(TableName = "VisitorAppointment", TableDescription = "访客预约")] +public class VisitorAppointmentEntity : SugarBaseEntity +{ + /// + /// 流水号 + /// + [SugarColumn(IsNullable = false, ColumnDescription = "流水号", UniqueGroupNameList = new[] { "idx_VisitorAppointment_FlowId" })] + public string FlowId { get; set; } + + public string Title { get; set; } + + public string Code { get; set; } + + public string Name { get; set; } + + public string Description { get; set; } + + public string DepartmentNo { get; set; } + + public string Company { get; set; } + + public DateTime ApplyTime { get; set; } + + public string AreaCustomCode { get; set; } +} diff --git a/Src/Dlhis.Entity/Visitor/Enums/AppointmentAreaEnumType.cs b/Src/Dlhis.Entity/Visitor/Enums/AppointmentAreaEnumType.cs new file mode 100644 index 00000000..70ebf494 --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Enums/AppointmentAreaEnumType.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Dlhis.Entity.Visitor.Enums; + +/// +/// 预约区域类型 +/// +[Description("预约区域类型")] +public enum AppointmentAreaEnumType +{ + /// + /// 门岗 + /// + [Description("门岗")] + Door = 1, + + /// + /// 车间 + /// + [Description("车间")] + Workshop = 2, +} diff --git a/Src/Dlhis.Entity/Visitor/Enums/AppointmentDetailEnumType.cs b/Src/Dlhis.Entity/Visitor/Enums/AppointmentDetailEnumType.cs new file mode 100644 index 00000000..dec16c8d --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Enums/AppointmentDetailEnumType.cs @@ -0,0 +1,35 @@ +using System.ComponentModel; + +namespace Dlhis.Entity.Visitor.Enums; + +/// +/// 访客预约明细状态 +/// +[Description("预约状态")] +public enum AppointmentDetailEnumType +{ + /// + /// 待来访 + /// + [Description("待来访")] + Wait = 0, + + /// + /// 取消 + /// + [Description("取消")] + Cancel = 5, + + /// + /// 到达 + /// + [Description("到达")] + Arrived = 10, + + + /// + /// 离开 + /// + [Description("离开")] + Leave = 99 +} diff --git a/Src/Dlhis.Entity/Visitor/Enums/ApponintmentAreaEnumType.cs b/Src/Dlhis.Entity/Visitor/Enums/ApponintmentAreaEnumType.cs new file mode 100644 index 00000000..f7972f2e --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Enums/ApponintmentAreaEnumType.cs @@ -0,0 +1,19 @@ +using System.ComponentModel; + +namespace Dlhis.Entity.Visitor.Enums; + +[Description("预约区域")] +public enum ApponintmentAreaEnumType +{ + /// + /// 门岗 + /// + [Description("门岗")] + Door = 1, + + /// + /// 车间 + /// + [Description("车间")] + Workshop = 2, +} diff --git a/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailEnumType.cs b/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailEnumType.cs new file mode 100644 index 00000000..fe0c852c --- /dev/null +++ b/Src/Dlhis.Entity/Visitor/Enums/VisitorAppointmentDetailEnumType.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; + +namespace Dlhis.Entity.Visitor.Enums; + +/// +/// 访客预约明细状态 +/// +[Description("访客预约状态")] +public enum VisitorAppointmentDetailEnumType +{ + /// + /// 到达 + /// + [Description("到达")] + Arrived = 1, + + /// + /// 离开 + /// + [Description("离开")] + Leave = 99 +} diff --git a/Src/Dlhis.Message/Controllers/AppointmentPushController.cs b/Src/Dlhis.Message/Controllers/AppointmentPushController.cs new file mode 100644 index 00000000..8d25db42 --- /dev/null +++ b/Src/Dlhis.Message/Controllers/AppointmentPushController.cs @@ -0,0 +1,26 @@ +using Dlhis.Message.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.SignalR; + +namespace Dlhis.Message.Controllers; + +/// +/// +/// +[Route("api/[controller]")] +[ApiController] +public class AppointmentPushController : ControllerBase +{ + private readonly IHubContext _hubContext; + + public AppointmentPushController(IHubContext hubContext) + { + _hubContext = hubContext; + } + + [HttpPost("push")] + public async Task PushAsync(Dictionary values) + { + await _hubContext.Clients.All.Raise(values); + } +} diff --git a/Src/Dlhis.Message/Dlhis.Message.csproj b/Src/Dlhis.Message/Dlhis.Message.csproj new file mode 100644 index 00000000..82051fc6 --- /dev/null +++ b/Src/Dlhis.Message/Dlhis.Message.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + enable + enable + Linux + ..\.. + + + + + + + + diff --git a/Src/Dlhis.Message/Dockerfile b/Src/Dlhis.Message/Dockerfile new file mode 100644 index 00000000..f23a7195 --- /dev/null +++ b/Src/Dlhis.Message/Dockerfile @@ -0,0 +1,23 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["Src/Dlhis.Message/Dlhis.Message.csproj", "Src/Dlhis.Message/"] +RUN dotnet restore "./Src/Dlhis.Message/./Dlhis.Message.csproj" +COPY . . +WORKDIR "/src/Src/Dlhis.Message" +RUN dotnet build "./Dlhis.Message.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./Dlhis.Message.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Dlhis.Message.dll"] \ No newline at end of file diff --git a/Src/Dlhis.Message/Packs/SignalRPack.cs b/Src/Dlhis.Message/Packs/SignalRPack.cs new file mode 100644 index 00000000..0c5d762d --- /dev/null +++ b/Src/Dlhis.Message/Packs/SignalRPack.cs @@ -0,0 +1,22 @@ +using Kurisu.AspNetCore.Startup; + +namespace Dlhis.Message.Packs; + +public class SignalRPack : BaseAppPack +{ + public override bool IsBeforeUseRouting => false; + + + public override void ConfigureServices(IServiceCollection services) + { + services.AddSignalR(); + } + + public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + app.UseEndpoints(endpoints => + { + endpoints.MapHub("/hub/appointment"); + }); + } +} diff --git a/Src/Dlhis.Message/Program.cs b/Src/Dlhis.Message/Program.cs new file mode 100644 index 00000000..b2292f00 --- /dev/null +++ b/Src/Dlhis.Message/Program.cs @@ -0,0 +1,20 @@ +using Kurisu.AspNetCore.Startup; +using Kurisu.Startup; +using Microsoft.IdentityModel.Logging; + +class Program +{ + static void Main(string[] args) + { + KurisuHost.Run(true, args); + } +} + +public class Startup : DefaultStartup +{ + public Startup(IConfiguration configuration) : base(configuration) + { + IdentityModelEventSource.ShowPII = true; + } +} + diff --git a/Src/Dlhis.Message/Properties/launchSettings.json b/Src/Dlhis.Message/Properties/launchSettings.json new file mode 100644 index 00000000..85b6d7fd --- /dev/null +++ b/Src/Dlhis.Message/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "profiles": { + "Dlhis.Message": { + "commandName": "Project", + "launchBrowser": false, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5050" + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json" +} \ No newline at end of file diff --git a/Src/Dlhis.Message/Services/IVisitorAppointmentService.cs b/Src/Dlhis.Message/Services/IVisitorAppointmentService.cs new file mode 100644 index 00000000..09489134 --- /dev/null +++ b/Src/Dlhis.Message/Services/IVisitorAppointmentService.cs @@ -0,0 +1,6 @@ +namespace Dlhis.Message.Services; + +public interface IVisitorAppointmentService +{ + Task Raise(Dictionary obj); +} diff --git a/Src/Dlhis.Message/TestBackgroundService.cs b/Src/Dlhis.Message/TestBackgroundService.cs new file mode 100644 index 00000000..f25ab20e --- /dev/null +++ b/Src/Dlhis.Message/TestBackgroundService.cs @@ -0,0 +1,26 @@ + +using Dlhis.Message.Services; +using Microsoft.AspNetCore.SignalR; + +namespace Dlhis.Message +{ + public class TestBackgroundService : BackgroundService, ISingletonDependency + { + private readonly IHubContext _hubContext; + + public TestBackgroundService(IHubContext hubContext) + { + _hubContext = hubContext; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + await _hubContext.Clients.All.Raise(new Dictionary { ["name"] = "ligy" }); + + await Task.Delay(1000 * 10); + } + } + } +} diff --git a/Src/Dlhis.Message/VisitorAppointmentHub.cs b/Src/Dlhis.Message/VisitorAppointmentHub.cs new file mode 100644 index 00000000..2b1405c5 --- /dev/null +++ b/Src/Dlhis.Message/VisitorAppointmentHub.cs @@ -0,0 +1,19 @@ +using Dlhis.Message.Services; +using Microsoft.AspNetCore.SignalR; + +namespace Dlhis.Message; + +public class VisitorAppointmentHub : Hub +{ + private readonly ILogger _logger; + + public VisitorAppointmentHub(ILogger logger) + { + _logger = logger; + } + + public override async Task OnConnectedAsync() + { + _logger.LogInformation("链接"); + } +} diff --git a/Src/Dlhis.Message/appsettings.Development.json b/Src/Dlhis.Message/appsettings.Development.json new file mode 100644 index 00000000..737d4399 --- /dev/null +++ b/Src/Dlhis.Message/appsettings.Development.json @@ -0,0 +1,25 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "SwaggerOptions": { + "Enable": true, + "Authority": "https://yikatong.isawesome.cn/oauth2", + "ClientId": "4fb184324eac4180", + "ClientSecret": "8ac8f235152f1524", + "Scopes": { + "openid": "openid", + "profile": "profile", + "yikatong": "yikatong" + } + }, + "IdentityServerOptions": { + "Authority": "https://yikatong.isawesome.cn/oauth2", + "RequireHttpsMetadata": true, + "Issuer": "identity.isawesome.cn", + "Audience": "" + } +} diff --git a/Src/Dlhis.Message/appsettings.json b/Src/Dlhis.Message/appsettings.json new file mode 100644 index 00000000..5629eb3b --- /dev/null +++ b/Src/Dlhis.Message/appsettings.json @@ -0,0 +1,72 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "SqlSugarOptions": { + "DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;", + "SlaveConnectionString": [], + "Timeout": 30, + "SlowSqlTime": 1, + "EnableSqlLog": false + }, + "SwaggerOptions": { + "Enable": true, + "Authority": "http://identity.oauth.svc.cluster.local", + "ClientId": "4fb184324eac4180", + "ClientSecret": "8ac8f235152f1524", + "Scopes": { + "openid": "openid", + "profile": "profile", + "yikatong": "yikatong" + } + }, + "IdentityServerOptions": { + "Authority": "http://identity.oauth.svc.cluster.local", + "RequireHttpsMetadata": false, + "Issuer": "identity.isawesome.cn", + "Audience": "", + "Pat": { + "Enable": false, + "Scheme": "token", + "ClientId": "reference", + "ClientSecret": "123456" + } + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "WriteTo": [ + { + "Name": "Async", + "Args": { + "configure": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "MySQL", + "Args": { + "connectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=logs;charset=utf8mb4;", + "tableName": "Logs", + "autoCreateSqlTable": true + } + } + ] + } + } + ] + } +} diff --git a/Src/Dlhis.ScheduledTask/BaseJob.cs b/Src/Dlhis.ScheduledTask/BaseJob.cs index 702f5530..c8dcaa44 100644 --- a/Src/Dlhis.ScheduledTask/BaseJob.cs +++ b/Src/Dlhis.ScheduledTask/BaseJob.cs @@ -30,7 +30,7 @@ public abstract class BaseJob : IJob sqlSugarOptionsService.IgnoreTenant = true; var name = this.GetType().GetCustomAttribute()!.Name; - Logger.LogInformation("[{name}]开始执行...", name); + Logger.LogDebug("[{name}]开始执行...", name); try { @@ -42,7 +42,7 @@ public abstract class BaseJob : IJob } finally { - Logger.LogInformation("[{name}]执行结束...", name); + Logger.LogDebug("[{name}]执行结束...", name); DbContext.Client.QueryFilter.Restore(); sqlSugarOptionsService.IgnoreTenant = false; } diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Dto/TaskDto.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Dto/TaskDto.cs new file mode 100644 index 00000000..b64dfcc0 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Dto/TaskDto.cs @@ -0,0 +1,25 @@ +using Dlhis.Entity.Device.Enums; + +namespace Dlhis.ScheduledTask.TaskAssignment.Dto; + +public class TaskDto +{ + public long TaskId { get; set; } + public long? UserId { get; set; } + + public DeviceTaskEnumType Type { get; set; } + public string DeviceUniqueNo { get; set; } + public string DeviceConnectionInfo { get; set; } + public string Brand { get; set; } + public string FuncStr { get; set; } + public string UserNo { get; set; } + public string UserCode { get; set; } + public string UserName { get; set; } + public string DepartmentNo { get; set; } + public string DepartmentName { get; set; } + public string CardNo { get; set; } + + public int Version { get; set; } + + public DeviceTaskStatusEnumType Status { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs index c3e4bb5d..fb628937 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs @@ -13,6 +13,7 @@ using Newtonsoft.Json.Linq; using Kurisu.Core.CustomClass; using Kurisu.AspNetCore; using Kurisu.AspNetCore.Utils; +using Dlhis.ScheduledTask.TaskAssignment.Dto; namespace Dlhis.ScheduledTask.TaskAssignment.Services.Implements; @@ -21,248 +22,158 @@ public class AssignmentService : IAssignmentService private readonly IDbContext _dbContext; private readonly IDataProtectionProvider _dataProtectionProvider; private readonly FaceUrlOptions _faceUrlOptions; - private readonly ILogger _logger; public AssignmentService(IDbContext dbContext, IDataProtectionProvider dataProtectionProvider, - IOptions options, - ILogger logger) + IOptions options) { _dbContext = dbContext; _dataProtectionProvider = dataProtectionProvider; _faceUrlOptions = options.Value; - _logger = logger; } public async Task> DeviceGetTasksAsync(DeviceTaskGetRequest request) { - ////获取心跳设备 todo - //var key = "heardbeat-devices"; - //var heartbeatDeviceNos = (await _redisCache.ListRangeAsync(key))?.Select(x => x.ToString()).ToList(); + var data = await GetDataAsync(request); + if (data.IsEmpty()) return new List(); - var data = await CommonHelper.RetryAsync(async () => - { - var page = await _dbContext.Queryable() - .LeftJoin((deviceTask, deivce) => deviceTask.DeviceUniqueNo == deivce.UniqueNo) - .LeftJoin((deviceTask, deivce, deivceTamplate) => deivceTamplate.Code == deivce.TemplateCode) - .LeftJoin((deviceTask, deivce, deivceTamplate, ga) => deviceTask.UserNo == ga.No) - .LeftJoin((deviceTask, deivce, deivceTamplate, ga, galeave) => deviceTask.UserNo == galeave.No) - .LeftJoin((deviceTask, deivce, deivceTamplate, ga, galeave, department) => department.No == ga.DepartmentNo) - .WhereIF(request.Brand.IsPresent(), (deviceTask, deivce, deivceTamplate) => deivceTamplate.Brand == request.Brand) - .WhereIF(request.DeviceUniqueNo.IsPresent(), (deviceTask, deivce) => deviceTask.DeviceUniqueNo == request.DeviceUniqueNo) - .WhereIF(request.Types.IsPresent(), deviceTask => request.Types.Contains(deviceTask.Type)) - .WhereIF(!request.IsProcess, deviceTask => deviceTask.Status == DeviceTaskStatusEnumType.Wait) - .WhereIF(request.IsProcess, deviceTask => deviceTask.Status == DeviceTaskStatusEnumType.Process - && SqlFunc.DateDiff(DateType.Minute, deviceTask.ModifiedTime, DateTime.Now) > 30) - //.Where(deviceTask => heartbeatDeviceNos.Contains(deviceTask.DeviceUniqueNo)) - .OrderBy(deviceTask => new { Priority = SqlFunc.Desc(deviceTask.Priority), deviceTask.CreateTime }) - .Select((deviceTask, deivce, deivceTamplate, ga, galeave, department) => new - { - UserId = SqlFunc.IsNull(SqlFunc.IsNull(deviceTask.UserId, ga.Id), galeave.IdentityUserId), - TaskId = deviceTask.Id, - deviceTask.Type, - deviceTask.DeviceUniqueNo, - DeviceConnectionInfo = deivce.ConnectionInfo, - deivceTamplate.Brand, - FuncStr = deivce.Funcs.ToString(), - deviceTask.UserNo, - UserCode = SqlFunc.IsNull(ga.Code, galeave.Code), - UserName = SqlFunc.IsNull(ga.Name, galeave.Name), - ga.DepartmentNo, - DepartmentName = department.Name, - ga.CardNo, - deviceTask.Version - }) - .ToPageListAsync(request); - - if (!page.Data.Any()) - { - return page.Data; - } - - var taskIdVs = page.Data.Select(x => new { x.TaskId, x.Version }).ToList(); - var where = LinqExpressionExtensions.False(); - taskIdVs.ForEach(p => - { - where = where.Or(x => x.Id == p.TaskId && x.Version == p.Version && x.Status != DeviceTaskStatusEnumType.Success); - }); - - var effecet = await _dbContext.Updateable() - .SetColumns(x => x.Version == x.Version + 1) - .SetColumns(x => x.Status == DeviceTaskStatusEnumType.Process) - .SetColumns(x => x.ModifiedTime == DateTime.Now) - .Where(where) - .ExecuteCommandAsync(); - - (taskIdVs.Count != effecet).ThrowIfTrue("获取任务失败"); - - return page.Data; - - }, 5); - - if (!data.Any()) - { - return new List(); - } - - Dictionary deviceUploadInfos = null; - if (data.Any(x => x.Type == DeviceTaskEnumType.UploadRecord)) - { - var deviceNos = data.Select(x => x.DeviceUniqueNo).Distinct(); - deviceUploadInfos = new Dictionary(deviceNos.Count()); - - var logInfos = await _dbContext.Queryable().Select(it => new - { - RowNumber = SqlFunc.RowNumber(SqlFunc.Desc(it.Id), it.DeviceUniqueNo), - it.DeviceUniqueNo, - it.RaiseDateTime - }) - .MergeTable() - .Where(it => it.RowNumber == 1) - .ToListAsync(); - - foreach (var item in deviceNos) - { - var logInfo = logInfos.FirstOrDefault(x => x.DeviceUniqueNo == item); - deviceUploadInfos.Add(item, logInfo?.RaiseDateTime); - } - } + var deviceUploadInfos = await GetDeviceUploadRecordInfosAsync(data); var timeLimitedDataProtector = _dataProtectionProvider .CreateProtector("down:face") .ToTimeLimitedDataProtector(); return data.GroupBy(x => new { x.Brand, x.DeviceUniqueNo, x.DeviceConnectionInfo, x.FuncStr }) - .Select(x => - { - var b = x.Key.Brand; - var d = x.Key.DeviceUniqueNo; - var dc = x.Key.DeviceConnectionInfo ?? "{}"; - var func = x.Key.FuncStr ?? "[]"; + .Select(x => + { + var b = x.Key.Brand; + var d = x.Key.DeviceUniqueNo; + var dc = x.Key.DeviceConnectionInfo ?? "{}"; + var func = x.Key.FuncStr ?? "[]"; - var jobj = new JObject - { - { "connectionInfo", JToken.Parse(dc) }, - { "function", JArray.Parse(func) } - }; + var jobj = new JObject + { + { "connectionInfo", JToken.Parse(dc) }, + { "function", JArray.Parse(func) } + }; - return new DeviceTaskToDeviceByDeviceResponse - { - Brand = b, - DeviceUniqueNo = d, - DeviceInfo = jobj, - Tasks = x.AsEnumerable().Select(item => - { - var key = $"face:{item.UserCode}"; - var token = item.Type == DeviceTaskEnumType.Delete - ? string.Empty - : timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(_faceUrlOptions.Limit)); + return new DeviceTaskToDeviceByDeviceResponse + { + Brand = b, + DeviceUniqueNo = d, + DeviceInfo = jobj, + Tasks = x.Select(item => + { + var key = $"face:{item.UserCode}"; + var token = item.Type == DeviceTaskEnumType.Delete + ? string.Empty + : timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(_faceUrlOptions.Limit)); - var dto = new TaskCombineDto - { - TaskId = item.TaskId, - Type = item.Type, - }; + var dto = new TaskCombineDto + { + TaskId = item.TaskId, + Type = item.Type, + }; - switch (dto.Type) - { - case DeviceTaskEnumType.Add: - case DeviceTaskEnumType.Delete: - case DeviceTaskEnumType.Update: - { - dto.Info = new UserToDeviceResponse - { - UserId = item.UserId.Value, - UserNo = item.UserNo, - UserCode = item.UserCode, - UserName = item.UserName, - DepartmentNo = item.DepartmentNo, - DepartmentName = item.DepartmentName, - CardNo = item.Type == DeviceTaskEnumType.Delete ? string.Empty : item.CardNo, - Face = item.Type == DeviceTaskEnumType.Delete ? string.Empty : _faceUrlOptions.Url + token,//下发才附带照片信息 - ValidDatePeriod = new DatePeriod - { - Start = DateOnly.FromDateTime(DateTime.Now.AddDays(-1)), - End = DateOnly.FromDateTime(DateTime.Now.AddYears(20)), - }, - TimePeriods = new List { 1 }, - Doors = new List { 1 }, - Schedule = 1 - }; - } - break; - case DeviceTaskEnumType.TimePeriodAdd: - case DeviceTaskEnumType.TimePeriodDelete: - { - dto.Info = new TimePeriodToDeviceResponse - { - Id = 1, - Name = "小白领", - Enable = true, - Sections = new List() - { - new() - { - DayOfWeek= DayOfWeek.Monday, - TimePeriods = new List() - { - new() - { - Start = TimeOnly.Parse("08:00:00"), - End = TimeOnly.Parse("17:30:00"), - }, - } - } - } - }; - } - break; - case DeviceTaskEnumType.ScheduleAdd: - case DeviceTaskEnumType.ScheduleDelete: - { - dto.Info = new ScheduleToDeviceResponse - { - Id = 1, - Enable = true, - Name = "计划的一部分", - Schedules = new List - { - new() - { - Name = "国庆节", - DateTimePeriod = new DateTimePeriod + switch (dto.Type) + { + case DeviceTaskEnumType.Add: + case DeviceTaskEnumType.Delete: + case DeviceTaskEnumType.Update: + { + dto.Info = new UserToDeviceResponse + { + UserId = item.UserId.HasValue ? item.UserId.Value : 0, + UserNo = item.UserNo, + UserCode = item.UserCode, + UserName = item.UserName, + DepartmentNo = item.DepartmentNo, + DepartmentName = item.DepartmentName, + CardNo = item.Type == DeviceTaskEnumType.Delete ? string.Empty : item.CardNo, + Face = item.Type == DeviceTaskEnumType.Delete ? string.Empty : _faceUrlOptions.Url + token,//下发才附带照片信息 + ValidDatePeriod = new DatePeriod + { + Start = DateOnly.FromDateTime(DateTime.Now.AddDays(-1)), + End = DateOnly.FromDateTime(DateTime.Now.AddYears(20)), + }, + TimePeriods = new List { 1 }, + Doors = new List { 1 }, + Schedule = 1 + }; + } + break; + case DeviceTaskEnumType.TimePeriodAdd: + case DeviceTaskEnumType.TimePeriodDelete: + { + dto.Info = new TimePeriodToDeviceResponse + { + Id = 1, + Name = "小白领", + Enable = true, + Sections = new List() + { + new() + { + DayOfWeek= DayOfWeek.Monday, + TimePeriods = new List() { - Start = new DateTime(2024,10,1), - End = new DateTime(2024,10,7) + new() + { + Start = TimeOnly.Parse("08:00:00"), + End = TimeOnly.Parse("17:30:00"), + }, } - } - } - }; - } - break; + } + } + }; + } + break; + case DeviceTaskEnumType.ScheduleAdd: + case DeviceTaskEnumType.ScheduleDelete: + { + dto.Info = new ScheduleToDeviceResponse + { + Id = 1, + Enable = true, + Name = "计划的一部分", + Schedules = new List + { + new() + { + Name = "国庆节", + DateTimePeriod = new DateTimePeriod + { + Start = new DateTime(2024,10,1), + End = new DateTime(2024,10,7) + } + } + } + }; + } + break; - case DeviceTaskEnumType.UploadRecord: - { - dto.Info = new UploadRecordToDeviceResponse - { - DateTimePeriod = new DateTimePeriod - { - Start = deviceUploadInfos[d] ?? DateTime.Now, - End = DateTime.Now.AddDays(1) - } - }; - } - break; - default: - break; - } + case DeviceTaskEnumType.UploadRecord: + { + dto.Info = new UploadRecordToDeviceResponse + { + DateTimePeriod = new DateTimePeriod + { + Start = deviceUploadInfos[d] ?? DateTime.Now, + End = DateTime.Now.AddDays(1) + } + }; + } + break; + default: + break; + } - return dto; + return dto; - }).ToList() - }; + }).ToList() + }; - }).ToList(); + }).ToList(); } /// @@ -314,4 +225,101 @@ public class AssignmentService : IAssignmentService await _dbContext.UpdateAsync(deviceTasks); } + + + //**************************************************** help method ************************************************** + + private async Task> GetDataAsync(DeviceTaskGetRequest request) + { + var data = await CommonHelper.RetryAsync(async () => + { + var page = await _dbContext.Queryable() + .LeftJoin((deviceTask, deivce) => deviceTask.DeviceUniqueNo == deivce.UniqueNo) + .LeftJoin((deviceTask, deivce, deivceTamplate) => deivceTamplate.Code == deivce.TemplateCode) + .LeftJoin((deviceTask, deivce, deivceTamplate, ga) => deviceTask.UserNo == ga.No) + .LeftJoin((deviceTask, deivce, deivceTamplate, ga, galeave) => deviceTask.UserNo == galeave.No) + .LeftJoin((deviceTask, deivce, deivceTamplate, ga, galeave, department) => department.No == ga.DepartmentNo) + .LeftJoin((deviceTask, deivce, deivceTamplate, ga, galeave, department, gainfoEx) => deviceTask.UserNo == gainfoEx.No) + .WhereIF(!request.IsProcess, deviceTask => deviceTask.Status == DeviceTaskStatusEnumType.Wait) + .WhereIF(request.IsProcess, deviceTask => deviceTask.Status == DeviceTaskStatusEnumType.Process + && SqlFunc.DateDiff(DateType.Minute, deviceTask.ModifiedTime, DateTime.Now) > 30) + .WhereIF(request.DeviceUniqueNo.IsPresent(), (deviceTask, deivce) => deviceTask.DeviceUniqueNo == request.DeviceUniqueNo) + .WhereIF(request.Types.IsPresent(), deviceTask => request.Types.Contains(deviceTask.Type)) + .WhereIF(request.Brand.IsPresent(), (deviceTask, deivce, deivceTamplate) => deivceTamplate.Brand == request.Brand) + .OrderBy(deviceTask => new { Priority = SqlFunc.Desc(deviceTask.Priority), deviceTask.CreateTime }) + .Select((deviceTask, deivce, deivceTamplate, ga, galeave, department, gainfoEx) => new TaskDto + { + UserId = SqlFunc.IsNull(SqlFunc.IsNull(deviceTask.UserId, ga.Id), galeave.IdentityUserId), + TaskId = deviceTask.Id, + Type = deviceTask.Type, + DeviceUniqueNo = deviceTask.DeviceUniqueNo, + DeviceConnectionInfo = deivce.ConnectionInfo, + Brand = deivceTamplate.Brand, + FuncStr = deivce.Funcs.ToString(), + UserNo = deviceTask.UserNo, + UserCode = SqlFunc.IsNull(SqlFunc.IsNull(ga.Code, galeave.Code), gainfoEx.Code), + UserName = SqlFunc.IsNull(SqlFunc.IsNull(ga.Name, galeave.Name), gainfoEx.Name), + DepartmentNo = ga.DepartmentNo, + DepartmentName = department.Name, + CardNo = ga.CardNo, + Version = deviceTask.Version, + Status = deviceTask.Status + }) + .ToPageListAsync(request); + + if (!page.Data.Any()) + { + return page.Data; + } + + //var taskIdVs = page.Data.Select(x => new { x.TaskId, x.Version, x.Status }).ToList(); + //var where = LinqExpressionExtensions.False(); + //taskIdVs.ForEach(p => + //{ + // where = where.Or(x => x.Id == p.TaskId && x.Version == p.Version && x.Status == p.Status); + //}); + + //var effecet = await _dbContext.Updateable() + // .SetColumns(x => x.Version == x.Version + 1) + // .SetColumns(x => x.Status == DeviceTaskStatusEnumType.Process) + // .SetColumns(x => x.ModifiedTime == DateTime.Now) + // .Where(where) + // .ExecuteCommandAsync(); + + //(taskIdVs.Count != effecet).ThrowIfTrue("获取任务失败"); + + return page.Data; + + }, 5); + + return data; + } + + private async Task> GetDeviceUploadRecordInfosAsync(List data) + { + if (data.Any(x => x.Type == DeviceTaskEnumType.UploadRecord)) + { + var deviceNos = data.Select(x => x.DeviceUniqueNo).Distinct(); + var result = new Dictionary(deviceNos.Count()); + + //日志数据最后一条 + var logInfos = await _dbContext.Queryable().Select(it => new + { + RowNumber = SqlFunc.RowNumber(SqlFunc.Desc(it.Id), it.DeviceUniqueNo), + it.DeviceUniqueNo, + it.RaiseDateTime + }) + .MergeTable() + .Where(it => it.RowNumber == 1) + .ToListAsync(); + + foreach (var item in deviceNos) + { + var logInfo = logInfos.FirstOrDefault(x => x.DeviceUniqueNo == item); + result.Add(item, logInfo?.RaiseDateTime); + } + } + + return new Dictionary(); + } } diff --git a/Src/Dlhis.Visitor/Appointment/Controllers/AppointmentsController.cs b/Src/Dlhis.Visitor/Appointment/Controllers/AppointmentsController.cs new file mode 100644 index 00000000..5923bd8c --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Controllers/AppointmentsController.cs @@ -0,0 +1,84 @@ +using System.ComponentModel.DataAnnotations; +using Dlhis.Visitor.Appointment.Request; +using Dlhis.Visitor.Appointment.Response; +using Dlhis.Visitor.Appointment.Services; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; +using Kurisu.Core.DataAccess.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Dlhis.Visitor.Appointment.Controllers; + +/// +/// ԤԼ +/// +[Authorize] +[ApiController] +[Route("api/[controller]")] +public class AppointmentsController : ControllerBase +{ + private readonly IAppointmentService _appointmentService; + + public AppointmentsController(IAppointmentService appointmentService) + { + _appointmentService = appointmentService; + } + + /// + /// ½ÓÊÜԤԼдÈë + /// + /// + /// + [AllowAnonymous] + [Transactional] + [IgnoreTenant] + [HttpPost("receive")] + public async Task ReceiveAsync(AppointmentReceiveRequest request) + { + await _appointmentService.ReceiveAsync(request); + } + + /// + /// ԤԼ·Öҳ + /// + /// + /// + [HttpGet("page")] + public async Task> GetPageAsync([FromQuery] AppointmentPageRequest request) + { + return await _appointmentService.GetPageAsync(request); + } + + /// + /// ȷÈϵ½´ï + /// + /// + /// + [HttpPost("confirm")] + public async Task ConfirmAsync(AppointmentConfirmRequest request) + { + await _appointmentService.ConfirmAsync(request); + } + + /// + /// ¸ù¾ÝÉí·Ý֤»ñȡµ±Ìì·ÿÍԤԼ + /// + /// + /// + [AllowAnonymous] + [HttpGet("today")] + public async Task GetTodayByIdNoAsync( + [FromQuery] + [StringLength(18, MinimumLength = 18, ErrorMessage = "Éí·Ý֤´íÎó")] + [Required(ErrorMessage = "Éí·Ý֤²»¿ÉΪ¿Õ")]string idNo) + { + return await _appointmentService.GetTodayByIdNoAsync(idNo); + } + + [AllowAnonymous] + [HttpGet("idno/page")] + public async Task> GetRecordPageByIdNoAsync([FromQuery] AppointmentIdNoPageRequest request) + { + return await _appointmentService.GetRecordPageByIdNoAsync(request); + } +} diff --git a/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs b/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs new file mode 100644 index 00000000..c7055988 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs @@ -0,0 +1,68 @@ +using Dlhis.Visitor.Appointment.Request; +using Dlhis.Visitor.Appointment.Response; +using Dlhis.Visitor.Appointment.Services; +using Kurisu.Core.DataAccess.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Dlhis.Visitor.Appointment.Controllers; + +/// +/// 预约区域 +/// +[Authorize] +[Route("api/[controller]")] +[ApiController] +public class ApponintmentAreasController : ControllerBase +{ + private readonly IApponintmentAreaService _apponintmentAreaService; + + public ApponintmentAreasController(IApponintmentAreaService apponintmentAreaService) + { + _apponintmentAreaService = apponintmentAreaService; + } + + /// + /// 预约区域 + /// + /// + /// + [HttpGet("page")] + public async Task> GetPageAsync([FromQuery] PageDto request) + { + return await _apponintmentAreaService.GetPageAsync(request); + } + + /// + /// 保存 + /// + /// + /// + [HttpPost("save")] + public async Task SaveAsync(AppointmentAreaSaveRequest request) + { + await _apponintmentAreaService.SaveAsync(request); + } + + + /// + /// 删除 + /// + /// + /// + [HttpDelete("{id}")] + public async Task DeleteAsync(long id) + { + await _apponintmentAreaService.DeleteAsync(id); + } + + /// + /// 分配设备组 + /// + /// + [HttpPost("assign")] + public async Task AssignAsync(AppointmentAreaAssignRequest request) + { + await _apponintmentAreaService.AssignAsync(request); + } +} diff --git a/Src/Dlhis.Visitor/Appointment/Dto/AppointmentReceiveItemDto.cs b/Src/Dlhis.Visitor/Appointment/Dto/AppointmentReceiveItemDto.cs new file mode 100644 index 00000000..57cf552c --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Dto/AppointmentReceiveItemDto.cs @@ -0,0 +1,31 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.Visitor.Appointment.Dto; + +public class AppointmentReceiveItemDto +{ + /// + /// 姓名 + /// + [Required(ErrorMessage = "姓名必填")] + public string Name { get; set; } + + /// + /// 手机号 + /// + [StringLength(11, MinimumLength = 11)] + [Required(ErrorMessage = "手机号必填")] + public string Phone { get; set; } + + /// + /// 身份证 + /// + [StringLength(18, MinimumLength = 18)] + [Required(ErrorMessage = "身份证必填")] + public string IdNo { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs new file mode 100644 index 00000000..7ef2b7e9 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.Visitor.Appointment.Request; + +public class AppointmentAreaAssignRequest +{ + /// + /// 预约区域编码 + /// + [Required] + public string CustomCode { get; set; } + + + /// + /// 分组 + /// + public List GroupCodes { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaSaveRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaSaveRequest.cs new file mode 100644 index 00000000..7a0ba649 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaSaveRequest.cs @@ -0,0 +1,35 @@ +using System.ComponentModel.DataAnnotations; +using Dlhis.Entity.Visitor.Enums; + +namespace Dlhis.Visitor.Appointment.Request; + +public class AppointmentAreaSaveRequest +{ + /// + /// 数据id + /// + public long? Id { get; set; } + + /// + /// 区域 AppointmentAreaEnumType + /// + [EnumDataType(typeof(AppointmentAreaEnumType))] + public AppointmentAreaEnumType Type { get; set; } + + /// + /// 预期编码 + /// + [Required] + public string CustomCode { get; set; } + + /// + /// 姓名 + /// + [Required] + public string Name { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentConfirmRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentConfirmRequest.cs new file mode 100644 index 00000000..240e79d2 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentConfirmRequest.cs @@ -0,0 +1,6 @@ +namespace Dlhis.Visitor.Appointment.Request; + +public class AppointmentConfirmRequest +{ + public long Id { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentIdNoPageRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentIdNoPageRequest.cs new file mode 100644 index 00000000..bca1f311 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentIdNoPageRequest.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Visitor.Appointment.Request; + +public class AppointmentIdNoPageRequest : PageDto +{ + /// + /// 身份证 + /// + [StringLength(18, MinimumLength = 18, ErrorMessage = "身份证错误")] + [Required(ErrorMessage = "身份证不可为空")] + public string IdNo { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentPageRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentPageRequest.cs new file mode 100644 index 00000000..88d7be1c --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentPageRequest.cs @@ -0,0 +1,9 @@ +using Kurisu.Core.CustomClass; +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Visitor.Appointment.Request; + +public class AppointmentPageRequest : PageDto +{ + public DateTimePeriod SearchDateTimePeriod { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentReceiveRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentReceiveRequest.cs new file mode 100644 index 00000000..3028e970 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentReceiveRequest.cs @@ -0,0 +1,83 @@ +using System.ComponentModel.DataAnnotations; +using Dlhis.Visitor.Appointment.Dto; + +namespace Dlhis.Visitor.Appointment.Request; + +public class AppointmentReceiveRequest : IValidatableObject +{ + /// + /// 流水号 + /// + [Required(ErrorMessage = "流水号必填")] + public string FlowId { get; set; } + + /// + /// 标题 + /// + [Required(ErrorMessage = "标题必填")] + public string Title { get; set; } + + /// + /// 对接人工号 + /// + [Required(ErrorMessage = "对接人工号必填")] + public string Code { get; set; } + + /// + /// 对接人姓名 + /// + [Required(ErrorMessage = "对接人姓名必填")] + public string Name { get; set; } + + /// + /// 申请时间 + /// + [Required(ErrorMessage = "申请时间必填")] + public DateTime ApplyTime { get; set; } + + /// + /// 预约区域 + /// + [Required(ErrorMessage = "申请预约区域必填")] + public string ApplyArea { get; set; } + + /// + /// 来源公司 + /// + [Required(ErrorMessage = "来源公司")] + public string Company { get; set; } + + /// + /// 来访时间 + /// + public DateTime Start { get; set; } + + /// + /// 离开时间 + /// + public DateTime End { get; set; } + + /// + /// 描述 + /// + public string Description { get; set; } + + /// + /// 厂区 + /// + public string Factory { get; set; } + + /// + /// 明细 + /// + [MinLength(1, ErrorMessage = "明细必填")] + public List Items { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + if (Start >= End) + { + yield return new ValidationResult("来访时间不能大于等于离开时间", new[] { nameof(Start), nameof(End) }); + } + } +} diff --git a/Src/Dlhis.Visitor/Appointment/Request/ApponintmentAreaSaveRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/ApponintmentAreaSaveRequest.cs new file mode 100644 index 00000000..40005e9d --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Request/ApponintmentAreaSaveRequest.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using Dlhis.Entity.Visitor.Enums; + +namespace Dlhis.Visitor.Appointment.Request +{ + public class ApponintmentAreaSaveRequest + { + public long? Id { get; set; } + + /// + /// + /// + [EnumDataType(typeof(AppointmentAreaEnumType))] + public AppointmentAreaEnumType Type { get; set; } + + public string CustomCode { get; set; } + } +} diff --git a/Src/Dlhis.Visitor/Appointment/Response/AppointmentDetailResponse.cs b/Src/Dlhis.Visitor/Appointment/Response/AppointmentDetailResponse.cs new file mode 100644 index 00000000..322e396b --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Response/AppointmentDetailResponse.cs @@ -0,0 +1,56 @@ +using Dlhis.Entity.Visitor.Enums; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Visitor.Appointment.Response; + +public class AppointmentDetailResponse +{ + public long Id { get; set; } + + public long AppointmentId { get; set; } + + /// + /// 流水号 + /// + public string FlowId { get; set; } + + /// + /// 访客名称 + /// + public string Name { get; set; } + + /// + /// 手机号 + /// + public string Phone { get; set; } + + /// + /// 身份证 + /// + public string IdNo { get; set; } + + /// + /// 预计到达 + /// + public DateTime Start { get; set; } + + /// + /// 预计离开 + /// + public DateTime End { get; set; } + + /// + /// 状态 + /// + public AppointmentDetailEnumType Status { get; set; } + + /// + /// 状态 + /// + public string StatusDesc => Status.GetDescription(); + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Response/AppointmentPageResponse.cs b/Src/Dlhis.Visitor/Appointment/Response/AppointmentPageResponse.cs new file mode 100644 index 00000000..8a0de429 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Response/AppointmentPageResponse.cs @@ -0,0 +1,22 @@ +namespace Dlhis.Visitor.Appointment.Response; + +public class AppointmentPageResponse +{ + public string FlowId { get; set; } + + public string Title { get; set; } + + public string Code { get; set; } + + public string Name { get; set; } + + public string Description { get; set; } + + public string DepartmentNo { get; set; } + + public string DepartmentName { get; set; } + + public string Company { get; set; } + + public DateTime ApplyTime { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Response/ApponintmentAreaPageResponse.cs b/Src/Dlhis.Visitor/Appointment/Response/ApponintmentAreaPageResponse.cs new file mode 100644 index 00000000..6197d54f --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Response/ApponintmentAreaPageResponse.cs @@ -0,0 +1,34 @@ +using Dlhis.Entity.Visitor.Enums; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Visitor.Appointment.Response; + +public class ApponintmentAreaPageResponse +{ + public long Id { get; set; } + + /// + /// 区域类型 + /// + public AppointmentAreaEnumType Type { get; set; } + + /// + /// 区域类型 + /// + public string TypeDesc => Type.GetDescription(); + + /// + /// 自定义编码 + /// + public string CustomCode { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Visitor/Appointment/Services/IAppointmentService.cs b/Src/Dlhis.Visitor/Appointment/Services/IAppointmentService.cs new file mode 100644 index 00000000..f020bfb9 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Services/IAppointmentService.cs @@ -0,0 +1,42 @@ +using Dlhis.Visitor.Appointment.Request; +using Dlhis.Visitor.Appointment.Response; +using Kurisu.Core.DataAccess.Dto; +using Microsoft.AspNetCore.Mvc; + +namespace Dlhis.Visitor.Appointment.Services; + +public interface IAppointmentService : IScopeDependency +{ + Task ReceiveAsync(AppointmentReceiveRequest request); + + /// + /// 预约分页 + /// + /// + /// + Task> GetPageAsync(AppointmentPageRequest request); + + /// + /// 查看明细 + /// + /// + /// + Task> GetAppointmentDetailsByIdAsync(long id); + + /// + /// 确认到达 + /// + /// + Task ConfirmAsync(AppointmentConfirmRequest request); + + + /// + /// 根据身份证获取最新访客预约 + /// + /// + /// + Task GetTodayByIdNoAsync(string idNo); + + + Task> GetRecordPageByIdNoAsync([FromQuery] AppointmentIdNoPageRequest request); +} diff --git a/Src/Dlhis.Visitor/Appointment/Services/IApponintmentAreaService.cs b/Src/Dlhis.Visitor/Appointment/Services/IApponintmentAreaService.cs new file mode 100644 index 00000000..71804a2d --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Services/IApponintmentAreaService.cs @@ -0,0 +1,17 @@ +using Dlhis.Visitor.Appointment.Request; +using Dlhis.Visitor.Appointment.Response; +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Visitor.Appointment.Services; + +public interface IApponintmentAreaService : IScopeDependency +{ + Task> GetPageAsync(PageDto request); + + Task SaveAsync(AppointmentAreaSaveRequest request); + + Task DeleteAsync(long id); + + + Task AssignAsync(AppointmentAreaAssignRequest request); +} \ No newline at end of file diff --git a/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs b/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs new file mode 100644 index 00000000..c1a65242 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs @@ -0,0 +1,189 @@ +using Dlhis.Basic.Api; +using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Device.Entities; +using Dlhis.Entity.Device.Enums; +using Dlhis.Entity.Visitor.Entity; +using Dlhis.Entity.Visitor.Enums; +using Dlhis.Visitor.Appointment.Request; +using Dlhis.Visitor.Appointment.Response; +using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.DataAccess.Dto; +using Kurisu.SqlSugar.Extensions; +using Kurisu.SqlSugar.Services; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; + +namespace Dlhis.Visitor.Appointment.Services.Implements; + +public class AppointmentService : IAppointmentService +{ + private readonly IDbContext _dbContext; + private readonly IDeviceGroupApi _deviceGroupApi; + + public AppointmentService(IDbContext dbContext, IDeviceGroupApi deviceGroupApi) + { + _dbContext = dbContext; + _deviceGroupApi = deviceGroupApi; + } + + public async Task ReceiveAsync(AppointmentReceiveRequest request) + { + var exists = await _dbContext.Queryable().Where(x => x.FlowId == request.FlowId).AnyAsync(); + exists.ThrowIfTrue("已经存在申请"); + + var area = await _dbContext.Queryable() + .Where(x => x.Name == request.ApplyArea) + .Where(x => x.TenantId == request.Factory) + .FirstAsync(); + area.ThrowIfNull("预约区域不存在"); + + var where = LinqExpressionExtensions.False(); + request.Items.ForEach(item => + { + where = where.Or(x => !(x.End < request.Start || x.Start > request.End)).And(x => x.IdNo == item.IdNo); + }); + + var existsDetails = await _dbContext.Queryable() + .Where(where) + .Where(x => x.Status == AppointmentDetailEnumType.Wait || x.Status == AppointmentDetailEnumType.Arrived) + .ToListAsync(); + + existsDetails.ThrowIfExists($"{existsDetails.Select(x => x.Name).Join(",")}存在预约时间冲突,请检查"); + + var id = await _dbContext.InsertReturnIdentityAsync(new VisitorAppointmentEntity + { + FlowId = request.FlowId, + Name = request.Name, + Code = request.Code, + Description = request.Description, + Title = request.Title, + Company = request.Company, + ApplyTime = request.ApplyTime, + AreaCustomCode = area.CustomCode, + }); + + foreach (var item in request.Items) + { + var isExternal = !await _dbContext.Queryable().Where(x => x.IdNo == item.IdNo).AnyAsync(); + if (isExternal) + { + var gainfoExternal = await _dbContext.Queryable().Where(x => x.IdNo == item.IdNo).FirstAsync(); + if (gainfoExternal == null) + { + gainfoExternal = new GainfoExternalEntity + { + No = Guid.NewGuid().ToString(), + Code = item.IdNo, + IdNo = item.IdNo, + Name = item.Name, + Company = request.Company, + Phone = item.Phone + }; + await _dbContext.InsertAsync(gainfoExternal); + } + else + { + gainfoExternal.Phone = item.Phone; + gainfoExternal.Company = request.Company; + + await _dbContext.UpdateAsync(gainfoExternal); + } + } + + var detail = new VisitorAppointmentDetailEntity + { + AppointmentId = id, + FlowId = request.FlowId, + Start = request.Start, + End = request.End, + IdNo = item.IdNo, + Name = item.Name, + Phone = item.Phone, + Remark = item.Remark, + Status = AppointmentDetailEnumType.Wait, + IsExternal = isExternal, + }; + + await _dbContext.InsertAsync(detail); + } + } + + public async Task> GetPageAsync(AppointmentPageRequest request) + { + return await _dbContext.Queryable() + .WhereIF(request.SearchDateTimePeriod?.Start.HasValue == true && request.SearchDateTimePeriod?.End.HasValue == true, + x => x.ApplyTime >= request.SearchDateTimePeriod.Start && x.ApplyTime <= request.SearchDateTimePeriod.End) + .WhereIF(request.Search.IsPresent(), x => x.Code == request.Search || x.Name == request.Search) + .Select() + .ToPageListAsync(request); + } + + public async Task> GetAppointmentDetailsByIdAsync(long id) + { + return await _dbContext.Queryable() + .Where(x => x.AppointmentId == id) + .Select() + .ToListAsync(); + } + + public async Task ConfirmAsync(AppointmentConfirmRequest request) + { + var detail = await _dbContext.Queryable().Where(x => x.Id == request.Id).SingleAsync(); + detail.ThrowIfNull("预约信息不存在"); + + //todo生成下发任务 + var mst = await _dbContext.Queryable().Where(x => x.Id == detail.AppointmentId).FirstAsync(); + var deviceGroup = await _dbContext.Queryable() + .Where(x => x.CustomCode == mst.AreaCustomCode) + .Select(x => x.GroupCode) + .FirstAsync(); + + var deviceCodesResult = await _deviceGroupApi.GetDevicesByCodeAsync(deviceGroup); + var deviceCodes = deviceCodesResult.Data; + + var userNo = detail.IsExternal + ? await _dbContext.Queryable().Where(x => x.IdNo == detail.IdNo).Select(x => x.No).FirstAsync() + : await _dbContext.Queryable().Where(x => x.IdNo == detail.IdNo).Select(x => x.No).FirstAsync(); + + await _dbContext.InsertAsync(deviceCodes.Select(x => new DeviceTaskEntity + { + CancellationId = 0, + DeviceType = DeviceTypeEnumType.Door, + DeviceUniqueNo = x.UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + UserNo = userNo, + Type = DeviceTaskEnumType.Add, + Priority = 100, + Version = 0, + }).ToList()); + + detail.Status = AppointmentDetailEnumType.Arrived; + await _dbContext.UpdateAsync(detail); + } + + + //********************************************************** 用户操作 ******************************************************************* + + public async Task GetTodayByIdNoAsync(string idNo) + { + var detail = await _dbContext.Queryable() + .Where(x => x.IdNo == idNo) + .Where(x => SqlFunc.DateIsSame(x.Start, DateTime.Today, DateType.Day)) + .OrderBy(x => x.Start) + .Select() + .FirstAsync(); + + return detail; + } + + public async Task> GetRecordPageByIdNoAsync([FromQuery] AppointmentIdNoPageRequest request) + { + var page = await _dbContext.Queryable() + .Where(x => x.IdNo == request.IdNo) + .OrderBy(x => x.Start) + .Select() + .ToPageListAsync(request); + + return page; + } +} diff --git a/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs b/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs new file mode 100644 index 00000000..64e6d6e5 --- /dev/null +++ b/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs @@ -0,0 +1,93 @@ +using Dlhis.Entity.Visitor.Entity; +using Dlhis.Visitor.Appointment.Request; +using Dlhis.Visitor.Appointment.Response; +using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.DataAccess.Dto; +using Kurisu.SqlSugar.Extensions; +using Kurisu.SqlSugar.Services; +using Mapster; + +namespace Dlhis.Visitor.Appointment.Services.Implements; + +public class ApponintmentAreaService : IApponintmentAreaService +{ + private readonly IDbContext _dbContext; + + public ApponintmentAreaService(IDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> GetPageAsync(PageDto request) + { + return await _dbContext.Queryable() + .Select() + .ToPageListAsync(request); + } + + + public async Task SaveAsync(AppointmentAreaSaveRequest request) + { + await CheckCustomCodeDuplicateAsync(request); + + if (!request.Id.HasValue) + { + var entity = request.Adapt(); + entity.Type = request.Type; + entity.CustomCode = request.CustomCode; + + await _dbContext.InsertAsync(entity); + } + else + { + var entity = await _dbContext.Queryable().Where(x => x.Id == request.Id).SingleAsync(); + entity.ThrowIfNull("预约区域不存在"); + + request.Adapt(entity); + + await _dbContext.UpdateAsync(entity); + } + } + + + public async Task DeleteAsync(long id) + { + var entity = await _dbContext.Queryable().Where(x => x.Id == id).SingleAsync(); + await _dbContext.DeleteAsync(entity); + } + + + public async Task AssignAsync(AppointmentAreaAssignRequest request) + { + await _dbContext.Client.Deleteable() + .Where(x => x.CustomCode == request.CustomCode) + .ExecuteCommandAsync(); + + var data = request.GroupCodes.Select(x => new AppointmentAreaAssignmentEntity + { + CustomCode = request.CustomCode, + GroupCode = x, + }) + .ToList(); + + await _dbContext.InsertAsync(data); + } + + + //********************************************************* help methods *************************************************************** + + /// + /// 检查编码重复 + /// + /// + /// + private async Task CheckCustomCodeDuplicateAsync(AppointmentAreaSaveRequest request) + { + var exists = await _dbContext.Queryable() + .Where(x => x.CustomCode == request.CustomCode) + .WhereIF(request.Id.HasValue, x => x.Id == request.Id) + .AnyAsync(); + + exists.ThrowIfTrue("重复区域编码,请检查"); + } +} diff --git a/Src/Dlhis.Visitor/Dlhis.Visitor.csproj b/Src/Dlhis.Visitor/Dlhis.Visitor.csproj new file mode 100644 index 00000000..1c1ea281 --- /dev/null +++ b/Src/Dlhis.Visitor/Dlhis.Visitor.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + disable + enable + True + + + + + + + + + + + + + + + + diff --git a/Src/Dlhis.Visitor/Packs/SqlSugarPack.cs b/Src/Dlhis.Visitor/Packs/SqlSugarPack.cs new file mode 100644 index 00000000..fc4bf67f --- /dev/null +++ b/Src/Dlhis.Visitor/Packs/SqlSugarPack.cs @@ -0,0 +1,36 @@ +using Kurisu.AspNetCore.Startup; +using Kurisu.SqlSugar.Extensions; +using SqlSugar; + +namespace Dlhis.Visitor.Packs; + +public class SqlSugarPack : BaseAppPack +{ + public override bool IsBeforeUseRouting { get; } + + public override void ConfigureServices(IServiceCollection services) + { + services.AddSqlSugar(sp => + { + var configuration = sp.GetService(); + + return new List + { + new() + { + ConfigId = "face", + + ConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value, + DbType = DbType.MySqlConnector, + InitKeyType = InitKeyType.Attribute, + IsAutoCloseConnection = true, + + MoreSettings = new ConnMoreSettings + { + DisableNvarchar = true, + } + } + }; + }); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Visitor/Program.cs b/Src/Dlhis.Visitor/Program.cs new file mode 100644 index 00000000..db27a2eb --- /dev/null +++ b/Src/Dlhis.Visitor/Program.cs @@ -0,0 +1,21 @@ +using Kurisu.AspNetCore.Startup; +using Kurisu.Startup; +using Microsoft.IdentityModel.Logging; + +namespace Dlhis.Visitor; + +class Program +{ + static void Main(string[] args) + { + KurisuHost.Run(args); + } +} + +public class Startup : DefaultStartup +{ + public Startup(IConfiguration configuration) : base(configuration) + { + IdentityModelEventSource.ShowPII = true; + } +} \ No newline at end of file diff --git a/Src/Dlhis.Visitor/Properties/launchSettings.json b/Src/Dlhis.Visitor/Properties/launchSettings.json new file mode 100644 index 00000000..bdb16e59 --- /dev/null +++ b/Src/Dlhis.Visitor/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "Dlhis.Visitor": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "launchUrl": "weatherforecast", + "applicationUrl": "http://localhost:5021", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Src/Dlhis.Visitor/appsettings.Development.json b/Src/Dlhis.Visitor/appsettings.Development.json new file mode 100644 index 00000000..7bacdb83 --- /dev/null +++ b/Src/Dlhis.Visitor/appsettings.Development.json @@ -0,0 +1,35 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "InternalRequest": { + "BasicRequestUrl": "http://localhost:5002" + }, + "SwaggerOptions": { + "Enable": true, + "Authority": "https://yikatong.isawesome.cn/oauth2", + "ClientId": "4fb184324eac4180", + "ClientSecret": "8ac8f235152f1524", + "Scopes": { + "openid": "openid", + "profile": "profile", + "yikatong": "yikatong" + } + }, + "IdentityServerOptions": { + "Authority": "https://yikatong.isawesome.cn/oauth2", + "RequireHttpsMetadata": true, + "Issuer": "identity.isawesome.cn", + "Audience": "" + }, + "SqlSugarOptions": { + "DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;", + "SlaveConnectionString": [], + "Timeout": 30, + "SlowSqlTime": 1, + "EnableSqlLog": true + } +} diff --git a/Src/Dlhis.Visitor/appsettings.json b/Src/Dlhis.Visitor/appsettings.json new file mode 100644 index 00000000..45833522 --- /dev/null +++ b/Src/Dlhis.Visitor/appsettings.json @@ -0,0 +1,75 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "InternalRequest": { + "BasicRequestUrl": "http://basic" + }, + "AllowedHosts": "*", + "SqlSugarOptions": { + "DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;", + "SlaveConnectionString": [], + "Timeout": 30, + "SlowSqlTime": 1, + "EnableSqlLog": false + }, + "SwaggerOptions": { + "Enable": true, + "Authority": "http://identity.oauth.svc.cluster.local", + "ClientId": "4fb184324eac4180", + "ClientSecret": "8ac8f235152f1524", + "Scopes": { + "openid": "openid", + "profile": "profile", + "yikatong": "yikatong" + } + }, + "IdentityServerOptions": { + "Authority": "http://identity.oauth.svc.cluster.local", + "RequireHttpsMetadata": false, + "Issuer": "identity.isawesome.cn", + "Audience": "", + "Pat": { + "Enable": false, + "Scheme": "token", + "ClientId": "reference", + "ClientSecret": "123456" + } + }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "System": "Warning", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "WriteTo": [ + { + "Name": "Async", + "Args": { + "configure": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "MySQL", + "Args": { + "connectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=logs;charset=utf8mb4;", + "tableName": "Logs", + "autoCreateSqlTable": true + } + } + ] + } + } + ] + } +} From 0d137dd7b5e632eeac714e6ab3f24cbd405ea66b Mon Sep 17 00:00:00 2001 From: liguoyang Date: Wed, 17 Apr 2024 15:41:35 +0800 Subject: [PATCH 05/13] add dockerfile --- Src/Dlhis.Visitor/Dlhis.Visitor.csproj | 3 +++ Src/Dlhis.Visitor/Dockerfile | 25 +++++++++++++++++++ .../Properties/launchSettings.json | 23 +++++++++++------ 3 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 Src/Dlhis.Visitor/Dockerfile diff --git a/Src/Dlhis.Visitor/Dlhis.Visitor.csproj b/Src/Dlhis.Visitor/Dlhis.Visitor.csproj index 1c1ea281..3e4a2742 100644 --- a/Src/Dlhis.Visitor/Dlhis.Visitor.csproj +++ b/Src/Dlhis.Visitor/Dlhis.Visitor.csproj @@ -5,6 +5,8 @@ disable enable True + Linux + ..\.. @@ -13,6 +15,7 @@ + diff --git a/Src/Dlhis.Visitor/Dockerfile b/Src/Dlhis.Visitor/Dockerfile new file mode 100644 index 00000000..104cb4f1 --- /dev/null +++ b/Src/Dlhis.Visitor/Dockerfile @@ -0,0 +1,25 @@ +#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:6.0 AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["Src/Dlhis.Visitor/Dlhis.Visitor.csproj", "Src/Dlhis.Visitor/"] +COPY ["Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj", "Src/Dlhis.Basic.Api/"] +COPY ["Src/Dlhis.Entity/Dlhis.Entity.csproj", "Src/Dlhis.Entity/"] +RUN dotnet restore "./Src/Dlhis.Visitor/./Dlhis.Visitor.csproj" +COPY . . +WORKDIR "/src/Src/Dlhis.Visitor" +RUN dotnet build "./Dlhis.Visitor.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./Dlhis.Visitor.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Dlhis.Visitor.dll"] \ No newline at end of file diff --git a/Src/Dlhis.Visitor/Properties/launchSettings.json b/Src/Dlhis.Visitor/Properties/launchSettings.json index bdb16e59..8499ad17 100644 --- a/Src/Dlhis.Visitor/Properties/launchSettings.json +++ b/Src/Dlhis.Visitor/Properties/launchSettings.json @@ -1,15 +1,22 @@ -{ - "$schema": "https://json.schemastore.org/launchsettings.json", +{ "profiles": { "Dlhis.Visitor": { "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5021", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5021" + }, + "Docker": { + "commandName": "Docker", + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/weatherforecast", + "environmentVariables": { + "ASPNETCORE_URLS": "http://+:80" + }, + "publishAllPorts": true } - } -} + }, + "$schema": "https://json.schemastore.org/launchsettings.json" +} \ No newline at end of file From 4770733b261254111975380277a041f75fd14760 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Wed, 17 Apr 2024 15:49:25 +0800 Subject: [PATCH 06/13] =?UTF-8?q?feat=20=E6=96=B0=E5=A2=9E=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Src/Gateway/appsettings.json | 4 +++- Src/Gateway/ocelot.json | 30 ++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Src/Gateway/appsettings.json b/Src/Gateway/appsettings.json index 68b1359a..508d6f2a 100644 --- a/Src/Gateway/appsettings.json +++ b/Src/Gateway/appsettings.json @@ -12,6 +12,8 @@ "Canteen", "Scheduled", "User", - "Sys" + "Sys", + "Visitor", + "Message" ] } diff --git a/Src/Gateway/ocelot.json b/Src/Gateway/ocelot.json index 52cdcdf4..26b30a73 100644 --- a/Src/Gateway/ocelot.json +++ b/Src/Gateway/ocelot.json @@ -35,10 +35,6 @@ }, { "UpstreamPathTemplate": "/api/user/{url}", - "UpstreamHttpMethod": [ - "Get", - "Post" - ], "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ @@ -50,10 +46,6 @@ }, { "UpstreamPathTemplate": "/api/basic/{url}", - "UpstreamHttpMethod": [ - "Get", - "Post" - ], "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ @@ -85,6 +77,28 @@ } ] }, + { + "UpstreamPathTemplate": "/api/visitor/{url}", + "DownstreamPathTemplate": "/api/{url}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "192.168.199.30", + "Port": 31008 + } + ] + }, + { + "UpstreamPathTemplate": "/api/message/{url}", + "DownstreamPathTemplate": "/api/{url}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "192.168.199.30", + "Port": 31009 + } + ] + }, { "UpstreamPathTemplate": "/{url}/swagger/v1/swagger.json", "DownstreamPathTemplate": "/{url}/swagger/v1/swagger.json", From b5a817af182f44f2a6bd6c6e7ee3d6bbefe6f13b Mon Sep 17 00:00:00 2001 From: liguoyang Date: Wed, 17 Apr 2024 16:42:05 +0800 Subject: [PATCH 07/13] =?UTF-8?q?fix=20idno=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/GainfosController.cs | 4 +-- .../Services/Implements/GainfoService.cs | 6 ++-- .../Services/Implements/AppointmentService.cs | 29 +++++++++++++++++-- Src/Dlhis.Visitor/appsettings.json | 4 +++ 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs index e5c23141..ed23f0ae 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs @@ -172,9 +172,9 @@ public class GainfosController : ControllerBase /// [AllowAnonymous] [HttpPost("check/idnoWithName")] - public async Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request) + public async Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request) { - await _gainfoService.CheckIdNoAndNameMatchAsync(request); + return await _gainfoService.CheckIdNoAndNameMatchAsync(request); } } diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs index f0f9f9cd..ee5a9bba 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs @@ -1,5 +1,4 @@ -using System.Text.RegularExpressions; -using Dlhis.Basic.Device.Services; +using Dlhis.Basic.Device.Services; using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Entity.Basic.Entity; @@ -336,7 +335,8 @@ public class GainfoService : IGainfoService match.ThrowIfFalse("验证失败!"); - return request.IdNo; + var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno"); + return protector.Protect(request.IdNo); } /// diff --git a/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs b/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs index c1a65242..2e4a405b 100644 --- a/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs +++ b/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs @@ -7,9 +7,11 @@ using Dlhis.Entity.Visitor.Enums; using Dlhis.Visitor.Appointment.Request; using Dlhis.Visitor.Appointment.Response; using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.CustomClass; using Kurisu.Core.DataAccess.Dto; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; +using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; using SqlSugar; @@ -19,11 +21,13 @@ public class AppointmentService : IAppointmentService { private readonly IDbContext _dbContext; private readonly IDeviceGroupApi _deviceGroupApi; + private readonly IDataProtectionProvider _dataProtectionProvider; - public AppointmentService(IDbContext dbContext, IDeviceGroupApi deviceGroupApi) + public AppointmentService(IDbContext dbContext, IDeviceGroupApi deviceGroupApi, IDataProtectionProvider dataProtectionProvider) { _dbContext = dbContext; _deviceGroupApi = deviceGroupApi; + _dataProtectionProvider = dataProtectionProvider; } public async Task ReceiveAsync(AppointmentReceiveRequest request) @@ -131,7 +135,6 @@ public class AppointmentService : IAppointmentService var detail = await _dbContext.Queryable().Where(x => x.Id == request.Id).SingleAsync(); detail.ThrowIfNull("预约信息不存在"); - //todo生成下发任务 var mst = await _dbContext.Queryable().Where(x => x.Id == detail.AppointmentId).FirstAsync(); var deviceGroup = await _dbContext.Queryable() .Where(x => x.CustomCode == mst.AreaCustomCode) @@ -141,7 +144,7 @@ public class AppointmentService : IAppointmentService var deviceCodesResult = await _deviceGroupApi.GetDevicesByCodeAsync(deviceGroup); var deviceCodes = deviceCodesResult.Data; - var userNo = detail.IsExternal + var userNo = detail.IsExternal ? await _dbContext.Queryable().Where(x => x.IdNo == detail.IdNo).Select(x => x.No).FirstAsync() : await _dbContext.Queryable().Where(x => x.IdNo == detail.IdNo).Select(x => x.No).FirstAsync(); @@ -166,6 +169,16 @@ public class AppointmentService : IAppointmentService public async Task GetTodayByIdNoAsync(string idNo) { + var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno"); + try + { + idNo = protector.Unprotect(idNo); + } + catch (Exception) + { + throw new UserFriendlyException("凭证有误"); + } + var detail = await _dbContext.Queryable() .Where(x => x.IdNo == idNo) .Where(x => SqlFunc.DateIsSame(x.Start, DateTime.Today, DateType.Day)) @@ -178,6 +191,16 @@ public class AppointmentService : IAppointmentService public async Task> GetRecordPageByIdNoAsync([FromQuery] AppointmentIdNoPageRequest request) { + var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno"); + try + { + request.IdNo = protector.Unprotect(request.IdNo); + } + catch (Exception) + { + throw new UserFriendlyException("凭证有误"); + } + var page = await _dbContext.Queryable() .Where(x => x.IdNo == request.IdNo) .OrderBy(x => x.Start) diff --git a/Src/Dlhis.Visitor/appsettings.json b/Src/Dlhis.Visitor/appsettings.json index 45833522..4946a1a3 100644 --- a/Src/Dlhis.Visitor/appsettings.json +++ b/Src/Dlhis.Visitor/appsettings.json @@ -16,6 +16,10 @@ "SlowSqlTime": 1, "EnableSqlLog": false }, + "DataProtectionOptions": { + "Enable": true, + "AppName": "yiliantong" + }, "SwaggerOptions": { "Enable": true, "Authority": "http://identity.oauth.svc.cluster.local", From 708d28c8497aa5f089c82adde6390c0870530677 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Wed, 17 Apr 2024 18:14:34 +0800 Subject: [PATCH 08/13] =?UTF-8?q?fix=20=E4=BA=BA=E8=84=B8=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/GainfosController.cs | 22 +- .../Services/IGainfoFaceService.cs | 13 + .../Organization/Services/IGainfoService.cs | 12 - .../Services/Implements/GainfoFaceService.cs | 222 +++++++++++++++++- .../Services/Implements/GainfoService.cs | 178 +------------- 5 files changed, 251 insertions(+), 196 deletions(-) diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs index ed23f0ae..c94a192d 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs @@ -68,7 +68,7 @@ public class GainfosController : ControllerBase [Transactional] public async Task UploadFaceAsync(GainfoUploadFaceRequest request) { - await _gainfoService.UploadFaceAsync(request); + await _gainfoFaceService.UploadFaceAsync(request); } /// @@ -82,6 +82,18 @@ public class GainfosController : ControllerBase await _gainfoFaceService.UploadExternalFaceAsync(request); } + /// + /// 外部人员人脸照片 + /// + /// + /// + [AllowAnonymous] + [HttpGet("external/face")] + public async Task GetExternalFaceAsync(string idno) + { + return await _gainfoFaceService.GetExternalFaceAsync(idno); + } + /// /// 批量上传人脸照片 /// @@ -91,7 +103,7 @@ public class GainfosController : ControllerBase [IgnoreTenant] public async Task UploadFaceAsync(List request) { - await _gainfoService.UploadFacesAsync(request); + await _gainfoFaceService.UploadFacesAsync(request); } /// @@ -104,7 +116,7 @@ public class GainfosController : ControllerBase [HttpGet("face")] public async Task GetFaceAsync(string token) { - return await _gainfoService.GetFaceAsync(token); + return await _gainfoFaceService.GetFaceAsync(token); } /// @@ -115,7 +127,7 @@ public class GainfosController : ControllerBase [HttpGet("face/{userCode}")] public async Task GetFaceByUserCodeAsync(string userCode) { - return await _gainfoService.GetFaceByUserCodeAsync(userCode); + return await _gainfoFaceService.GetFaceByUserCodeAsync(userCode); } /// @@ -127,7 +139,7 @@ public class GainfosController : ControllerBase [HttpPost("faces")] public async Task> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request) { - return await _gainfoService.GetFaceByUserCodesAsync(request); + return await _gainfoFaceService.GetFaceByUserCodesAsync(request); } /// diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs index e2f00e2f..e4653c21 100644 --- a/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs @@ -1,8 +1,21 @@ using Dlhis.Basic.Organization.Request; +using Microsoft.AspNetCore.Mvc; namespace Dlhis.Basic.Organization.Services; public interface IGainfoFaceService : IScopeDependency { Task UploadExternalFaceAsync(GainfoUploadFaceRequest request); + + Task GetExternalFaceAsync(string idno); + + Task GetFaceAsync(string token); + + Task UploadFaceAsync(GainfoUploadFaceRequest request); + + Task UploadFacesAsync(List request); + + Task GetFaceByUserCodeAsync(string userCode); + + Task> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request); } diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs index 7624acfc..43347e5c 100644 --- a/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs @@ -1,7 +1,6 @@ using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Kurisu.Core.DataAccess.Dto; -using Microsoft.AspNetCore.Mvc; namespace Dlhis.Basic.Organization.Services; @@ -13,21 +12,10 @@ public interface IGainfoService : IScopeDependency Task CurrentUserInfoAsync(); - Task UploadFaceAsync(GainfoUploadFaceRequest request); - - Task UploadFacesAsync(List request); - - Task GetFaceAsync(string token); - - Task GetFaceByUserCodeAsync(string userCode); - - Task> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request); - Task> GetGainfoListAsync(GainfoListRequest request); Task GetGainfoDetailAsync(GainfoDetailRequest request); - Task MigrationAsync(MigrationRequest request); Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request); diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs index 2b91d5d8..b7754a96 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs @@ -1,8 +1,15 @@ -using Dlhis.Basic.Organization.Request; +using Dlhis.Basic.Device.Services; +using Dlhis.Basic.Organization.Request; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Enums; +using Dlhis.Entity.Device.Enums; +using Kurisu.AspNetCore.Utils; using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.CustomClass; +using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Services; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Mvc; namespace Dlhis.Basic.Organization.Services.Implements; @@ -10,11 +17,30 @@ public class GainfoFaceService : IGainfoFaceService { private readonly IGainfoStore _gainfoStore; private readonly IDbContext _dbContext; + private readonly ILogger _logger; + private readonly IConfiguration _configuration; + private readonly RedisCache _redisCache; + private readonly ICurrentUser _currentUser; + private readonly IDevicePermissionService _devicePermissionService; + private readonly IDataProtectionProvider _dataProtectionProvider; - public GainfoFaceService(IGainfoStore gainfoStore, IDbContext dbContext) + public GainfoFaceService(IGainfoStore gainfoStore, + IDbContext dbContext, + ILogger logger, + IConfiguration configuration, + RedisCache redisCache, + ICurrentUser currentUser, + IDevicePermissionService devicePermissionService, + IDataProtectionProvider dataProtectionProvider) { _gainfoStore = gainfoStore; _dbContext = dbContext; + _logger = logger; + _configuration = configuration; + _redisCache = redisCache; + _currentUser = currentUser; + _devicePermissionService = devicePermissionService; + _dataProtectionProvider = dataProtectionProvider; } public async Task UploadExternalFaceAsync(GainfoUploadFaceRequest request) @@ -48,4 +74,196 @@ public class GainfoFaceService : IGainfoFaceService await faceContext.UpdateAsync(face); } } + + public async Task GetExternalFaceAsync(string idno) + { + var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno"); + try + { + idno = protector.Unprotect(idno); + } + catch (Exception) + { + throw new UserFriendlyException("凭证有误,无法获取人脸数"); + } + + var dbContext = _dbContext.ChangeDb("face"); + var face = await dbContext.Queryable() + .Where(x => x.UserCode == idno) + .SingleAsync(); + + face.ThrowIfNull("人脸照片尚未录入"); + + var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); + + var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value; + var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get(); + + var key = $"face:{idno}"; + var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit)); + + return faceUrl + token; + } + + public async Task GetFaceAsync(string token) + { + var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); + + try + { + var password = timeLimitedDataProtector.Unprotect(token); + var userCode = password.Split(':')[1]; + + var faceCache = await _redisCache.HashGetAsync("faces", userCode); + if (faceCache.HasValue) + { + return new FileContentResult(Convert.FromBase64String(faceCache), "image/png"); + } + + var dbContext = _dbContext.ChangeDb("face"); + var face = await dbContext.Queryable().Where(x => x.UserCode == userCode).SingleAsync(); + + if (face == null) + { + _logger.LogWarning("学工号:{userCode}不存在人脸照片", userCode); + return new NotFoundResult(); + } + + return new FileContentResult(Convert.FromBase64String(face.Face), "image/png"); + } + catch (Exception ex) + { + _logger.LogError(ex, "获取人脸失败:{message}", ex.Message); + return new NotFoundResult(); + } + } + + public async Task UploadFaceAsync(GainfoUploadFaceRequest request) + { + var gainfo = await _gainfoStore.Queryable().Where(x => x.No == request.UserNo).FirstAsync(); + gainfo.ThrowIfNull("人员档案信息不存在"); + + var userId = _currentUser.GetIntSubjectId(); + + var faceContext = _dbContext.ChangeDb("face"); + var face = await faceContext.Queryable().Where(x => x.UserCode == gainfo.Code).SingleAsync(); + + var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update; + + await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face); + if (face == null) + { + face = new GainfoFaceEntity + { + UserCode = gainfo.Code, + Face = request.Face, + CreateTime = DateTime.Now, + ModifiedTime = DateTime.Now, + CreatedBy = userId, + ModifiedBy = userId + }; + + await faceContext.InsertAsync(face); + } + else + { + if (face.Face == request.Face) + { + _logger.LogWarning("相同的人脸照片更新忽略"); + return; + } + + face.Face = request.Face; + face.ModifiedBy = userId; + face.ModifiedTime = DateTime.Now; + await faceContext.UpdateAsync(face); + } + + //生成任务 + await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType); + } + + public async Task UploadFacesAsync(List requests) + { + foreach (var request in requests) + { + var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).Where(x => x.No == request.UserNo).FirstAsync(); + gainfo ??= await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync(); + + gainfo.ThrowIfNull("人员档案信息不存在"); + + var dbContext = _dbContext.ChangeDb("face"); + var face = await dbContext.Queryable().Where(x => x.UserCode == gainfo.Code).SingleAsync(); + + var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update; + + await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face); + if (face == null) + { + face = new GainfoFaceEntity + { + UserCode = gainfo.Code, + Face = request.Face + }; + + await dbContext.InsertAsync(face); + } + else + { + if (face.Face == request.Face) + { + _logger.LogWarning("相同的人脸照片更新忽略"); + return; + } + + face.Face = request.Face; + await dbContext.UpdateAsync(face); + } + + //生成任务 + await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType); + } + } + + + public async Task GetFaceByUserCodeAsync(string userCode) + { + var gainfo = await _dbContext.Queryable().Where(x => x.Code == userCode).SingleAsync(); + gainfo.ThrowIfNull($"{userCode}人员信息不存在"); + + var dbContext = _dbContext.ChangeDb("face"); + var face = await dbContext.Queryable() + .Where(x => x.UserCode == userCode) + .SingleAsync(); + + face.ThrowIfNull("人脸照片尚未录入"); + + var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); + + var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value; + var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get(); + + var key = $"face:{userCode}"; + var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit)); + + return faceUrl + token; + } + + public async Task> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request) + { + var faceDictionary = new Dictionary(); + + foreach (var userCode in request.UserCodes) + { + try + { + var faceUrl = await GetFaceByUserCodeAsync(userCode); + faceDictionary.Add(userCode, faceUrl); + } + catch (Exception) + { + } + } + return faceDictionary; + } } diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs index ee5a9bba..33c1ea94 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs @@ -1,20 +1,16 @@ -using Dlhis.Basic.Device.Services; -using Dlhis.Basic.Organization.Request; +using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Enums; -using Dlhis.Entity.Device.Enums; using Dlhis.Scheduled.Api; using Dlhis.Scheduled.Api.Request; using Dlhis.Sys.Api; -using Kurisu.AspNetCore.Utils; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Mvc; namespace Dlhis.Basic.Organization.Services.Implements; @@ -24,9 +20,6 @@ public class GainfoService : IGainfoService private readonly IDbContext _dbContext; private readonly IDataProtectionProvider _dataProtectionProvider; private readonly ICurrentUser _currentUser; - private readonly IDevicePermissionService _devicePermissionService; - private readonly RedisCache _redisCache; - private readonly IConfiguration _configuration; private readonly ITenantApi _tenantApi; private readonly IHangfireApi _hangfireApi; private readonly ILogger _logger; @@ -35,9 +28,6 @@ public class GainfoService : IGainfoService IDbContext dbContext, IDataProtectionProvider dataProtectionProvider, ICurrentUser currentUser, - IDevicePermissionService devicePermissionService, - RedisCache redisCache, - IConfiguration configuration, ITenantApi tenantApi, IHangfireApi hangfireApi, ILogger logger) @@ -46,9 +36,6 @@ public class GainfoService : IGainfoService _dbContext = dbContext; _dataProtectionProvider = dataProtectionProvider; _currentUser = currentUser; - _devicePermissionService = devicePermissionService; - _redisCache = redisCache; - _configuration = configuration; _tenantApi = tenantApi; _hangfireApi = hangfireApi; _logger = logger; @@ -162,169 +149,6 @@ public class GainfoService : IGainfoService return info; } - public async Task GetFaceAsync(string token) - { - var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); - - try - { - var password = timeLimitedDataProtector.Unprotect(token); - var userCode = password.Split(':')[1]; - - var faceCache = await _redisCache.HashGetAsync("faces", userCode); - if (faceCache.HasValue) - { - return new FileContentResult(Convert.FromBase64String(faceCache), "image/png"); - } - - var dbContext = _dbContext.ChangeDb("face"); - var face = await dbContext.Queryable().Where(x => x.UserCode == userCode).SingleAsync(); - - if (face == null) - { - _logger.LogWarning("学工号:{userCode}不存在人脸照片", userCode); - return new NotFoundResult(); - } - - return new FileContentResult(Convert.FromBase64String(face.Face), "image/png"); - } - catch (Exception ex) - { - _logger.LogError(ex, "获取人脸失败:{message}", ex.Message); - return new NotFoundResult(); - } - } - - public async Task UploadFaceAsync(GainfoUploadFaceRequest request) - { - var gainfo = await _gainfoStore.Queryable().Where(x => x.No == request.UserNo).FirstAsync(); - gainfo.ThrowIfNull("人员档案信息不存在"); - - var userId = _currentUser.GetIntSubjectId(); - - var faceContext = _dbContext.ChangeDb("face"); - var face = await faceContext.Queryable().Where(x => x.UserCode == gainfo.Code).SingleAsync(); - - var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update; - - await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face); - if (face == null) - { - face = new GainfoFaceEntity - { - UserCode = gainfo.Code, - Face = request.Face, - CreateTime = DateTime.Now, - ModifiedTime = DateTime.Now, - CreatedBy = userId, - ModifiedBy = userId - }; - - await faceContext.InsertAsync(face); - } - else - { - if (face.Face == request.Face) - { - _logger.LogWarning("相同的人脸照片更新忽略"); - return; - } - - face.Face = request.Face; - face.ModifiedBy = userId; - face.ModifiedTime = DateTime.Now; - await faceContext.UpdateAsync(face); - } - - //生成任务 - await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType); - } - - public async Task UploadFacesAsync(List requests) - { - foreach (var request in requests) - { - var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).Where(x => x.No == request.UserNo).FirstAsync(); - gainfo ??= await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync(); - - gainfo.ThrowIfNull("人员档案信息不存在"); - - var dbContext = _dbContext.ChangeDb("face"); - var face = await dbContext.Queryable().Where(x => x.UserCode == gainfo.Code).SingleAsync(); - - var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update; - - await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face); - if (face == null) - { - face = new GainfoFaceEntity - { - UserCode = gainfo.Code, - Face = request.Face - }; - - await dbContext.InsertAsync(face); - } - else - { - if (face.Face == request.Face) - { - _logger.LogWarning("相同的人脸照片更新忽略"); - return; - } - - face.Face = request.Face; - await dbContext.UpdateAsync(face); - } - - //生成任务 - await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType); - } - } - - public async Task GetFaceByUserCodeAsync(string userCode) - { - var gainfo = await _dbContext.Queryable().Where(x => x.Code == userCode).SingleAsync(); - gainfo.ThrowIfNull($"{userCode}人员信息不存在"); - - var dbContext = _dbContext.ChangeDb("face"); - - var face = await dbContext.Queryable() - .Where(x => x.UserCode == userCode) - .SingleAsync(); - - face.ThrowIfNull("人脸照片尚未录入"); - - var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector(); - - var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value; - var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get(); - - var key = $"face:{userCode}"; - var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit)); - - return faceUrl + token; - } - - public async Task> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request) - { - var faceDictionary = new Dictionary(); - - foreach (var userCode in request.UserCodes) - { - try - { - var faceUrl = await GetFaceByUserCodeAsync(userCode); - faceDictionary.Add(userCode, faceUrl); - } - catch (Exception) - { - } - } - return faceDictionary; - } - - public async Task CheckIdNoAndNameMatchAsync(GainfoCheckIdNoAndNameRequest request) { var match = await _gainfoStore.Queryable(GainfoStatusEnumType.External).AnyAsync(x => x.IdNo == request.IdNo && x.Name == request.Name); From de37fc8becd3b5844779a8fcf7cd97ed74e84fe5 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Thu, 18 Apr 2024 14:34:58 +0800 Subject: [PATCH 09/13] =?UTF-8?q?fix=20redis=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Src/Dlhis.Visitor/appsettings.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Src/Dlhis.Visitor/appsettings.json b/Src/Dlhis.Visitor/appsettings.json index 4946a1a3..49ad4e0d 100644 --- a/Src/Dlhis.Visitor/appsettings.json +++ b/Src/Dlhis.Visitor/appsettings.json @@ -16,6 +16,9 @@ "SlowSqlTime": 1, "EnableSqlLog": false }, + "RedisOptions": { + "ConnectionString": "192.168.199.30:30115,defaultDatabase=1,password=dlhis123" + }, "DataProtectionOptions": { "Enable": true, "AppName": "yiliantong" From 5426a2144940dbfbc58acf5e344a0b9bfcf9bd92 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Thu, 18 Apr 2024 15:03:41 +0800 Subject: [PATCH 10/13] =?UTF-8?q?fix=20=E5=A4=96=E9=83=A8=E4=BA=BA?= =?UTF-8?q?=E5=91=98=E4=B8=8A=E4=BC=A0=E7=85=A7=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Implements/GainfoFaceService.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs index b7754a96..5080477d 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs @@ -45,6 +45,16 @@ public class GainfoFaceService : IGainfoFaceService public async Task UploadExternalFaceAsync(GainfoUploadFaceRequest request) { + var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno"); + try + { + request.UserNo = protector.Unprotect(request.UserNo); + } + catch (Exception) + { + throw new UserFriendlyException("凭证有误,无法获取人脸数"); + } + var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync(); gainfo.ThrowIfNull("人员信息不存在"); From de58369b1c62e4c8f2c75f56141eaa2815ad49f1 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Thu, 18 Apr 2024 15:06:27 +0800 Subject: [PATCH 11/13] =?UTF-8?q?fix=20=E8=BA=AB=E4=BB=BD=E8=AF=81?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Organization/Services/Implements/GainfoFaceService.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs index 5080477d..c00b1641 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs @@ -55,7 +55,9 @@ public class GainfoFaceService : IGainfoFaceService throw new UserFriendlyException("凭证有误,无法获取人脸数"); } - var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync(); + var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External) + .Where(x => x.IdNo == request.UserNo) + .FirstAsync(); gainfo.ThrowIfNull("人员信息不存在"); var faceContext = _dbContext.ChangeDb("face"); From 5888684c15d3b60d058982e87d4721623ffa3fd2 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Fri, 19 Apr 2024 17:06:51 +0800 Subject: [PATCH 12/13] =?UTF-8?q?fix=20=E6=B6=88=E8=B4=B9=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/BalanceSummaryController.cs | 37 ++ .../Order/Controllers/BalancesController.cs | 50 +-- .../Request/BalanceRecordAnalysisRequest.cs | 26 +- .../Response/BalanceRecordAnalysisRespones.cs | 34 -- .../Response/BalanceRecordAnalysisResponse.cs | 22 + .../BalanceRecordDetailPageResponse.cs | 19 + .../{Implements => }/BaseOrderService.cs | 2 +- .../Order/Services/IBalanceService.cs | 15 +- .../Order/Services/IBalanceSummaryService.cs | 12 + .../Services/Implements/BalanceService.cs | 405 +++--------------- .../Implements/BalanceSummaryService.cs | 52 +++ .../Order/Services/Implements/OrderService.cs | 23 +- .../Canteen/Enums/ShiftEnumType.cs | 10 +- 13 files changed, 262 insertions(+), 445 deletions(-) create mode 100644 Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs delete mode 100644 Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisRespones.cs create mode 100644 Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisResponse.cs rename Src/Dlhis.Canteen/Order/Services/{Implements => }/BaseOrderService.cs (98%) create mode 100644 Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs create mode 100644 Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs diff --git a/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs b/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs new file mode 100644 index 00000000..65c7555a --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Controllers/BalanceSummaryController.cs @@ -0,0 +1,37 @@ +using Dlhis.Canteen.Dishes.Request; +using Dlhis.Canteen.Order.Request; +using Dlhis.Canteen.Order.Response; +using Dlhis.Canteen.Order.Services; +using Kurisu.Core.DataAccess.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Dlhis.Canteen.Order.Controllers; + +/// +/// 消费统计 +/// +[Authorize] +[Route("api/[controller]")] +[ApiController] +public class BalanceSummaryController : ControllerBase +{ + private readonly IBalanceSummaryService _balanceSummaryService; + + public BalanceSummaryController(IBalanceSummaryService balanceSummaryService) + { + _balanceSummaryService = balanceSummaryService; + } + + /// + /// 用餐分析 + /// + /// + /// + [HttpGet("analysis")] + public async Task> BalanceRecordAnalysisAsync([FromQuery] BalanceRecordAnalysisRequest request) + { + return await _balanceSummaryService.BalanceRecordAnalysisAsync(request); + } +} diff --git a/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs b/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs index 84e5bd40..56341e2a 100644 --- a/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs +++ b/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs @@ -51,12 +51,12 @@ public class BalancesController : ControllerBase /// - /// 消费明细 + /// 营业点消费明细 /// /// /// [HttpGet("recordPageDetails")] - public async Task> RecordPageDetailsAsync([FromQuery] BalanceRecordPageDetailRequest request) + public async Task RecordPageDetailsAsync([FromQuery] BalanceRecordPageDetailRequest request) { return await _balanceService.RecordPageDetailsAsync(request); } @@ -97,52 +97,6 @@ public class BalancesController : ControllerBase return await _balanceService.GetPageByUserAsync(request); } - /// - /// 根据成本中心 - /// - /// - /// - [HttpGet("recordByCostId")] - public async Task> RecordByCostIdAsync([FromQuery] BalanceRecordPageByCostIdRequest request) - { - return await _balanceService.RecordByCostIdAsync(request); - } - - - /// - /// 消费汇总 根据部门号 - /// - /// - /// - [HttpGet("recordSummaryByNo")] - public async Task> BalanceRecordSummaryByNoAsync([FromQuery] BalanceRecordSummaryRequest request) - { - return await _balanceService.BalanceRecordSummaryByNoAsync(request); - } - - /// - /// 消费汇总 根据人事范围 - /// - /// - /// - [HttpGet("recordSummaryByTid")] - public async Task> BalanceRecordSummaryByTidAsync([FromQuery] BalanceRecordSummaryRequest request) - { - return await _balanceService.BalanceRecordSummaryByTidAsync(request); - } - - - /// - /// 用餐分析 - /// - /// - /// - [HttpGet("BalanceRecordSummaryAsync")] - public async Task> BalanceRecordAnalysisAsync([FromQuery] BalanceRecordAnalysisRequest request) - { - return await _balanceService.BalanceRecordAnalysisAsync(request); - } - /// /// 获取消费机总数、离线设备数量、营业点数量、可消费人数、人均日消费额 /// diff --git a/Src/Dlhis.Canteen/Order/Request/BalanceRecordAnalysisRequest.cs b/Src/Dlhis.Canteen/Order/Request/BalanceRecordAnalysisRequest.cs index 9fe8e693..01177303 100644 --- a/Src/Dlhis.Canteen/Order/Request/BalanceRecordAnalysisRequest.cs +++ b/Src/Dlhis.Canteen/Order/Request/BalanceRecordAnalysisRequest.cs @@ -1,22 +1,26 @@ -using Kurisu.Core.DataAccess.Dto; +using System.ComponentModel.DataAnnotations; +using Kurisu.Core.CustomClass; +using Kurisu.Core.DataAccess.Dto; namespace Dlhis.Canteen.Order.Request { - public class BalanceRecordAnalysisRequest : PageDto + public class BalanceRecordAnalysisRequest : PageDto, IValidatableObject { - /// - /// 开始日期 - /// - public DateTime? StartDatetime { get; set; } - - /// - /// 结束日期 - /// - public DateTime? EndDatetime { get; set; } + public DateTimePeriod SearchDateTimePeriod { get; set; } /// /// 营业点 /// public Guid? BusinessPlaceCode { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + if (SearchDateTimePeriod != null && SearchDateTimePeriod.End.HasValue) + { + SearchDateTimePeriod.End = SearchDateTimePeriod.End.Value.AddDays(1).AddSeconds(-1); + } + + yield break; + } } } diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisRespones.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisRespones.cs deleted file mode 100644 index f938e46e..00000000 --- a/Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisRespones.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Dlhis.Canteen.Order.Response; - -public class BalanceRecordAnalysisRespones -{ - /// - /// 消费日期 - /// - public DateOnly CostDate { get; set; } - - /// - /// 早餐人数 - /// - public int BreakfastNumberOfPeople { get; set; } - - /// - /// 午餐人数 - /// - public int LunchNumberOfPeople { get; set; } - - /// - /// 晚餐人数 - /// - public int DinnerNumberOfPeople { get; set; } - - /// - /// 宵夜人数 - /// - public int LateNightNumberOfPeople { get; set; } - - /// - /// 总人数 - /// - public int TotalNumberOfPeople { get; set; } -} diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisResponse.cs new file mode 100644 index 00000000..e0a5bd63 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordAnalysisResponse.cs @@ -0,0 +1,22 @@ +using Dlhis.Entity.Canteen.Enums; +using Kurisu.Core.CustomClass; + +namespace Dlhis.Canteen.Order.Response; + +public class BalanceRecordAnalysisResponse +{ + /// + /// 消费日期 + /// + public DateOnly Date { get; set; } + + /// + /// 餐次消费数据 + /// + public List> Items { get; set; } + + /// + /// 总人数 + /// + public int Total { get; set; } +} diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs index cf665408..22f3ebe2 100644 --- a/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs +++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordDetailPageResponse.cs @@ -1,9 +1,28 @@ using Dlhis.Entity.Canteen.Enums; using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.DataAccess.Dto; using Newtonsoft.Json; namespace Dlhis.Canteen.Order.Response; +public class BalanceRecordByBusinessPlaceResponse +{ + /// + /// 消费总金额 + /// + public decimal Amount { get; set; } + + /// + /// 消费人数 + /// + public int Total { get; set; } + + /// + /// 分页数据 + /// + public Pagination Pagination { get; set; } +} + public class BalanceRecordDetailPageResponse { public long Id { get; set; } diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs b/Src/Dlhis.Canteen/Order/Services/BaseOrderService.cs similarity index 98% rename from Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs rename to Src/Dlhis.Canteen/Order/Services/BaseOrderService.cs index b92f47de..04074c8d 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/BaseOrderService.cs @@ -7,7 +7,7 @@ using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Services; using Mapster; -namespace Dlhis.Canteen.Order.Services.Implements; +namespace Dlhis.Canteen.Order.Services; public abstract class BaseOrderService { diff --git a/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs b/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs index 25b5e6a8..5acebbdf 100644 --- a/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs @@ -15,15 +15,12 @@ public interface IBalanceService : IScopeDependency Task SupplementBalanceAsync(BalanceSupplementRequest request); - Task> RecordByCostIdAsync(BalanceRecordPageByCostIdRequest request); - - Task> RecordPageDetailsAsync(BalanceRecordPageDetailRequest request); - - Task> BalanceRecordSummaryByNoAsync(BalanceRecordSummaryRequest request); - - Task> BalanceRecordSummaryByTidAsync(BalanceRecordSummaryRequest request); - - Task> BalanceRecordAnalysisAsync(BalanceRecordAnalysisRequest request); + /// + /// 营业点消费明细 + /// + /// + /// + Task RecordPageDetailsAsync(BalanceRecordPageDetailRequest request); Task GetConsumeNumberAsync(); diff --git a/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs b/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs new file mode 100644 index 00000000..41a9dd3e --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Services/IBalanceSummaryService.cs @@ -0,0 +1,12 @@ +using Dlhis.Canteen.Dishes.Request; +using Dlhis.Canteen.Order.Request; +using Dlhis.Canteen.Order.Response; +using Kurisu.Core.DataAccess.Dto; +using Microsoft.AspNetCore.Mvc; + +namespace Dlhis.Canteen.Order.Services; + +public interface IBalanceSummaryService : IScopeDependency +{ + Task> BalanceRecordAnalysisAsync(BalanceRecordAnalysisRequest request); +} diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs index dac5dba0..47268f89 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs @@ -160,6 +160,74 @@ public class BalanceService : IBalanceService } + public async Task RecordPageDetailsAsync(BalanceRecordPageDetailRequest request) + { + var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Data.Select(x => (Guid?)x.Code).ToList(); + if (request.BusinessplaceCodes.IsPresent()) + { + myCodes = myCodes.Where(x => request.BusinessplaceCodes.Contains(x)).ToList(); + } + + var queryable = _dbContext.Queryable() + .LeftJoin((record, department) => record.DepartmentNo == department.No) + .LeftJoin((record, department, bplace) => record.BusinessPlaceCode == bplace.Code) + .LeftJoin((record, department, bplace, gainfo) => record.UserNo == gainfo.No) + .Where((record) => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) + .Where(record => myCodes.Contains(record.BusinessPlaceCode)) + .WhereIF(request.SearchDateTimePeriod?.Start.HasValue == true, record => record.CostDateTime >= request.SearchDateTimePeriod.Start) + .WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDateTime <= request.SearchDateTimePeriod.End) + .WhereIF(request.ShiftType.HasValue, record => record.ShiftType == request.ShiftType) + .WhereIF(request.Search.IsPresent(), record => record.UserCode == request.Search || record.Name == request.Search); + + var page = await queryable + .OrderBy(record => record.CostDateTime, OrderByType.Desc) + .Select((record, department, bplace, gainfo) => new BalanceRecordDetailPageResponse + { + Id = record.Id, + No = record.No, + CurrentAmount = SqlFunc.Abs(record.Amount), + CostDate = record.CostDate, + UserNo = record.UserNo, + UserCode = record.UserCode, + Source = record.Source, + UserName = record.Name, + DepartmentName = department.Name, + BusinessPlaceName = bplace.Name, + CostDateTime = record.CostDateTime, + ShiftType = record.ShiftType, + Werks = gainfo.Werks, + Factory = record.TenantId, + Remark = record.Remark, + }) + .ToPageListAsync(request); + + try + { + var tenantResult = await _tenantApi.GetTenantsInternalAsync(); + var tenants = tenantResult.Data; + + page.Data.ForEach(item => + { + item.Factory = tenants.FirstOrDefault(x => x.Code == item.Factory)?.Name; + }); + } + catch (Exception) + { + } + + + var amount = await queryable.SumAsync(record => SqlFunc.Abs(record.Amount)); + var total = await queryable.GroupBy(record => record.UserNo).Select(record => record.UserNo).CountAsync(); + + return new BalanceRecordByBusinessPlaceResponse + { + Amount = amount, + Total = total, + Pagination = page, + }; + } + + public async Task SupplementBalanceAsync(BalanceSupplementRequest request) { var balanceInfo = await _dbContext.Queryable().Where(x => x.No == request.No).SingleAsync(); @@ -208,342 +276,6 @@ public class BalanceService : IBalanceService }, 10); } - - /// - /// 根据成本中心 - /// - /// - /// - public async Task> RecordByCostIdAsync(BalanceRecordPageByCostIdRequest request) - { - var paeginfos = await _dbContext.Queryable() - .WhereIF(!request.UserCode.IsEmpty(), record => record.UserCode == request.UserCode) - .WhereIF(!request.DepartmentNo.IsEmpty(), record => record.DepartmentNo == request.DepartmentNo) - .WhereIF(!request.OriginTenantId.IsEmpty(), record => record.OriginTenantId == request.OriginTenantId) - .WhereIF(!request.CostId.IsEmpty(), record => record.CostId == request.CostId) - .WhereIF(request.StartDatetime.HasValue, record => record.CostDateTime >= request.StartDatetime) - .WhereIF(request.EndDatetime.HasValue, record => record.CostDateTime <= request.EndDatetime) - .Where(record => record.Type == BalanceRecordTypeEnumType.Out) - .OrderBy(record => record.CreateTime, OrderByType.Desc) - .ToListAsync(); - - var lst = new List(); - foreach (var costIdGroup in paeginfos.GroupBy(record => record.CostId)) - { - //每个costID - var obj = new BalanceRecordCostIdResponse - { - CostId = costIdGroup.Key - }; - - // 所有人次 - var BreakfastNumberOfPeople = costIdGroup.Count(x => x.ShiftType == ShiftEnumType.Breakfast); - - var LunchNumberOfPeople = costIdGroup.Count(x => x.ShiftType == ShiftEnumType.Lunch); - - var DinnerNumberOfPeople = costIdGroup.Count(x => x.ShiftType == ShiftEnumType.Dinner); - - var LateNightNumberOfPeople = costIdGroup.Count(x => x.ShiftType == ShiftEnumType.Nightsnack); - // 每个餐次人数 - obj.BreakfastNumberOfPeople = costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Select(x => x.UserNo).Distinct().Count(); - obj.LunchNumberOfPeople = costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Lunch).Select(x => x.UserNo).Distinct().Count(); - obj.DinnerNumberOfPeople = costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Dinner).Select(x => x.UserNo).Distinct().Count(); - obj.LateNightNumberOfPeople = costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Select(x => x.UserNo).Distinct().Count(); - - //餐次金额 - obj.BreakfastAmount = Math.Abs(costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Sum(x => x.Amount)); - obj.LunchAmount = Math.Abs(costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Lunch).Sum(x => x.Amount)); - obj.DinnerAmount = Math.Abs(costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Dinner).Sum(x => x.Amount)); - obj.LateNightAmount = Math.Abs(costIdGroup.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Sum(x => x.Amount)); - - - // 每个餐次单价 - obj.BreakfastPrice = BreakfastNumberOfPeople == 0 ? 0 : Math.Round(obj.BreakfastAmount / BreakfastNumberOfPeople, 2); - obj.LunchPrice = LunchNumberOfPeople == 0 ? 0 : Math.Round(obj.LunchAmount / LunchNumberOfPeople, 2); - obj.DinnerPrice = DinnerNumberOfPeople == 0 ? 0 : Math.Round(obj.DinnerAmount / DinnerNumberOfPeople, 2); - obj.LateNightPrice = LateNightNumberOfPeople == 0 ? 0 : Math.Round(obj.LateNightAmount / LateNightNumberOfPeople, 2); - - // 总人数 总金额 - obj.TotalNumberOfPeople = costIdGroup.Select(x => x.UserNo).Distinct().Count(); - obj.TotalAmount = obj.BreakfastAmount + obj.LunchAmount + obj.DinnerAmount + obj.LateNightAmount; - - lst.Add(obj); - } - - // 分页操作 - var startIndex = (request.PageIndex - 1) * request.PageSize; - var pagedData = lst.Skip(startIndex).Take(request.PageSize).ToList(); - - var pagination = new Pagination - { - PageIndex = request.PageIndex, - PageSize = request.PageSize, - Total = lst.Count, // 使用原始列表的总数进行分页 - Data = pagedData - }; - - return pagination; - } - - /// - /// 消费明细 - /// - /// - /// - public async Task> RecordPageDetailsAsync(BalanceRecordPageDetailRequest request) - { - var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Data.Select(x => (Guid?)x.Code).ToList(); - - var page = await _dbContext.Queryable() - .LeftJoin((record, department) => record.DepartmentNo == department.No) - .LeftJoin((record, department, bplace) => record.BusinessPlaceCode == bplace.Code) - .LeftJoin((record, department, bplace, gainfo) => record.UserNo == gainfo.No) - .Where((record) => myCodes.Contains(record.BusinessPlaceCode)) - .Where((record) => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) - .WhereIF(request.SearchDateTimePeriod?.Start.HasValue == true, record => record.CostDateTime >= request.SearchDateTimePeriod.Start) - .WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDateTime <= request.SearchDateTimePeriod.End) - .WhereIF(request.ShiftType.HasValue, record => record.ShiftType == request.ShiftType) - .WhereIF(request.Search.IsPresent(), record => record.UserCode == request.Search || record.Name == request.Search) - .WhereIF(request.BusinessplaceCodes.IsPresent(), record => request.BusinessplaceCodes.Contains(record.BusinessPlaceCode)) - .OrderBy(record => record.CostDateTime, OrderByType.Desc) - .Select((record, department, bplace, gainfo) => new BalanceRecordDetailPageResponse - { - Id = record.Id, - No = record.No, - CurrentAmount = SqlFunc.Abs(record.Amount), - CostDate = record.CostDate, - UserNo = record.UserNo, - UserCode = record.UserCode, - Source = record.Source, - UserName = record.Name, - DepartmentName = department.Name, - BusinessPlaceName = bplace.Name, - CostDateTime = record.CostDateTime, - ShiftType = record.ShiftType, - Werks = gainfo.Werks, - Factory = record.TenantId, - Remark = record.Remark, - }) - .ToPageListAsync(request); - - try - { - var tenantResult = await _tenantApi.GetTenantsInternalAsync(); - var tenants = tenantResult.Data; - - page.Data.ForEach(item => - { - item.Factory = tenants.FirstOrDefault(x => x.Code == item.Factory)?.Name; - }); - } - catch (Exception) - { - } - - return page; - } - /// - /// 消费汇总 根据部门号 - /// - /// - /// - public async Task> BalanceRecordSummaryByNoAsync(BalanceRecordSummaryRequest request) - { - var paeginfos = await _dbContext.Queryable() - .WhereIF(!request.DepartmentNo.IsEmpty(), record => record.DepartmentNo == request.DepartmentNo) - .WhereIF(!request.UserCode.IsEmpty(), record => record.UserCode == request.UserCode) - .WhereIF(!request.OriginTenantId.IsEmpty(), record => record.TenantId == request.OriginTenantId) - .WhereIF(request.StartDatetime.HasValue, record => record.CostDateTime >= request.StartDatetime) - .WhereIF(request.EndDatetime.HasValue, record => record.CostDateTime <= request.EndDatetime) - .WhereIF(!request.CostId.IsEmpty(), record => record.CostId == request.CostId) - .Where(record => record.Type == BalanceRecordTypeEnumType.Out) - .OrderBy(record => record.CreateTime, OrderByType.Desc) - .ToListAsync(); - - var lst = new List(); - - foreach (var departmentGroup in paeginfos.GroupBy(record => record.DepartmentNo)) - { - // 每个部门 - var obj = new BalanceRecordSummaryRespones - { - DepartmentNo = departmentGroup.Key, - CostId = request.CostId, - OriginTenantId = "" - }; - // 所有人次 - var BreakfastNumberOfPeople = departmentGroup.Count(x => x.ShiftType == ShiftEnumType.Breakfast); - - var LunchNumberOfPeople = departmentGroup.Count(x => x.ShiftType == ShiftEnumType.Lunch); - - var DinnerNumberOfPeople = departmentGroup.Count(x => x.ShiftType == ShiftEnumType.Dinner); - - var LateNightNumberOfPeople = departmentGroup.Count(x => x.ShiftType == ShiftEnumType.Nightsnack); - //每个餐次人数 - obj.BreakfastNumberOfPeople = departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Select(x => x.UserNo).Distinct().Count(); - obj.LunchNumberOfPeople = departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Lunch).Select(x => x.UserNo).Distinct().Count(); - obj.DinnerNumberOfPeople = departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Dinner).Select(x => x.UserNo).Distinct().Count(); - obj.LateNightNumberOfPeople = departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Select(x => x.UserNo).Distinct().Count(); - - //餐次金额 - obj.BreakfastAmount = Math.Abs(departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Sum(x => x.Amount)); - obj.LunchAmount = Math.Abs(departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Lunch).Sum(x => x.Amount)); - obj.DinnerAmount = Math.Abs(departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Dinner).Sum(x => x.Amount)); - obj.LateNightAmount = Math.Abs(departmentGroup.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Sum(x => x.Amount)); - - // 每个餐次单价 - obj.BreakfastPrice = BreakfastNumberOfPeople == 0 ? 0 : Math.Round(obj.BreakfastAmount / BreakfastNumberOfPeople, 2); - obj.LunchPrice = LunchNumberOfPeople == 0 ? 0 : Math.Round(obj.LunchAmount / LunchNumberOfPeople, 2); - obj.DinnerPrice = DinnerNumberOfPeople == 0 ? 0 : Math.Round(obj.DinnerAmount / DinnerNumberOfPeople, 2); - obj.LateNightPrice = LateNightNumberOfPeople == 0 ? 0 : Math.Round(obj.LateNightAmount / LateNightNumberOfPeople, 2); - - // 总人数 总金额 - obj.TotalNumberOfPeople = departmentGroup.Select(x => x.UserNo).Distinct().Count(); - obj.TotalAmount = obj.BreakfastAmount + obj.LunchAmount + obj.DinnerAmount + obj.LateNightAmount; - lst.Add(obj); - } - - var departments = await _dbContext.Queryable().ToListAsync(); - lst.ForEach(x => - { - x.DepartmentName = departments.Where(d => d.No == x.DepartmentNo).Select(d => d.Name).First(); - }); - - // 分页操作 - var startIndex = (request.PageIndex - 1) * request.PageSize; - var pagedData = lst.Skip(startIndex).Take(request.PageSize).ToList(); - - var pagination = new Pagination - { - PageIndex = request.PageIndex, - PageSize = request.PageSize, - Total = lst.Count, // 使用原始列表的总数进行分页 - Data = pagedData - }; - - return pagination; - } - - /// - /// 消费汇总 根据人事范围 - /// - /// - /// - public async Task> BalanceRecordSummaryByTidAsync(BalanceRecordSummaryRequest request) - { - var paeginfos = await _dbContext.Queryable() - .WhereIF(!request.DepartmentNo.IsEmpty(), record => record.DepartmentNo == request.DepartmentNo) - .WhereIF(!request.UserCode.IsEmpty(), record => record.UserCode == request.UserCode) - .WhereIF(!request.OriginTenantId.IsEmpty(), record => record.TenantId == request.OriginTenantId) - .WhereIF(request.StartDatetime.HasValue, record => record.CostDateTime >= request.StartDatetime) - .WhereIF(request.EndDatetime.HasValue, record => record.CostDateTime <= request.EndDatetime) - .WhereIF(!request.CostId.IsEmpty(), record => record.CostId == request.CostId) - .Where(record => record.Type == BalanceRecordTypeEnumType.Out) - .OrderBy(record => record.CreateTime, OrderByType.Desc) - .ToListAsync(); - - var lst = new List(); - - foreach (var originTenantIdGroup in paeginfos.GroupBy(record => record.OriginTenantId)) - { - // 每个人事范围 - var obj = new BalanceRecordSummaryRespones - { - OriginTenantId = originTenantIdGroup.Key, - CostId = request.CostId, - DepartmentNo = "" - }; - - // 所有人次 - var BreakfastNumberOfPeople = originTenantIdGroup.Count(x => x.ShiftType == ShiftEnumType.Breakfast); - var LunchNumberOfPeople = originTenantIdGroup.Count(x => x.ShiftType == ShiftEnumType.Lunch); - var DinnerNumberOfPeople = originTenantIdGroup.Count(x => x.ShiftType == ShiftEnumType.Dinner); - var LateNightNumberOfPeople = originTenantIdGroup.Count(x => x.ShiftType == ShiftEnumType.Nightsnack); - //每个餐次人数 - obj.BreakfastNumberOfPeople = originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Select(x => x.UserNo).Distinct().Count(); - obj.LunchNumberOfPeople = originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Lunch).Select(x => x.UserNo).Distinct().Count(); - obj.DinnerNumberOfPeople = originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Dinner).Select(x => x.UserNo).Distinct().Count(); - obj.LateNightNumberOfPeople = originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Select(x => x.UserNo).Distinct().Count(); - - //餐次金额 - obj.BreakfastAmount = Math.Abs(originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Sum(x => x.Amount)); - obj.LunchAmount = Math.Abs(originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Lunch).Sum(x => x.Amount)); - obj.DinnerAmount = Math.Abs(originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Dinner).Sum(x => x.Amount)); - obj.LateNightAmount = Math.Abs(originTenantIdGroup.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Sum(x => x.Amount)); - - - // 每个餐次单价 - obj.BreakfastPrice = BreakfastNumberOfPeople == 0 ? 0 : Math.Round(obj.BreakfastAmount / BreakfastNumberOfPeople, 2); - obj.LunchPrice = LunchNumberOfPeople == 0 ? 0 : Math.Round(obj.LunchAmount / LunchNumberOfPeople, 2); - obj.DinnerPrice = DinnerNumberOfPeople == 0 ? 0 : Math.Round(obj.DinnerAmount / DinnerNumberOfPeople, 2); - obj.LateNightPrice = LateNightNumberOfPeople == 0 ? 0 : Math.Round(obj.LateNightAmount / LateNightNumberOfPeople, 2); - - // 总人数 总金额 - obj.TotalNumberOfPeople = originTenantIdGroup.Select(x => x.UserNo).Distinct().Count(); - obj.TotalAmount = obj.BreakfastAmount + obj.LunchAmount + obj.DinnerAmount + obj.LateNightAmount; - lst.Add(obj); - } - // 分页操作 - var startIndex = (request.PageIndex - 1) * request.PageSize; - var pagedData = lst.Skip(startIndex).Take(request.PageSize).ToList(); - - var pagination = new Pagination - { - PageIndex = request.PageIndex, - PageSize = request.PageSize, - Total = lst.Count, // 使用原始列表的总数进行分页 - Data = pagedData - }; - - return pagination; - } - - /// - /// 用餐分析 - /// - /// - /// - public async Task> BalanceRecordAnalysisAsync(BalanceRecordAnalysisRequest request) - { - var pageinfo = await _dbContext.Queryable() - .WhereIF(request.StartDatetime.HasValue, record => record.CostDateTime >= request.StartDatetime) - .WhereIF(request.EndDatetime.HasValue, record => record.CostDateTime <= request.EndDatetime) - .WhereIF(request.BusinessPlaceCode.HasValue, record => record.BusinessPlaceCode == request.BusinessPlaceCode) - .Where(record => record.Type == BalanceRecordTypeEnumType.Out) - .ToListAsync(); - - var lst = new List(); - foreach (var first in pageinfo.GroupBy(record => record.CostDateTime.ToString("yyyy-MM-dd"))) - { - var obj = new BalanceRecordAnalysisRespones - { - CostDate = DateOnly.FromDateTime(Convert.ToDateTime(first.Key)), - //每个餐次人数 - BreakfastNumberOfPeople = first.Where(x => x.ShiftType == ShiftEnumType.Breakfast).Select(x => x.UserNo).Distinct().Count(), - LunchNumberOfPeople = first.Where(x => x.ShiftType == ShiftEnumType.Lunch).Select(x => x.UserNo).Distinct().Count(), - DinnerNumberOfPeople = first.Where(x => x.ShiftType == ShiftEnumType.Dinner).Select(x => x.UserNo).Distinct().Count(), - LateNightNumberOfPeople = first.Where(x => x.ShiftType == ShiftEnumType.Nightsnack).Select(x => x.UserNo).Distinct().Count(), - - TotalNumberOfPeople = first.Where(x => x.CostDate.ToString("yyyy-MM-dd") == first.Key).Select(x => x.UserNo).Distinct().Count() - }; - - lst.Add(obj); - } - // 分页操作 - var startIndex = (request.PageIndex - 1) * request.PageSize; - var pagedData = lst.Skip(startIndex).Take(request.PageSize).ToList(); - - var pagination = new Pagination - { - PageIndex = request.PageIndex, - PageSize = request.PageSize, - Total = lst.Count, // 使用原始列表的总数进行分页 - Data = pagedData - }; - - return pagination; - } - public async Task GetPageByUserAsync(BalanceRecordUserPageRequest request) { var jinkoCode = _currentUser.GetUserClaim("jinko-code") ?? string.Empty; @@ -631,6 +363,7 @@ public class BalanceService : IBalanceService return res; } + /// /// 获取单日消费数据 /// diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs new file mode 100644 index 00000000..e5b4b1cf --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceSummaryService.cs @@ -0,0 +1,52 @@ +using Dlhis.Canteen.Order.Request; +using Dlhis.Canteen.Order.Response; +using Dlhis.Entity.Canteen.Entities; +using Dlhis.Entity.Canteen.Enums; +using Kurisu.Core.CustomClass; +using Kurisu.Core.DataAccess.Dto; +using Kurisu.Core.DataAccess.Extensions; +using Kurisu.SqlSugar.Services; + +namespace Dlhis.Canteen.Order.Services.Implements; + +public class BalanceSummaryService : IBalanceSummaryService +{ + private readonly IDbContext _dbContext; + + public BalanceSummaryService(IDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> BalanceRecordAnalysisAsync(BalanceRecordAnalysisRequest request) + { + var list = await _dbContext.Queryable() + .WhereIF(request.SearchDateTimePeriod?.Start.HasValue == true && request.SearchDateTimePeriod?.End.HasValue == true, + record => record.CostDate >= request.SearchDateTimePeriod.Start && record.CostDate <= request.SearchDateTimePeriod.End) + .WhereIF(request.BusinessPlaceCode.HasValue, record => record.BusinessPlaceCode == request.BusinessPlaceCode) + .Where(record => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid) + .ToListAsync(); + + var shifts = Enum.GetValues().ToList(); + + var page = list.GroupBy(record => record.CostDate).Select(grp => + { + return new BalanceRecordAnalysisResponse + { + Date = DateOnly.FromDateTime(grp.Key), + Items = shifts.Select(shift => + { + return new KeyValueDto + { + Key = shift, + Value = grp.Where(x => x.ShiftType == ShiftEnumType.Breakfast).DistinctBy(x => x.UserNo).Count() + }; + }).ToList(), + Total = grp.Where(x => x.CostDate == grp.Key).DistinctBy(x => x.UserNo).Count() + }; + }) + .ToPage(request); + + return page; + } +} diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs index de376b0f..c5deb241 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs @@ -18,6 +18,7 @@ using Dlhis.Canteen.Order.Response; using Dlhis.Canteen.Dishes; using Dlhis.Canteen.Order.Request; using Kurisu.Core.Result; +using Org.BouncyCastle.Asn1.Ocsp; namespace Dlhis.Canteen.Order.Services.Implements; @@ -61,7 +62,7 @@ public class OrderService : BaseOrderService, IOrderService { if (handler.Acquired) { - if (!await DbContext.Queryable().Where(x => x.ThirdNo == request.ThirdNo).AnyAsync()) + if (!await ToCheckAsync(request.ThirdNo)) { try { @@ -128,6 +129,26 @@ public class OrderService : BaseOrderService, IOrderService }; } + private async Task ToCheckAsync(string thirdNo) + { + var order = await DbContext.Queryable() + .Where(x => x.ThirdNo == thirdNo) + .OrderBy(x => x.CreateTime, OrderByType.Desc) + .FirstAsync(); + + if (order == null) + { + return false; + } + + if (!order.IsOffline && order.OrderStatus == CanteenOrderStatusEnumType.Success) + { + return true; + } + + return false; + } + private async Task HandleOfflineAsync(ConsumeRequest request, GainfoEntity gainfo) { diff --git a/Src/Dlhis.Entity/Canteen/Enums/ShiftEnumType.cs b/Src/Dlhis.Entity/Canteen/Enums/ShiftEnumType.cs index 410b9f27..ca0c2e72 100644 --- a/Src/Dlhis.Entity/Canteen/Enums/ShiftEnumType.cs +++ b/Src/Dlhis.Entity/Canteen/Enums/ShiftEnumType.cs @@ -12,29 +12,29 @@ public enum ShiftEnumType /// 早餐 /// [Description("早餐")] - Breakfast = 1, + Breakfast = 10, /// /// 午餐 /// [Description("午餐")] - Lunch = 2, + Lunch = 20, /// /// 晚餐 /// [Description("晚餐")] - Dinner = 3, + Dinner = 30, /// /// 宵夜 /// [Description("宵夜")] - Nightsnack = 4, + Nightsnack = 40, /// /// 凌晨餐 /// [Description("凌晨餐")] - Midnightsnack = 5, + Midnightsnack = 50, } \ No newline at end of file From 125aae476b1b73c8c2574e9c3773b738442e1fcc Mon Sep 17 00:00:00 2001 From: liguoyang Date: Fri, 19 Apr 2024 17:27:49 +0800 Subject: [PATCH 13/13] =?UTF-8?q?fix=20=E4=BF=AE=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=88=86=E9=85=8D=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entity/AppointmentAreaAssignmentEntity.cs | 9 ++++----- .../ApponintmentAreasController.cs | 2 +- .../Request/AppointmentAreaAssignRequest.cs | 3 +-- .../Services/Implements/AppointmentService.cs | 20 ++++++++----------- .../Implements/ApponintmentAreaService.cs | 4 ++-- Src/Dlhis.Visitor/Dlhis.Visitor.csproj | 1 - Src/Dlhis.Visitor/Dockerfile | 1 - 7 files changed, 16 insertions(+), 24 deletions(-) diff --git a/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs b/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs index 3635b96b..320f9599 100644 --- a/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs +++ b/Src/Dlhis.Entity/Visitor/Entity/AppointmentAreaAssignmentEntity.cs @@ -17,12 +17,11 @@ public class AppointmentAreaAssignmentEntity : SugarBaseEntity, ITenantId public string CustomCode { get; set; } /// - /// 分组code + /// 设备code /// - [SugarColumn(IsNullable = false, ColumnDescription = "分组code")] - public Guid GroupCode { get; set; } - //UniqueGroupNameList = new[] { "idx_aaa_cc_grpc_tid" } + [SugarColumn(IsNullable = false, ColumnDescription = "设备code")] + public Guid DeviceCode { get; set; } - [SugarColumn()] + [SugarColumn] public string TenantId { get; set; } } diff --git a/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs b/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs index c7055988..f2392cbb 100644 --- a/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs +++ b/Src/Dlhis.Visitor/Appointment/Controllers/ApponintmentAreasController.cs @@ -57,7 +57,7 @@ public class ApponintmentAreasController : ControllerBase } /// - /// 分配设备组 + /// 分配设备 /// /// [HttpPost("assign")] diff --git a/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs b/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs index 7ef2b7e9..755a14a8 100644 --- a/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs +++ b/Src/Dlhis.Visitor/Appointment/Request/AppointmentAreaAssignRequest.cs @@ -10,9 +10,8 @@ public class AppointmentAreaAssignRequest [Required] public string CustomCode { get; set; } - /// /// 分组 /// - public List GroupCodes { get; set; } + public List DeviceCodes { get; set; } } diff --git a/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs b/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs index 2e4a405b..3942964b 100644 --- a/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs +++ b/Src/Dlhis.Visitor/Appointment/Services/Implements/AppointmentService.cs @@ -1,5 +1,4 @@ -using Dlhis.Basic.Api; -using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Enums; using Dlhis.Entity.Visitor.Entity; @@ -20,13 +19,11 @@ namespace Dlhis.Visitor.Appointment.Services.Implements; public class AppointmentService : IAppointmentService { private readonly IDbContext _dbContext; - private readonly IDeviceGroupApi _deviceGroupApi; private readonly IDataProtectionProvider _dataProtectionProvider; - public AppointmentService(IDbContext dbContext, IDeviceGroupApi deviceGroupApi, IDataProtectionProvider dataProtectionProvider) + public AppointmentService(IDbContext dbContext, IDataProtectionProvider dataProtectionProvider) { _dbContext = dbContext; - _deviceGroupApi = deviceGroupApi; _dataProtectionProvider = dataProtectionProvider; } @@ -136,23 +133,22 @@ public class AppointmentService : IAppointmentService detail.ThrowIfNull("预约信息不存在"); var mst = await _dbContext.Queryable().Where(x => x.Id == detail.AppointmentId).FirstAsync(); - var deviceGroup = await _dbContext.Queryable() + var deviceCodes = await _dbContext.Queryable() .Where(x => x.CustomCode == mst.AreaCustomCode) - .Select(x => x.GroupCode) - .FirstAsync(); + .Select(x => x.DeviceCode) + .ToListAsync(); - var deviceCodesResult = await _deviceGroupApi.GetDevicesByCodeAsync(deviceGroup); - var deviceCodes = deviceCodesResult.Data; + var deviceUniqueNos = await _dbContext.Queryable().Where(x => deviceCodes.Contains(x.Code)).Select(x => x.UniqueNo).ToListAsync(); var userNo = detail.IsExternal ? await _dbContext.Queryable().Where(x => x.IdNo == detail.IdNo).Select(x => x.No).FirstAsync() : await _dbContext.Queryable().Where(x => x.IdNo == detail.IdNo).Select(x => x.No).FirstAsync(); - await _dbContext.InsertAsync(deviceCodes.Select(x => new DeviceTaskEntity + await _dbContext.InsertAsync(deviceUniqueNos.Select(x => new DeviceTaskEntity { CancellationId = 0, DeviceType = DeviceTypeEnumType.Door, - DeviceUniqueNo = x.UniqueNo, + DeviceUniqueNo = x, Status = DeviceTaskStatusEnumType.Wait, UserNo = userNo, Type = DeviceTaskEnumType.Add, diff --git a/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs b/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs index 64e6d6e5..b67159aa 100644 --- a/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs +++ b/Src/Dlhis.Visitor/Appointment/Services/Implements/ApponintmentAreaService.cs @@ -63,10 +63,10 @@ public class ApponintmentAreaService : IApponintmentAreaService .Where(x => x.CustomCode == request.CustomCode) .ExecuteCommandAsync(); - var data = request.GroupCodes.Select(x => new AppointmentAreaAssignmentEntity + var data = request.DeviceCodes.Select(x => new AppointmentAreaAssignmentEntity { CustomCode = request.CustomCode, - GroupCode = x, + DeviceCode = x, }) .ToList(); diff --git a/Src/Dlhis.Visitor/Dlhis.Visitor.csproj b/Src/Dlhis.Visitor/Dlhis.Visitor.csproj index 3e4a2742..e76f0181 100644 --- a/Src/Dlhis.Visitor/Dlhis.Visitor.csproj +++ b/Src/Dlhis.Visitor/Dlhis.Visitor.csproj @@ -19,7 +19,6 @@ - diff --git a/Src/Dlhis.Visitor/Dockerfile b/Src/Dlhis.Visitor/Dockerfile index 104cb4f1..bf1c8a0e 100644 --- a/Src/Dlhis.Visitor/Dockerfile +++ b/Src/Dlhis.Visitor/Dockerfile @@ -8,7 +8,6 @@ FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["Src/Dlhis.Visitor/Dlhis.Visitor.csproj", "Src/Dlhis.Visitor/"] -COPY ["Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj", "Src/Dlhis.Basic.Api/"] COPY ["Src/Dlhis.Entity/Dlhis.Entity.csproj", "Src/Dlhis.Entity/"] RUN dotnet restore "./Src/Dlhis.Visitor/./Dlhis.Visitor.csproj" COPY . .