李昊 5 anni fa
parent
commit
b14c887f60
100 ha cambiato i file con 9622 aggiunte e 0 eliminazioni
  1. 263 0
      .gitignore
  2. 8 0
      GxPress/.vscode/solution-explorer/class.cs-template
  3. 3 0
      GxPress/.vscode/solution-explorer/class.ts-template
  4. 9 0
      GxPress/.vscode/solution-explorer/class.vb-template
  5. 3 0
      GxPress/.vscode/solution-explorer/default.ts-template
  6. 8 0
      GxPress/.vscode/solution-explorer/enum.cs-template
  7. 8 0
      GxPress/.vscode/solution-explorer/interface.cs-template
  8. 3 0
      GxPress/.vscode/solution-explorer/interface.ts-template
  9. 17 0
      GxPress/.vscode/solution-explorer/template-parameters.js
  10. 96 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminAppReportController.cs
  11. 85 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminAppVersionController.cs
  12. 118 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminArticleController.cs
  13. 73 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminArticleGroupController.cs
  14. 47 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminArticleLabelController.cs
  15. 47 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminCaptchaController.cs
  16. 116 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminCarController.cs
  17. 47 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminCommentController.cs
  18. 143 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminController.cs
  19. 86 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminDepartmentController.cs
  20. 51 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminFeedbackController.cs
  21. 80 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminFileController.cs
  22. 106 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminFinanceController.cs
  23. 87 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminFlowController.Actions.cs
  24. 146 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminFlowController.Dto.cs
  25. 105 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminFlowController.cs
  26. 113 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminHumanAffairsController.cs
  27. 53 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminJobController.cs
  28. 120 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminMeetingController.cs
  29. 75 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminNoticeController.cs
  30. 108 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminPrintController.cs
  31. 18 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminProcessController.Dto.cs
  32. 138 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminProcessController.cs
  33. 73 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminProcessGroupController.cs
  34. 82 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminRoleController.cs
  35. 71 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminRoleGroupController.cs
  36. 103 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminSellController.cs
  37. 79 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminSlideController.cs
  38. 106 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminStorehouseController.cs
  39. 102 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminThesaurusController.cs
  40. 243 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminUserController.cs
  41. 477 0
      GxPress/Api/GxPress.Api/AdminControllers/AdminUtilsController.cs
  42. 32 0
      GxPress/Api/GxPress.Api/AppControllers/AboutController.cs
  43. 100 0
      GxPress/Api/GxPress.Api/AppControllers/AddressBookGroupController.cs
  44. 82 0
      GxPress/Api/GxPress.Api/AppControllers/AddressBookGroupUserController.cs
  45. 69 0
      GxPress/Api/GxPress.Api/AppControllers/AdminVerifyController.cs
  46. 49 0
      GxPress/Api/GxPress.Api/AppControllers/AnalyzeController.cs
  47. 80 0
      GxPress/Api/GxPress.Api/AppControllers/AppCarController.cs
  48. 37 0
      GxPress/Api/GxPress.Api/AppControllers/AppController.cs
  49. 156 0
      GxPress/Api/GxPress.Api/AppControllers/AppFlowController.Actions.cs
  50. 138 0
      GxPress/Api/GxPress.Api/AppControllers/AppFlowController.Dto.cs
  51. 312 0
      GxPress/Api/GxPress.Api/AppControllers/AppFlowController.cs
  52. 746 0
      GxPress/Api/GxPress.Api/AppControllers/AppMeetingController.cs
  53. 89 0
      GxPress/Api/GxPress.Api/AppControllers/AppProcessController.cs
  54. 43 0
      GxPress/Api/GxPress.Api/AppControllers/AppReportController.cs
  55. 53 0
      GxPress/Api/GxPress.Api/AppControllers/AppVersionController.cs
  56. 123 0
      GxPress/Api/GxPress.Api/AppControllers/ArticleController.cs
  57. 38 0
      GxPress/Api/GxPress.Api/AppControllers/ArticleGroupController.cs
  58. 62 0
      GxPress/Api/GxPress.Api/AppControllers/ArticleGroupUserController.cs
  59. 60 0
      GxPress/Api/GxPress.Api/AppControllers/BlacklistArticleController.cs
  60. 72 0
      GxPress/Api/GxPress.Api/AppControllers/BlacklistController.cs
  61. 56 0
      GxPress/Api/GxPress.Api/AppControllers/ChatRecordController.cs
  62. 67 0
      GxPress/Api/GxPress.Api/AppControllers/CollectionController.cs
  63. 63 0
      GxPress/Api/GxPress.Api/AppControllers/CommentController.cs
  64. 33 0
      GxPress/Api/GxPress.Api/AppControllers/DepartmentController.cs
  65. 55 0
      GxPress/Api/GxPress.Api/AppControllers/ElasticsSearchController.cs
  66. 57 0
      GxPress/Api/GxPress.Api/AppControllers/FeedbackController.cs
  67. 232 0
      GxPress/Api/GxPress.Api/AppControllers/FileController.cs
  68. 36 0
      GxPress/Api/GxPress.Api/AppControllers/FinanceController.cs
  69. 190 0
      GxPress/Api/GxPress.Api/AppControllers/GroupChatController.cs
  70. 157 0
      GxPress/Api/GxPress.Api/AppControllers/GroupChatUserController.cs
  71. 223 0
      GxPress/Api/GxPress.Api/AppControllers/GroupController.cs
  72. 39 0
      GxPress/Api/GxPress.Api/AppControllers/HumanAffairsController.cs
  73. 29 0
      GxPress/Api/GxPress.Api/AppControllers/ImController.cs
  74. 197 0
      GxPress/Api/GxPress.Api/AppControllers/MiddleController.cs
  75. 136 0
      GxPress/Api/GxPress.Api/AppControllers/MissiveController.cs
  76. 101 0
      GxPress/Api/GxPress.Api/AppControllers/NoteController.cs
  77. 151 0
      GxPress/Api/GxPress.Api/AppControllers/NoticeController.cs
  78. 118 0
      GxPress/Api/GxPress.Api/AppControllers/NoticeFolderController.cs
  79. 98 0
      GxPress/Api/GxPress.Api/AppControllers/OftenContactController.cs
  80. 39 0
      GxPress/Api/GxPress.Api/AppControllers/PrintController.cs
  81. 39 0
      GxPress/Api/GxPress.Api/AppControllers/SellController.cs
  82. 40 0
      GxPress/Api/GxPress.Api/AppControllers/ShareController.cs
  83. 44 0
      GxPress/Api/GxPress.Api/AppControllers/SlideController.cs
  84. 39 0
      GxPress/Api/GxPress.Api/AppControllers/StorehouseController.cs
  85. 28 0
      GxPress/Api/GxPress.Api/AppControllers/TestController.cs
  86. 39 0
      GxPress/Api/GxPress.Api/AppControllers/ThesaurusController.cs
  87. 60 0
      GxPress/Api/GxPress.Api/AppControllers/TopicCommentController.cs
  88. 249 0
      GxPress/Api/GxPress.Api/AppControllers/TopicController.cs
  89. 456 0
      GxPress/Api/GxPress.Api/AppControllers/UserController.cs
  90. 11 0
      GxPress/Api/GxPress.Api/AppControllers/VerificationCodeController.Dto.cs
  91. 73 0
      GxPress/Api/GxPress.Api/AppControllers/VerificationCodeController.cs
  92. 38 0
      GxPress/Api/GxPress.Api/AppControllers/VisitController.cs
  93. 121 0
      GxPress/Api/GxPress.Api/AppControllers/WaitHandleController.cs
  94. 50 0
      GxPress/Api/GxPress.Api/GxPress.Api.csproj
  95. 30 0
      GxPress/Api/GxPress.Api/Program.cs
  96. 83 0
      GxPress/Api/GxPress.Api/ServiceExtensions/AuthenticationExtension.cs
  97. 22 0
      GxPress/Api/GxPress.Api/ServiceExtensions/AutoMapperExtension.cs
  98. 27 0
      GxPress/Api/GxPress.Api/ServiceExtensions/CachingExtension.cs
  99. 39 0
      GxPress/Api/GxPress.Api/ServiceExtensions/RepositoryExtension.cs
  100. 0 0
      GxPress/Api/GxPress.Api/ServiceExtensions/RuntimeHelper.cs

+ 263 - 0
.gitignore

@@ -0,0 +1,263 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+*.pubxml
+/GxPress/Api/GxPress.Api/wwwroot/cache
+/GxPress/Api/GxPress.Api/appsettings.json
+/GxPress/Api/GxPress.Api/appsettings.Development.json
+*.json

+ 8 - 0
GxPress/.vscode/solution-explorer/class.cs-template

@@ -0,0 +1,8 @@
+using System;
+
+namespace {{namespace}}
+{
+    public class {{name}}
+    {
+    }
+}

+ 3 - 0
GxPress/.vscode/solution-explorer/class.ts-template

@@ -0,0 +1,3 @@
+export class {{name}} {
+
+}

+ 9 - 0
GxPress/.vscode/solution-explorer/class.vb-template

@@ -0,0 +1,9 @@
+Imports System
+
+Namespace {{namespace}}
+
+    Public Class {{name}}
+    
+    End Class
+
+End Namespace

+ 3 - 0
GxPress/.vscode/solution-explorer/default.ts-template

@@ -0,0 +1,3 @@
+export default {{name}} {
+
+}

+ 8 - 0
GxPress/.vscode/solution-explorer/enum.cs-template

@@ -0,0 +1,8 @@
+using System;
+
+namespace {{namespace}}
+{
+    public enum {{name}}
+    {
+    }
+}

+ 8 - 0
GxPress/.vscode/solution-explorer/interface.cs-template

@@ -0,0 +1,8 @@
+using System;
+
+namespace {{namespace}}
+{
+    public interface {{name}}
+    {
+    }
+}

+ 3 - 0
GxPress/.vscode/solution-explorer/interface.ts-template

@@ -0,0 +1,3 @@
+export interface {{name}} {
+
+}

+ 17 - 0
GxPress/.vscode/solution-explorer/template-parameters.js

@@ -0,0 +1,17 @@
+var path = require("path");
+
+module.exports = function(filename, projectPath, folderPath) {
+    var namespace = "Unknown";
+    if (projectPath) {
+        namespace = path.basename(projectPath, path.extname(projectPath));
+        if (folderPath) {
+            namespace += "." + folderPath.replace(path.dirname(projectPath), "").substring(1).replace(/[\\\/]/g, ".");
+        }
+        namespace = namespace.replace(/[\\\-]/g, "_");
+    }       
+
+    return {
+        namespace: namespace,
+        name: path.basename(filename, path.extname(filename))
+    }
+};

+ 96 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminAppReportController.cs

@@ -0,0 +1,96 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper;
+using GxPress.Common.Tools;
+using GxPress.Entity;
+using GxPress.Repository.Interface.AppReport;
+using GxPress.Request.App.AppReport;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// App数据报表
+    /// </summary>
+    [Route("api/admin/app-report")]
+    [ApiController]
+    [Authorize]
+    public class AdminAppReportController : ControllerBase
+    {
+        private  readonly IAppReportRepository _appReportRepository;
+        private readonly IMapper _mapper;
+        public AdminAppReportController(IAppReportRepository appReportRepository,IMapper mapper)
+        {
+            _appReportRepository = appReportRepository;
+            _mapper = mapper;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<int> Insert(AppReportRequest request)
+        {
+            request.IocUrl = StringUtils.RemoveDomain(request.IocUrl);
+            var appReport = _mapper.Map<AppReport>(request);
+            return await _appReportRepository.InsertAsync(appReport);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update")]
+        public async Task<bool> Update(AppReportRequest request)
+        {
+            request.IocUrl = StringUtils.RemoveDomain(request.IocUrl);
+            var appReport = _mapper.Map<AppReport>(request);
+            return await _appReportRepository.UpdateAsync(appReport);
+        }
+
+        /// <summary>
+        /// 查询
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<Entity.AppReport>> GetAppReportList()
+        {
+            var result= await _appReportRepository.GetAppReportListAsync();
+            var appReportList = result as AppReport[] ?? result.ToArray();
+            foreach (var appReport in appReportList)
+            {
+                appReport.IocUrl = StringUtils.AddDomain(appReport.IocUrl);
+            }
+            
+            return appReportList;
+        }
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _appReportRepository.DeleteAsyncTask(id);
+        }
+
+        /// <summary>
+        /// 根据type查询数据
+        /// </summary>
+        /// <param name="reportType"></param>
+        /// <returns></returns>
+        [HttpGet("{reportType}")]
+        public async Task<Entity.AppReport> GetAppReport(int reportType)
+        {
+            var appReport = await _appReportRepository.GetAppReport(reportType);
+            appReport.IocUrl = StringUtils.AddDomain(appReport.IocUrl);
+            return appReport;
+        }
+    }
+}

+ 85 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminAppVersionController.cs

@@ -0,0 +1,85 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.AppVersion;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// APP版本管理
+    /// </summary>
+    [Route("api/admin/app-version")]
+    [ApiController]
+    [Authorize]
+    public class AdminAppVersionController : ControllerBase
+    {
+        private readonly ILogger<AdminAppVersionController> _logger;
+        private readonly IAppVersionRepository _appVersionRepository;
+
+        public AdminAppVersionController(ILogger<AdminAppVersionController> logger, IAppVersionRepository appVersionRepository)
+        {
+            _logger = logger;
+            _appVersionRepository = appVersionRepository;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request">参数</param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> InAppVersion([FromBody] AppVersionInRequest request)
+        {
+            var appVersion = new AppVersion { VersionType = request.VersionType, VersionNumber = request.VersionNumber, Describe = request.Describe, QrCodeUrl = request.QrCodeUrl };
+            return await _appVersionRepository.InsertAsync(appVersion) > 0;
+        }
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<AppVersion> Get(int id)
+        {
+            return await _appVersionRepository.GetAsync(id);
+        }
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody] AppVersion request)
+        {
+            request.Id = id;
+            return await _appVersionRepository.UpdateAsync(request);
+        }
+        /// <summary>
+        /// 查询
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<AppVersion>> GetAppVersionAll()
+        {
+            return await _appVersionRepository.GetAppVersionAsync();
+        }
+      
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        [AllowAnonymous]
+        public async Task<bool> Delete(int id)
+        {
+            return await _appVersionRepository.DeleteAsync(id);
+        }
+    }
+}

+ 118 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminArticleController.cs

@@ -0,0 +1,118 @@
+using System;
+using System.Threading.Tasks;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.Admin.Article;
+using GxPress.Request.Article;
+using GxPress.Request.ArticleAnalyze;
+using GxPress.Result.Article;
+using GxPress.Service.Interface.Article;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 审批文章
+    /// </summary>
+    [Route("api/admin/article")]
+    [ApiController]
+    [Authorize]
+    public class AdminArticleController : ControllerBase
+    {
+        private readonly IArticleRepository _articleRepository;
+        private readonly IArticleService _articleService;
+
+        public AdminArticleController(IArticleRepository articleRepository, IArticleService articleService)
+        {
+            _articleRepository = articleRepository;
+            _articleService = articleService;
+        }
+
+        /// <summary>
+        /// 添加文章
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<ArticleResult> Add([FromBody] ArticleAddRequest request)
+        {
+            if (!string.IsNullOrEmpty(request.Summary) && request.Summary.Length > 500)
+            {
+                throw new Exception("保存失败,字符数不能超出500");
+            }
+            return await _articleService.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 修改文章
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut]
+        public async Task<ArticleResult> Edit([FromBody] ArticleEditRequest request)
+        {
+            if (!string.IsNullOrEmpty(request.Summary) && request.Summary.Length > 500)
+            {
+                throw new Exception("保存失败,字符数不能超出500");
+            }
+            return await _articleService.EditAsync(request);
+        }
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("")]
+        [AllowAnonymous]
+        public async Task<PagedList<ArticleResult>> GetList([FromQuery] ArticleSearchRequest request)
+        {
+            var pagedList = await _articleRepository.GetListAsync(request.Keyword, request);
+            return pagedList;
+        }
+
+        /// <summary>
+        /// 文章
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        [AllowAnonymous]
+        public async Task<ArticleResult> Get(int id)
+        {
+            var article= await _articleService.GetAsync(id,0);
+            return  article;
+        }
+
+        /// <summary>
+        /// 删除文章
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _articleRepository.DeleteAsync(id);
+        }
+        ///// <summary>
+        /////  文章 点赞 收藏 转发
+        ///// </summary>
+        ///// <returns></returns>
+        //[HttpPost("analyze")]
+        //[AllowAnonymous]
+        //public async Task<bool> AddArticleAnalyze([FromBody] ArticleAnalyzeRequest request)
+        //{
+        //    return await _articleAnalyzeRepository.SetArticleAnalyzeAsync(request);
+        //}
+
+        /// <summary>
+        /// 克隆文章
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("clone")]
+        public async Task<bool> CloneArticle(CloneArticleRequest request)
+        { 
+            return await _articleRepository.CloneArticleAsync(request);
+        }
+    }
+}

+ 73 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminArticleGroupController.cs

@@ -0,0 +1,73 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.ArticleGroup;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 文章组
+    /// </summary>
+    [Route("api/admin/articleGroup")]
+    [ApiController]
+    [Authorize]
+    public class AdminArticleGroupController : Controller
+    {
+
+        private readonly IArticleGroupRepository _processGroupRepository;
+
+        public AdminArticleGroupController(IArticleGroupRepository processGroupRepository)
+        {
+            _processGroupRepository = processGroupRepository;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<ArticleGroup> Add([FromBody] ArticleGroupAddRequest request)
+        {
+            return await _processGroupRepository.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<IEnumerable<ArticleGroup>> GetList()
+        {
+            return await _processGroupRepository.GetListAsync(0);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody]ArticleGroupAddRequest request)
+        {
+            return await _processGroupRepository.UpdateAsync(id, request);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _processGroupRepository.DeleteAsync(id);
+        }
+
+
+    }
+}

+ 47 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminArticleLabelController.cs

@@ -0,0 +1,47 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using GxPress.Service.Interface.ArticleLabel;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using GxPress.Common.Exceptions;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// APP版本管理
+    /// </summary>
+    [Route("api/admin/article-label")]
+    [ApiController]
+    [Authorize]
+    public class AdminArticleLabelController : ControllerBase
+    {
+        private readonly IArticleLabelService _articleLabelService;
+        public AdminArticleLabelController(IArticleLabelService articleLabelService)
+        {
+            _articleLabelService = articleLabelService;
+        }
+        /// <summary>
+        /// 获取标签列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<IEnumerable<Entity.ArticleLabel.ArticleLabel>> GetArticleLabelsAsync()
+        {
+            return await _articleLabelService.GetArticleLabelsAsync();
+        }
+
+        /// <summary>
+        /// 添加标签
+        /// </summary>
+        /// <param name="labelName"></param>
+        /// <returns></returns>
+        [HttpGet("add/{labelName}")]
+        public async Task<int> InsertAsync(string labelName)
+        {
+            if (string.IsNullOrWhiteSpace(labelName))
+                throw new BusinessException("标签名称不能为空!");
+            labelName = labelName.Trim();
+            return await _articleLabelService.InsertAsync(labelName);
+        }
+    }
+}

+ 47 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminCaptchaController.cs

@@ -0,0 +1,47 @@
+using System;
+using System.Threading.Tasks;
+using GxPress.Common.Tools;
+using GxPress.Result.Captcha;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Distributed;
+using GxPress.Common.Extensions;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 验证码
+    /// </summary>
+    [Route("api/admin/captcha")]
+    [ApiController]
+    public class AdminCaptchaController : ControllerBase
+    {
+        //验证码过期时间
+        private readonly IDistributedCache _cache;
+
+        public AdminCaptchaController(IDistributedCache cache) {
+            _cache = cache;
+        }
+
+        /// <summary>
+        /// 获取验证码图片和Guid
+        /// </summary>
+        [HttpGet("image")]
+        public async Task<CaptchaResult> GetCaptchaImage()
+        {
+            await using var ms = CaptchaHelper.Create(out var code);
+            var guid = Guid.NewGuid();
+            //将Guid和验证码值存入redis
+
+            await _cache.SetAsync($"captcha:{guid.ToString()}", code, new DistributedCacheEntryOptions
+            {
+                AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300)
+            });
+            var result = new CaptchaResult
+            {
+                CaptchaImg = Convert.ToBase64String(ms.ToArray()),
+                CaptchaGuid = guid
+            };
+            return result;
+        }
+    }
+}

+ 116 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminCarController.cs

@@ -0,0 +1,116 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity.WorkCar;
+using GxPress.Repository.Interface.WorkCar;
+using GxPress.Request.App.WorkCar;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 会议
+    /// </summary>
+    [Route("api/admin/car")]
+    [ApiController]
+    [Authorize]
+    public class AdminCarController : ControllerBase
+    {
+        private readonly ICarTypeRepository _carTypeRepository;
+        private readonly ICarOrderRepository _carOrderRepository;
+        private readonly ICarRepository _carRepository;
+
+        public AdminCarController(ICarTypeRepository carTypeRepository, ICarOrderRepository carOrderRepository, ICarRepository carRepository)
+        {
+            _carTypeRepository = carTypeRepository;
+            _carOrderRepository = carOrderRepository;
+            _carRepository = carRepository;
+        }
+
+        /// <summary>
+        /// 新增车辆类型
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("type")]
+        public async Task<CarType> TypeAdd([FromBody] CarType request)
+        {
+            request.Id = await _carTypeRepository.InsertAsync(request);
+            return request;
+        }
+
+        /// <summary>
+        /// 修改车辆类型
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("type")]
+        public async Task TypeEdit([FromBody] CarType request)
+        {
+            await _carTypeRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 获取车辆类型列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("type")]
+        public async Task<IEnumerable<CarType>> TypeList()
+        {
+            return await _carTypeRepository.GetListAsync();
+        }
+
+        /// <summary>
+        /// 删除车辆类型
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("type/{id}")]
+        public async Task<bool> TypeRemove([FromRoute]int id)
+        {
+            return await _carTypeRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 新增车辆
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("")]
+        public async Task<Car> CarAdd([FromBody] Car request)
+        {
+            request.Id = await _carRepository.InsertAsync(request);
+            return request;
+        }
+
+        /// <summary>
+        /// 修改车辆
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("")]
+        public async Task CarEdit([FromBody] Car request)
+        {
+            await _carRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 获取车辆列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("")]
+        public async Task<IEnumerable<Car>> CarList([FromQuery] CarRequest request)
+        {
+            return await _carRepository.GetListAsync(request.TypeId);
+        }
+
+        /// <summary>
+        /// 删除车辆
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> CarRemove([FromRoute]int id)
+        {
+            return await _carRepository.DeleteAsync(id);
+        }
+    }
+}

+ 47 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminCommentController.cs

@@ -0,0 +1,47 @@
+using System.Threading.Tasks;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.Comment;
+using GxPress.Result.Comment;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 文章评论 通知评论
+    /// </summary>
+    [Route("api/admin/comment")]
+    [ApiController]
+    public class AdminCommentController : ControllerBase
+    {
+        private readonly ICommentRepository _commentRepository;
+        public AdminCommentController(ICommentRepository commentRepository)
+        {
+            _commentRepository = commentRepository;
+        }
+
+       
+        /// <summary>
+        /// 分页显示数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        public async Task<PagedList<CommentPageResult>> GetPagedList([FromBody] CommentSearchPageRequest request)
+        {
+            return await _commentRepository.GetPagedList(request);
+        }
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpDelete("delete")]
+        [AllowAnonymous]
+        public async Task<bool> Delete([FromBody] CommentDeleteRequest request)
+        {
+            return await _commentRepository.DeleteCommentAsync(request);
+        }
+    }
+}

+ 143 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminController.cs

@@ -0,0 +1,143 @@
+using System.Security.Claims;
+using System.Threading.Tasks;
+using GxPress.Api.Tools;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.EnumConst;
+using GxPress.Repository.Interface;
+using GxPress.Request.Admin;
+using GxPress.Result.Admin;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 管理员
+    /// </summary>
+    [Route("api/admin/admin")]
+    [ApiController]
+    [Authorize(Roles = Roles.Admin)]
+    public class AdminController : ControllerBase
+    {
+        private readonly JwtOptions _jwtOptions;
+        private readonly ILogger<AdminController> _logger;
+        private readonly IAdminRepository _adminRepository;
+
+        public AdminController(IOptions<JwtOptions> jwtOptions, ILogger<AdminController> logger, IAdminRepository adminRepository)
+        {
+            _jwtOptions = jwtOptions.Value;
+            _logger = logger;
+            _adminRepository = adminRepository;
+        }
+
+        /// <summary>
+        /// 登录
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("signin")]
+        [AllowAnonymous]
+        public async Task<AdminSignInResult> SignIn(AdminSignInRequest request)
+        {
+            var result = await _adminRepository.SignInAsync(request);
+            var claims = new[]
+            {
+                new Claim(ClaimTypes.NameIdentifier,result.AdminId.ToString()),
+                new Claim(ClaimTypes.Role,AccountTypeConst.Admin.ToString())
+            };
+            result.Token = TokenHelper.BuildToken(_jwtOptions, claims);
+            _logger.LogInformation("admin token:{token}", result.Token);
+            return result;
+        }
+
+        /// <summary>
+        /// 注册
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("signup")]
+        public async Task<int> SignUp([FromBody]AdminSignUpRequest request)
+        {
+            return await _adminRepository.SignUpAsync(request);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _adminRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<AdminDetailResult> Get(int id)
+        {
+            return await _adminRepository.GetDetailAsync(id);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody] Admin request)
+        {
+            return await _adminRepository.UpdateAsync(id, request);
+        }
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("updatemenu")]
+        public async Task<bool> UpdateMenu( [FromBody] Admin request)
+        {
+            return await _adminRepository.UpdateQAsync(request);
+        }
+        /// <summary>
+        /// 分页列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        public async Task<PagedList<AdminPageResult>> GetPagedList([FromBody]AdminPageSearchRequest request)
+        {
+            return await _adminRepository.GetPagedList(request);
+        }
+
+        /// <summary>
+        /// 修改密码
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("updatepassword")]
+        public async Task<bool> UpdatePassWord([FromBody] AdminUpdatePassWordRequest request)
+        {
+            return await _adminRepository.UpdatePassWord(request);
+        }
+        /// <summary>
+        /// 修改密码
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("admin-update-password")]
+        public async Task<bool> AdminUpdatePassWord([FromBody] AdminUpdatePassWordRequest request)
+        {
+            return await _adminRepository.AdminUpdatePassWord(request);
+        }
+    }
+}

+ 86 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminDepartmentController.cs

@@ -0,0 +1,86 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Result.Department;
+using GxPress.Service.Interface.Department;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 部门
+    /// </summary>
+    [Route("api/admin/department")]
+    [ApiController]
+    [Authorize]
+    public class AdminDepartmentController : ControllerBase
+    {
+        private readonly IDepartmentRepository _departmentRepository;
+        private readonly IDepartmentService _departmentService;
+        public AdminDepartmentController(IDepartmentRepository departmentRepository,IDepartmentService departmentService)
+        {
+            _departmentRepository = departmentRepository;
+            _departmentService = departmentService;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<Department> Add([FromBody]Department request)
+        {
+            return await _departmentRepository.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<Department> GetDetail(int id)
+        {
+            return await _departmentRepository.GetAsync(id);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _departmentService.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody] Department request)
+        {
+            return await _departmentRepository.UpdateAsync(id, request);
+        }
+
+        /// <summary>
+        /// 树形结构展示,懒加载
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("tree")]
+        public async Task<List<DepartmentTreeResult>> GetTree(int id = 0)
+        {
+            return await _departmentRepository.GetTreeAsync(id);
+        }
+       
+    }
+}

+ 51 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminFeedbackController.cs

@@ -0,0 +1,51 @@
+using System.Threading.Tasks;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Feedback;
+using GxPress.Result.Feedback;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 意见反馈
+    /// </summary>
+    [Route("api/admin/Feedback")]
+    [ApiController]
+    [Authorize]
+    public class AdminFeedbackController : ControllerBase
+    {
+        private readonly ILogger<AdminAppVersionController> _logger;
+        private readonly IFeedbackRepository _feedbackRepository;
+
+        public AdminFeedbackController(ILogger<AdminAppVersionController> logger, IFeedbackRepository feedbackRepository)
+        {
+            _logger = logger;
+            _feedbackRepository = feedbackRepository;
+        }
+
+        /// <summary>
+        /// 查询分页数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        public async Task<PagedList<FeedbackPageResult>> GetPageList([FromBody] FeedbackPageRequest request)
+        {
+            return await _feedbackRepository.GetPagedList(request);
+        }
+        /// <summary>
+        /// 删除意见反馈
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _feedbackRepository.DeleteAsync(id);
+        }
+    }
+}

+ 80 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminFileController.cs

@@ -0,0 +1,80 @@
+using System.IO;
+using System.Threading.Tasks;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Tools;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 文件管理
+    /// </summary>
+    [Route("api/admin/file")]
+    [ApiController]
+    public class AdminFileController : ControllerBase
+    {
+        private readonly IWebHostEnvironment _environment;
+
+        public AdminFileController(IWebHostEnvironment environment)
+        {
+            _environment = environment;
+        }
+
+        /// <summary>
+        /// 上传
+        /// </summary>
+        /// <param name="file"></param>
+        /// <returns></returns>
+        [HttpPost("upload")]
+        public async Task<ResultPath> Upload(IFormFile file)
+        {
+            if (file == null) throw new BusinessException("请选择需要上传的文件");
+
+            byte[] bytes;
+            await using (var ms = new MemoryStream())
+            {
+                file.CopyTo(ms);
+                bytes = ms.ToArray();
+            }
+
+            var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), file.FileName,
+                bytes);
+            saveResult.AbsolutePath = Request.Scheme + "://" + Request.Host.Host +
+                                      (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
+                                      saveResult.RelativePath;
+            return saveResult;
+        }
+
+        //上传文件到本地缓存文件夹,返回一个预览地址
+        //真正提交的时候把缓存文件异步保存到七牛云
+
+        //下载,从七牛云下载文件?
+        /// <summary>
+        /// 上传用户Excel
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("upload-user-excel")]
+        public async Task<ResultPath> UploadUserExcel(IFormFile file)
+        {
+
+            if (file == null) throw new BusinessException("请选择需要上传的文件");
+            byte[] bytes;
+            await using (var ms = new MemoryStream())
+            {
+                file.CopyTo(ms);
+                bytes = ms.ToArray();
+            }
+
+            var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), file.FileName,
+                bytes);
+            saveResult.AbsolutePath = Request.Scheme + "://" + Request.Host.Host +
+                                      (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
+                                      saveResult.RelativePath;
+            
+
+            return saveResult;
+        }
+    }
+}

+ 106 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminFinanceController.cs

@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ExcelDataReader;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Finance;
+using GxPress.Request.User;
+using GxPress.Result.Finance;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 财务数据
+    /// </summary>
+    [Route("api/admin/finance")]
+    [ApiController]
+    [Authorize]
+    public class AdminFinanceController : ControllerBase
+    {
+        private readonly ILogger<AdminFinanceController> _logger;
+        private readonly IFinanceRepository _repository;
+
+        public AdminFinanceController(ILogger<AdminFinanceController> logger, IFinanceRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+
+        /// <summary>
+        /// 解析财务数据Excel数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload")]
+        public async Task<bool> FinanceExcelUpload([FromBody] UserExcelUploadRequest request)
+        {
+            var relativePath = request.ExcelUrl;
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+            //获取excel分析
+            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
+            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
+            var result = reader.AsDataSet();
+            var sheet = result.Tables["Sheet1"];
+            var error = string.Empty;
+            var listFinance = new List<Finance>();
+            for (int i = 1; i < sheet.Rows.Count; i++) //行
+            {
+                var finance = new Finance();
+                if (i == 1)
+                    continue;
+                var amount = sheet.Rows[i][0].ToString().Trim(); //金额
+                if (string.IsNullOrEmpty(amount))
+                    error = "金额必填";
+                finance.Amount = int.Parse(amount);
+                var financeType = sheet.Rows[i][1].ToString().Trim(); //类型
+                if (string.IsNullOrEmpty(financeType))
+                    error = "类型必须";
+                finance.FinanceType = int.Parse(financeType);
+                var enteringDateTime = sheet.Rows[i][2].ToString().Trim(); //录入时间
+                if (string.IsNullOrEmpty(enteringDateTime))
+                    error = "录入时间必填";
+                finance.EnteringDateTime = DateTime.Parse(enteringDateTime);
+                if (!string.IsNullOrEmpty(error))
+                    break;
+                listFinance.Add(finance);
+            }
+
+            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
+            //计算
+            var success = await _repository.InsertAsync(listFinance);
+            if (success == false)
+                throw new BusinessException("服务器异常");
+            return true;
+        }
+        /// <summary>
+        /// 财务列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<Finance>> GetPagedList(PageParameter request)
+        {
+            return await _repository.GetPageListAsync(request);
+        }
+        /// <summary>
+        /// 财务图表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        public async Task<FinanceResult> GetFinanceChart(FinanceRequest request)
+        {
+            return await _repository.GetFinanceChartAsync(request);
+        }
+    }
+}

+ 87 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminFlowController.Actions.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Datory;
+using GxPress.Common.Tools;
+using GxPress.Entity.WorkFlow;
+using GxPress.Entity.WorkFlowDto;
+using GxPress.Entity.WorkProcessDto;
+using GxPress.EnumConst;
+using GxPress.Result;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    public partial class AdminFlowController
+    {
+        /// <summary>
+        /// 动作 - 审批
+        /// </summary>
+        /// <param name="request">审批意见</param>
+        /// <returns></returns>
+        [HttpPost("action/check")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsCheck([FromBody] CheckRequest request)
+        {
+            await _flowService.CheckAsync(request.TodoId, request.IsChecked, request.Message);
+
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 下载
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/download")]
+        [AllowAnonymous]
+        public async Task<DefaultStringResult> ActionsDownload([FromBody] ActionRequest request)
+        {
+            var url = await docService.MakeDoc(request.FlowId, _loginContext.AccountId);
+            var result = new DownloadResult
+            {
+                DownloadUrl = StringUtils.AddDomain(url),
+                PreviewUrl = StringUtils.GetPreviewDocUrl(url)
+            };
+            return new DefaultStringResult
+            {
+                Value = result.DownloadUrl
+            };
+        }
+        /// <summary>
+        /// 动作 - 催办
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/remind")]
+        [AllowAnonymous]
+        public DefaultResult ActionsRemind([FromBody] ActionRequest request)
+        {
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 上会
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/meeting")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsMeeting([FromBody] ActionRequest request)
+        {
+            //await _flowRepository.UpdateStateAsync(request.FlowId, nameof(FlowState.Meeting));
+            await _flowTodoRepository.UpdateAsync(Q.Where(nameof(Entity.WorkFlow.FlowTodo.FlowId), request.FlowId).Where(nameof(Entity.WorkFlow.FlowTodo.UserId), _loginContext.AccountId).Set(nameof(Entity.WorkFlow.FlowTodo.IsDone), true).Set(nameof(Entity.WorkFlow.FlowTodo.DoneType), 3));
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+    }
+}

+ 146 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminFlowController.Dto.cs

@@ -0,0 +1,146 @@
+using System.Collections.Generic;
+using GxPress.Entity.WorkFlow;
+
+namespace GxPress.Api.AdminControllers
+{
+    public partial class AdminFlowController
+    {
+        public class ListRequest
+        {
+            /// <summary>
+            /// 审批类型
+            /// </summary>
+            public int ProcessId { get; set; }
+
+            /// <summary>
+            /// 状态
+            /// </summary>
+            public string State { get; set; }
+
+            /// <summary>
+            /// 提交时间
+            /// </summary>
+            public string StartDate { get; set; }
+
+            /// <summary>
+            /// 完成时间
+            /// </summary>
+            public string EndDate { get; set; }
+
+            /// <summary>
+            /// 关键词
+            /// </summary>
+            public string Keyword { get; set; }
+
+            /// <summary>
+            /// 当前页
+            /// </summary>
+            public int Page { get; set; }
+
+            /// <summary>
+            /// 每页显示多少项
+            /// </summary>
+            public int PerPage { get; set; }
+        }
+
+        public class TodoListResult
+        {
+            /// <summary>
+            /// 当前页
+            /// </summary>
+            public int Count { get; set; }
+
+            /// <summary>
+            /// 每页显示多少项
+            /// </summary>
+            public IEnumerable<FlowTodoResult> Items { get; set; }
+        }
+
+        public class GetCountResult
+        {
+            /// <summary>
+            /// 我审批的 - 待审批
+            /// </summary>
+            public int MyCheckingCount { get; set; }
+
+            /// <summary>
+            /// 我审批的 - 已审批
+            /// </summary>
+            public int MyCheckedCount { get; set; }
+
+            /// <summary>
+            /// 我发起的
+            /// </summary>
+            public int SubmittedCount { get; set; }
+
+            /// <summary>
+            /// 抄送我的 - 未读
+            /// </summary>
+            public int CcUnreadCount { get; set; }
+
+            /// <summary>
+            /// 抄送我的 - 全部
+            /// </summary>
+            public int CcAllCount { get; set; }
+        }
+
+        public class FlowTodoResult : FlowTodo
+        {
+            public string State { get; set; }
+            /// <summary>
+            /// 当前页
+            /// </summary>
+            public string Title { get; set; }
+
+            public string AvatarUrl { get; set; }
+
+            /// <summary>
+            /// 每页显示多少项
+            /// </summary>
+            public List<string> Summaries { get; set; }
+        }
+
+        public class CheckRequest
+        {
+            /// <summary>
+            /// 工作流Id
+            /// </summary>
+            public int FlowId { get; set; }
+
+            /// <summary>
+            /// 待办Id
+            /// </summary>
+            public int TodoId { get; set; }
+
+            /// <summary>
+            /// 是否审核通过
+            /// </summary>
+            public bool IsChecked { get; set; }
+
+            /// <summary>
+            /// 留言
+            /// </summary>
+            public string Message { get; set; }
+        }
+
+        public class ActionRequest
+        {
+            /// <summary>
+            /// 工作流Id
+            /// </summary>
+            public int FlowId { get; set; }
+        }
+        public class DownloadResult
+        {
+            /// <summary>
+            /// 下载地址
+            /// </summary>
+            public string DownloadUrl { get; set; }
+
+            /// <summary>
+            /// 预览
+            /// </summary>
+            public string PreviewUrl { get; set; }
+        }
+    }
+}

+ 105 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminFlowController.cs

@@ -0,0 +1,105 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Repository.Interface.WorkFlow;
+using GxPress.Repository.Interface.WorkProcess;
+using GxPress.Result.App;
+using GxPress.Result.App.Flow;
+using GxPress.Service.Interface;
+using GxPress.Service.Interface.Doc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 通讯录用户信息
+    /// </summary>
+    [Route("api/admin/flow")]
+    [ApiController]
+    [Authorize]
+    public partial class AdminFlowController : ControllerBase
+    {
+        private readonly ILogger<AppControllers.AppVersionController> _logger;
+        private readonly ILoginContext _loginContext;
+        private readonly IProcessGroupRepository _processGroupRepository;
+        private readonly IProcessRepository _processRepository;
+        private readonly IProcessService _processService;
+        private readonly IFlowService _flowService;
+        private readonly IUserRepository _userRepository;
+        private readonly IDepartmentRepository _departmentRepository;
+        private readonly IFlowTodoRepository _flowTodoRepository;
+        private readonly IFlowRepository _flowRepository;
+        private readonly IDocService docService;
+
+        public AdminFlowController(ILogger<AppControllers.AppVersionController> logger, ILoginContext loginContext, IProcessService processService, IFlowService flowService, IUserRepository userRepository, IDepartmentRepository departmentRepository, IProcessGroupRepository processGroupRepository, IProcessRepository processRepository, IFlowTodoRepository flowTodoRepository, IFlowRepository flowRepository, IDocService docService)
+        {
+            _logger = logger;
+            _loginContext = loginContext;
+            _processService = processService;
+            _flowService = flowService;
+            _userRepository = userRepository;
+            _departmentRepository = departmentRepository;
+            _processGroupRepository = processGroupRepository;
+            _processRepository = processRepository;
+            _flowTodoRepository = flowTodoRepository;
+            _flowRepository = flowRepository;
+            this.docService = docService;
+        }
+
+        /// <summary>
+        /// 获取详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        [AllowAnonymous]
+        public async Task<FlowResult> Get(int id)
+        {
+            return await _flowService.GetFlowResult(id);
+        }
+
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<List<Option>> List()
+        {
+            var options = new List<Option>();
+
+            var groups = await _processGroupRepository.GetListAsync();
+            foreach (var processGroup in groups)
+            {
+                var children = new List<Option>();
+                var processes = await _processRepository.GetListByGroupIdAsync(processGroup.Id);
+                foreach (var process in processes)
+                {
+                    children.Add(new Option
+                    {
+                        Label = process.Name,
+                        Value = process.Id
+                    });
+                }
+                options.Add(new Option
+                {
+                    Label = processGroup.Name,
+                    Value = 0,
+                    Options = children
+                });
+            }
+
+            return options;
+        }
+
+        /// <summary>
+        /// 获取工作项
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task<ListResult> List([FromBody] ListRequest request)
+        {
+            return await _flowService.ListAllAsync(request.Page, request.PerPage, request.ProcessId, request.State, request.StartDate, request.EndDate);
+        }
+    }
+}

+ 113 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminHumanAffairsController.cs

@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ExcelDataReader;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.HumanAffairs;
+using GxPress.Request.User;
+using GxPress.Result.HumanAffairs;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 人事数据
+    /// </summary>
+    [Route("api/admin/human-affairs")]
+    [ApiController]
+    [Authorize]
+    public class AdminHumanAffairsController : ControllerBase
+    {
+        private readonly ILogger<AdminHumanAffairsController> _logger;
+        private readonly IHumanAffairsRepository _repository;
+
+        public AdminHumanAffairsController(ILogger<AdminHumanAffairsController> logger, IHumanAffairsRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+
+        /// <summary>
+        ///  导入人事数据Excel数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload")]
+        public async Task<bool> FinanceExcelUpload([FromBody] UserExcelUploadRequest request)
+        {
+            var relativePath = request.ExcelUrl;
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+            //获取excel分析
+            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
+            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
+            var result = reader.AsDataSet();
+            var sheet = result.Tables["Sheet1"];
+            var error = string.Empty;
+            var listHumanAffairs = new List<HumanAffairs>();
+            for (int i = 1; i < sheet.Rows.Count; i++) //行
+            {
+                var humanAffairs = new HumanAffairs();
+                if (i == 1)
+                    continue;
+                var numberPeople = sheet.Rows[i][0].ToString().Trim(); //人数
+                if (string.IsNullOrEmpty(numberPeople))
+                    error = "入职/离职人数";
+                humanAffairs.NumberPeople = int.Parse(numberPeople);
+
+                var salary = sheet.Rows[i][1].ToString().Trim(); //工资
+                if (string.IsNullOrEmpty(salary))
+                    error = "入职/离职工资元";
+                humanAffairs.Salary = int.Parse(salary);
+
+                var humanAffairsType = sheet.Rows[i][2].ToString().Trim(); //工资
+                if (string.IsNullOrEmpty(humanAffairsType))
+                    error = "类型:1:入职 2:离职";
+                humanAffairs.HumanAffairsType = int.Parse(humanAffairsType);
+
+                var enteringDateTime = sheet.Rows[i][3].ToString().Trim(); //录入时间
+                if (string.IsNullOrEmpty(enteringDateTime))
+                    error = "录入时间必填";
+                humanAffairs.EnteringDateTime = DateTime.Parse(enteringDateTime);
+                if (!string.IsNullOrEmpty(error))
+                    break;
+                listHumanAffairs.Add(humanAffairs);
+            }
+
+            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
+            //计算
+            var success = await _repository.InsertAsync(listHumanAffairs);
+            if (success == false)
+                throw new BusinessException("服务器异常");
+            return true;
+        }
+        /// <summary>
+        /// 人事数据列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<HumanAffairs>> GetPagedList(PageParameter request)
+        {
+            return await _repository.GetPageListAsync(request);
+        }
+        /// <summary>
+        /// 人事图像
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        public async Task<HumanAffairsResult> GetHumanAffairsChart(HumanAffairsRequest request)
+        {
+            return await _repository.GetHumanAffairsChartAsync(request);
+        }
+    }
+}

+ 53 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminJobController.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Threading.Tasks;
+using GxPress.Api.Tools;
+using GxPress.Service.Interface.ElasticSearch;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Quartz;
+
+namespace GxPress.Api.AdminControllers
+{
+    [Route("api/admin/job")]
+    [ApiController]
+    [Authorize]
+    public class AdminJobController : ControllerBase
+    {
+        private readonly ISchedulerFactory _schedulerFactory;
+
+        private readonly IServiceProvider _serviceProvider;
+        private IScheduler _scheduler;
+        private readonly IElasticSearchService _elasticSearchService;
+        public AdminJobController(ISchedulerFactory schedulerFactory, IElasticSearchService elasticSearchService, IServiceProvider serviceProvider)
+        {
+            this._schedulerFactory = schedulerFactory;
+            _elasticSearchService = elasticSearchService;
+            _serviceProvider = serviceProvider;
+        }
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<bool> Get()
+        {
+            //1、通过调度工厂获得调度器
+            _scheduler = await _schedulerFactory.GetScheduler();
+            //2、开启调度器
+            await _scheduler.Start();
+            //3、创建一个触发器
+            var trigger = TriggerBuilder.Create()
+                            .WithSimpleSchedule(x => x.WithIntervalInSeconds(60).RepeatForever())//每10秒执行一次
+                            .Build();
+            //构建工厂 构造函数
+            _scheduler.JobFactory = new JobFactory(_serviceProvider, _elasticSearchService);
+            // await _scheduler.ScheduleJob(trigger);
+            //4、创建任务
+            var jobDetail = JobBuilder.Create<MyJob>()
+                            .WithIdentity("job1", "group1")
+                            .Build();
+            //5、将触发器和任务器绑定到调度器中
+            await _scheduler.ScheduleJob(jobDetail, trigger);
+            //await _scheduler.Start();
+            //await _scheduler.Shutdown();
+            return true;
+        }
+    }
+}

+ 120 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminMeetingController.cs

@@ -0,0 +1,120 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity.WorkMeeting;
+using GxPress.Repository.Interface.WorkMeeting;
+using GxPress.Request.Admin.WorkMeeting;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 会议
+    /// </summary>
+    [Route("api/admin/meeting")]
+    [ApiController]
+    [Authorize]
+    public class AdminMeetingController : ControllerBase
+    {
+        private readonly IMeetingLocationRepository _meetingLocationRepository;
+        private readonly IMeetingOrderRepository _meetingOrderRepository;
+        private readonly IMeetingRepository _meetingRepository;
+        private readonly IMeetingRoomRepository _meetingRoomRepository;
+        private readonly IMeetingSummaryRepository _meetingSummaryRepository;
+
+        public AdminMeetingController(IMeetingLocationRepository meetingLocationRepository, IMeetingOrderRepository meetingOrderRepository, IMeetingRepository meetingRepository, IMeetingRoomRepository meetingRoomRepository, IMeetingSummaryRepository meetingSummaryRepository)
+        {
+            _meetingLocationRepository = meetingLocationRepository;
+            _meetingOrderRepository = meetingOrderRepository;
+            _meetingRepository = meetingRepository;
+            _meetingRoomRepository = meetingRoomRepository;
+            _meetingSummaryRepository = meetingSummaryRepository;
+        }
+
+        /// <summary>
+        /// 新增会议地点
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("location")]
+        public async Task<MeetingLocation> LocationAdd([FromBody] MeetingLocation request)
+        {
+            request.Id = await _meetingLocationRepository.InsertAsync(request);
+            return request;
+        }
+
+        /// <summary>
+        /// 修改会议地点
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("location")]
+        public async Task LocationEdit([FromBody] MeetingLocation request)
+        {
+            await _meetingLocationRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 获取会议地点列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("location")]
+        public async Task<IEnumerable<MeetingLocation>> LocationList()
+        {
+            return await _meetingLocationRepository.GetListAsync();
+        }
+
+        /// <summary>
+        /// 删除会议地点
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("location/{id}")]
+        public async Task<bool> LocationRemove([FromRoute]int id)
+        {
+            return await _meetingLocationRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 新增会议室
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("room")]
+        public async Task<MeetingRoom> RoomAdd([FromBody] MeetingRoom request)
+        {
+            request.Id = await _meetingRoomRepository.InsertAsync(request);
+            return request;
+        }
+
+        /// <summary>
+        /// 修改会议室
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("room")]
+        public async Task RoomEdit([FromBody] MeetingRoom request)
+        {
+            await _meetingRoomRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 获取会议地点列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("room")]
+        public async Task<IEnumerable<MeetingRoom>> RoomList([FromQuery] MeetingRoomRequest request)
+        {
+            return await _meetingRoomRepository.GetListAsync(request.LocationId);
+        }
+
+        /// <summary>
+        /// 删除会议地点
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("room/{id}")]
+        public async Task<bool> RoomRemove([FromRoute]int id)
+        {
+            return await _meetingRoomRepository.DeleteAsync(id);
+        }
+    }
+}

+ 75 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminNoticeController.cs

@@ -0,0 +1,75 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Notice;
+using GxPress.Result.Notice;
+using GxPress.Service.Interface.Notice;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 通知
+    /// </summary>
+    [Route("api/admin/notice")]
+    [ApiController]
+    [Authorize]
+    public class AdminNoticeController : ControllerBase
+    {
+        private readonly INoticeRepository _noticeRepository;
+
+        private readonly INoticeService _noticeServivce;
+        public AdminNoticeController(INoticeRepository noticeRepository,ILoginContext loginContext,INoticeService noticeService)
+        {
+            _noticeRepository = noticeRepository;
+            _noticeServivce=noticeService;
+        }
+
+        /// <summary>
+        /// 查询
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<NoticeListPageResult>> GetNoticeByUserId(NoticePageSearchRequest request)
+        {
+            return await _noticeRepository.GetAdminNoticeByUserIdAsync(request);
+        }
+
+        /// <summary>
+        /// 管理员删除通知
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> AdminDelete(int id)
+        {
+            return await _noticeRepository.AdminDeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 获取通知详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("detail/{id}")]
+        public async Task<Result.Notice.NoticeDetailResult> GetNoticeDetailResult(int id)
+        {
+            return await _noticeServivce.GetNoticeDetailResultAsync(id,0);
+        }
+        /// <summary>
+        ///  修改通知
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> UpdateNoticeAsync(int id,[FromBody] Notice request)
+        {
+            return await _noticeRepository.UpdateNoticeAsync(request);
+        }
+    }
+}

+ 108 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminPrintController.cs

@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using ExcelDataReader;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Print;
+using GxPress.Request.User;
+using GxPress.Result.Print;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 出版数据
+    /// </summary>
+    [Route("api/admin/print")]
+    [ApiController]
+    [Authorize]
+    public class AdminPrintController : ControllerBase
+    {
+        private readonly ILogger<AdminPrintController> _logger;
+        private readonly IPrintRepository _repository;
+
+        public AdminPrintController(ILogger<AdminPrintController> logger, IPrintRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+
+        /// <summary>
+        /// 导入出版Excel数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload")]
+        public async Task<bool> PrintExcelUpload([FromBody] UserExcelUploadRequest request)
+        {
+            var relativePath = request.ExcelUrl;
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+            //获取excel分析
+            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
+            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
+            var result = reader.AsDataSet();
+            var sheet = result.Tables["Sheet1"];
+            var error = string.Empty;
+            var listPrint = new List<Print>();
+            for (int i = 1; i < sheet.Rows.Count; i++) //行
+            {
+                var print = new Print();
+                if (i == 1)
+                    continue;
+                var amount = sheet.Rows[i][0].ToString().Trim(); //出版金额
+                if (string.IsNullOrEmpty(amount))
+                    error = "出版金额";
+                print.PublishAmount = int.Parse(amount);
+                var volumeCount = sheet.Rows[i][1].ToString().Trim(); //出版册数
+                if (string.IsNullOrEmpty(volumeCount))
+                    error = "出版册数";
+                print.VolumeCount = int.Parse(volumeCount);
+                var printAmount = sheet.Rows[i][2].ToString().Trim(); //印刷金额
+                if (string.IsNullOrEmpty(printAmount))
+                    error = "印刷金额";
+                print.PrintAmount = int.Parse(printAmount);
+                var enteringDateTime = sheet.Rows[i][3].ToString().Trim(); //录入时间
+                if (string.IsNullOrEmpty(enteringDateTime))
+                    error = "录入时间必填";
+                print.EnteringDateTime = DateTime.Parse(enteringDateTime);
+                if (!string.IsNullOrEmpty(error))
+                    break;
+                listPrint.Add(print);
+            }
+
+            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
+            //计算
+            var success = await _repository.InsertAsync(listPrint);
+            if (success == false)
+                throw new BusinessException("服务器异常");
+            return true;
+        }
+        /// <summary>
+        /// 出版数据列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<Print>> GetPagedList(PageParameter request)
+        {
+            return await _repository.GetPageListAsync(request);
+        }
+        /// <summary>
+        /// 发行图表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        public async Task<PrintResult> GetSellChart(PrintRequest request)
+        {
+            return await _repository.GetPrintChartAsync(request);
+        }
+    }
+}

+ 18 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminProcessController.Dto.cs

@@ -0,0 +1,18 @@
+namespace GxPress.Api.AdminControllers
+{
+    public partial class AdminProcessController
+    {
+        public class CloneRequest
+        {
+            /// <summary>
+            /// 流程Id
+            /// </summary>
+            public int ProcessId { get; set; }
+
+            /// <summary>
+            /// 流程名称
+            /// </summary>
+            public string Name { get; set; }
+        }
+    }
+}

+ 138 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminProcessController.cs

@@ -0,0 +1,138 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using AutoMapper;
+using GxPress.Entity.WorkProcess;
+using GxPress.Entity.WorkProcessDto;
+using GxPress.Repository.Interface.WorkProcess;
+using GxPress.Service.Interface;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 审批流程
+    /// </summary>
+    [Route("api/admin/process")]
+    [ApiController]
+    [Authorize]
+    public partial class AdminProcessController : ControllerBase
+    {
+        private readonly IProcessRepository _processRepository;
+        private readonly IProcessService _processService;
+
+        public AdminProcessController(IProcessRepository processRepository, IProcessService processService)
+        {
+            _processRepository = processRepository;
+            _processService = processService;
+        }
+
+        /// <summary>
+        /// 获取流程定义
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        [AllowAnonymous]
+        public async Task<ProcessDto> Get(int id)
+        {
+            return await _processService.GetAsync(id);
+        }
+
+        /// <summary>
+        /// 添加流程定义
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task<Process> Add([FromBody] ProcessDto request)
+        {
+            return await _processService.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 编辑流程定义
+        /// </summary>
+        /// <param name="id">流程Id</param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("{id}")]
+        [AllowAnonymous]
+        public async Task<Process> Edit([FromRoute] int id, [FromBody] ProcessDto request)
+        {
+            request.Id = id;
+            return await _processService.EditAsync(request);
+        }
+
+        //获取流程定义,分步获取
+
+        ///// <summary>
+        ///// 获取流程基本设置
+        ///// </summary>
+        ///// <param name="id"></param>
+        ///// <returns></returns>
+        //[HttpGet("baseInfo")]
+        //public async Task<ProcessBaseInfoResult> GetBaseInfo(int id)
+        //{
+        //    return await _processRepository.GetBaseInfoAsync(id);
+        //}
+
+        ///// <summary>
+        ///// 获取流程表单设置
+        ///// </summary>
+        ///// <param name="id"></param>
+        ///// <returns></returns>
+        //[HttpGet("form")]
+        //public async Task<List<ProcessFormSettingResult>> GetFormSetting(int id)
+        //{
+        //    return await _processRepository.GetFormSettingAsync(id);
+        //}
+
+        ///// <summary>
+        ///// 获取流程节点树
+        ///// </summary>
+        ///// <param name="id"></param>
+        ///// <returns></returns>
+        //[HttpGet("nodeTree")]
+        //public async Task<ProcessNodeTreeResult> GetNodeTree(int id)
+        //{
+        //    return await _processRepository.GetNodeTreeAsync(id);
+        //}
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("")]
+        [AllowAnonymous]
+        public async Task<IEnumerable<Process>> GetList([FromQuery] string keyword)
+        {
+            return await _processRepository.GetListAsync(keyword);
+        }
+
+        /// <summary>
+        /// 删除流程
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _processRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 复制流程
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("actions/clone")]
+        public async Task<Process> Clone([FromBody] CloneRequest request)
+        {
+            var process = await _processService.GetAsync(request.ProcessId);
+            process.Name = request.Name;
+            return await _processService.AddAsync(process);
+        }
+    }
+}

+ 73 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminProcessGroupController.cs

@@ -0,0 +1,73 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Entity.WorkProcess;
+using GxPress.Repository.Interface;
+using GxPress.Repository.Interface.WorkProcess;
+using GxPress.Request.ProcessGroup;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 审批流程组
+    /// </summary>
+    [Route("api/admin/processGroup")]
+    [ApiController]
+    [Authorize]
+    public class AdminProcessGroupController : Controller
+    {
+        private readonly IProcessGroupRepository _processGroupRepository;
+
+        public AdminProcessGroupController(IProcessGroupRepository processGroupRepository)
+        {
+            _processGroupRepository = processGroupRepository;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<ProcessGroup> Add([FromBody] ArticleGroupAddRequest request)
+        {
+            return await _processGroupRepository.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<IEnumerable<ProcessGroup>> GetList()
+        {
+            return await _processGroupRepository.GetListAsync();
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody]ArticleGroupAddRequest request)
+        {
+            return await _processGroupRepository.UpdateAsync(id, request);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _processGroupRepository.DeleteAsync(id);
+        }
+
+    }
+}

+ 82 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminRoleController.cs

@@ -0,0 +1,82 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.Role;
+using GxPress.Result.Role;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 角色
+    /// </summary>
+    [Route("api/admin/role")]
+    [ApiController]
+    [Authorize]
+    public class AdminRoleController : ControllerBase
+    {
+        private readonly IRoleRepository _roleRepository;
+
+        public AdminRoleController(IRoleRepository roleRepository)
+        {
+            _roleRepository = roleRepository;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<RoleDetailResult> Add(RoleAddRequest request)
+        {
+            return await _roleRepository.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _roleRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody]RoleAddRequest request)
+        {
+            return await _roleRepository.UpdateAsync(id, request);
+        }
+
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<RoleDetailResult> GetDetail(int id)
+        {
+            return await _roleRepository.GetDetailAsync(id);
+        }
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <param name="groupId"></param>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<List<RoleDetailResult>> GetList(int groupId)
+        {
+            return await _roleRepository.GetDetailListAsync(groupId);
+        }
+    }
+}

+ 71 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminRoleGroupController.cs

@@ -0,0 +1,71 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.RoleGroup;
+using GxPress.Result.RoleGroup;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 角色组
+    /// </summary>
+    [Route("api/admin/roleGroup")]
+    [ApiController]
+    [Authorize]
+    public class AdminRoleGroupController : ControllerBase
+    {
+        private readonly IRoleGroupRepository _roleGroupRepository;
+
+        public AdminRoleGroupController(IRoleGroupRepository roleGroupRepository)
+        {
+            _roleGroupRepository = roleGroupRepository;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<RoleGroup> Add([FromBody] RoleGroupAddRequest request)
+        {
+            return await _roleGroupRepository.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody]RoleGroupAddRequest request)
+        {
+            return await _roleGroupRepository.UpdateAsync(id, request);
+        }
+
+        /// <summary>
+        /// 获取列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<List<RoleGroupDetailResult>> GetList()
+        {
+            return await _roleGroupRepository.GetDetailListAsync();
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("id")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _roleGroupRepository.DeleteAsync(id);
+        }
+    }
+}

+ 103 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminSellController.cs

@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using ExcelDataReader;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Sell;
+using GxPress.Request.User;
+using GxPress.Result.sell;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 发行数据
+    /// </summary>
+    [Route("api/admin/sell")]
+    [ApiController]
+    [Authorize]
+    public class AdminSellController : ControllerBase
+    {
+        private readonly ILogger<AdminSellController> _logger;
+        private readonly ISellRepository _repository;
+
+        public AdminSellController(ILogger<AdminSellController> logger, ISellRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+        /// <summary>
+        /// 发行数据Excel数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload")]
+        public async Task<bool> SellExcelUpload([FromBody] UserExcelUploadRequest request)
+        {
+            var relativePath = request.ExcelUrl;
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+            //获取excel分析
+            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
+            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
+            var result = reader.AsDataSet();
+            var sheet = result.Tables["Sheet1"];
+            var error = string.Empty;
+            var listSell = new List<Sell>();
+            for (int i = 1; i < sheet.Rows.Count; i++) //行
+            {
+                var sell = new Sell();
+                if (i == 1)
+                    continue;
+                var sellAmount = sheet.Rows[i][0].ToString().Trim(); //金额
+                if (string.IsNullOrEmpty(sellAmount))
+                    error = "发行金额";
+                sell.SellAmount = int.Parse(sellAmount);
+                var sellVolumeCount = sheet.Rows[i][1].ToString().Trim(); //类型
+                if (string.IsNullOrEmpty(sellVolumeCount))
+                    error = "发行册数";
+                sell.SellVolumeCount = int.Parse(sellVolumeCount);
+                var enteringDateTime = sheet.Rows[i][2].ToString().Trim(); //录入时间
+                if (string.IsNullOrEmpty(enteringDateTime))
+                    error = "录入时间必填";
+                sell.EnteringDateTime = DateTime.Parse(enteringDateTime);
+                if (!string.IsNullOrEmpty(error))
+                    break;
+                listSell.Add(sell);
+            }
+
+            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
+            //计算
+            var success = await _repository.InsertAsync(listSell);
+            if (success == false)
+                throw new BusinessException("服务器异常");
+            return true;
+        }
+        /// <summary>
+        /// 发行列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<Sell>> GetPagedList(PageParameter request)
+        {
+            return await _repository.GetPageListAsync(request);
+        }
+        /// <summary>
+        /// 发行图表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        public async Task<SellResult> GetSellChart(SellRequest request)
+        {
+            return await _repository.GetSellChartAsync(request);
+        }
+    }
+}

+ 79 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminSlideController.cs

@@ -0,0 +1,79 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 审批轮播
+    /// </summary>
+    [Route("api/admin/slide")]
+    [ApiController]
+    [Authorize]
+    public class AdminSlideController : ControllerBase
+    {
+        private readonly ISlideRepository _slideRepository;
+
+        public AdminSlideController(ISlideRepository slideRepository)
+        {
+            _slideRepository = slideRepository;
+        }
+
+        /// <summary>
+        /// 添加轮播
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<Slide> Add([FromBody] Slide request)
+        {
+            return await _slideRepository.AddAsync(request);
+        }
+
+        /// <summary>
+        /// 修改轮播
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut]
+        public async Task<Slide> Edit([FromBody] Slide request)
+        {
+            return await _slideRepository.EditAsync(request);
+        }
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("")]
+        public async Task<IEnumerable<Slide>> GetList([FromQuery] Slide request)
+        {
+            var pagedList = await _slideRepository.GetListAsync();
+            return pagedList;
+        }
+
+        /// <summary>
+        /// 轮播
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<Slide> Get(int id)
+        {
+            return await _slideRepository.GetAsync(id);
+        }
+
+        /// <summary>
+        /// 删除轮播
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _slideRepository.DeleteAsync(id);
+        }
+    }
+}

+ 106 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminStorehouseController.cs

@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ExcelDataReader;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Sell;
+using GxPress.Request.Storehouse;
+using GxPress.Request.User;
+using GxPress.Result.Storehouse;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 仓库数据
+    /// </summary>
+    [Route("api/admin/storehouse")]
+    [ApiController]
+    [Authorize]
+    public class AdminStorehouseController : ControllerBase
+    {
+        private readonly ILogger<AdminStorehouseController> _logger;
+        private readonly IStorehouseRepository _repository;
+
+        public AdminStorehouseController(ILogger<AdminStorehouseController> logger, IStorehouseRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+
+        /// <summary>
+        /// 仓库数据Excel数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload")]
+        public async Task<bool> StorehouseExcelUpload([FromBody] UserExcelUploadRequest request)
+        {
+            var relativePath = request.ExcelUrl;
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+            //获取excel分析
+            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
+            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
+            var result = reader.AsDataSet();
+            var sheet = result.Tables["Sheet1"];
+            var error = string.Empty;
+            var listStorehouse = new List<Storehouse>();
+            for (int i = 1; i < sheet.Rows.Count; i++) //行
+            {
+                var storehouse = new Storehouse();
+                if (i == 1)
+                    continue;
+                var storehouseCount = sheet.Rows[i][0].ToString().Trim(); //金额
+                if (string.IsNullOrEmpty(storehouseCount))
+                    error = "库存数";
+                storehouse.StorehouseCount = int.Parse(storehouseCount);
+
+                var enteringDateTime = sheet.Rows[i][1].ToString().Trim(); //录入时间
+                if (string.IsNullOrEmpty(enteringDateTime))
+                    error = "录入时间必填";
+                storehouse.EnteringDateTime = DateTime.Parse(enteringDateTime);
+                if (!string.IsNullOrEmpty(error))
+                    break;
+                listStorehouse.Add(storehouse);
+            }
+
+            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
+            //计算
+            var success = await _repository.InsertAsync(listStorehouse);
+            if (success == false)
+                throw new BusinessException("服务器异常");
+            return true;
+        }
+
+        /// <summary>
+        /// 仓库数据列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<Storehouse>> GetPagedList(PageParameter request)
+        {
+            return await _repository.GetPageListAsync(request);
+        }
+
+        /// <summary>
+        /// 库存图标
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        public async Task<StorehouseResult> GetStorehouseChart(StorehouseRequest request)
+        {
+            return await _repository.GetStorehouseChartAsync(request);
+        }
+    }
+}

+ 102 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminThesaurusController.cs

@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Admin;
+using GxPress.Request.AppVersion;
+using GxPress.Request.Thesaurus;
+using GxPress.Result.Admin;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 词库 热词 冷词
+    /// </summary>
+    [Route("api/admin/thesaurus")]
+    [ApiController]
+    [Authorize]
+    public class AdminThesaurusController : ControllerBase
+    {
+
+        private readonly IThesaurusRepository _thesaurusRepository;
+
+        public AdminThesaurusController(IThesaurusRepository thesaurusRepository)
+        {
+            _thesaurusRepository = thesaurusRepository;
+        }
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request">参数</param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        [AllowAnonymous]
+        public async Task<bool> InThesaurus([FromBody] ThesaurusInRequest request)
+        {
+            if (!string.IsNullOrEmpty(request.ThesaurusName) && request.ThesaurusName.Length > 500)
+            {
+                throw new Exception("保存失败,字符数不能超出16字");
+            }
+            var appVersion = new Thesaurus { ThesaurusType = request.ThesaurusType, ThesaurusName = request.ThesaurusName };
+            return await _thesaurusRepository.InsertAsync(appVersion);
+        }
+
+        /// <summary>
+        /// 分页查询列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        [AllowAnonymous]
+        public async Task<PagedList<Thesaurus>> GetPagedList([FromBody]ThesaurusPageSearchRequest request)
+        {
+            return await _thesaurusRepository.GetPageList(request);
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _thesaurusRepository.DeleteAsync(id);
+        }
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<Thesaurus> Get(int id)
+        {
+            return await _thesaurusRepository.GetDetailAsync(id);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody] Thesaurus request)
+        {
+            if (!string.IsNullOrEmpty(request.ThesaurusName) && request.ThesaurusName.Length > 500)
+            {
+                throw new Exception("保存失败,字符数不能超出16字");
+            }
+            return await _thesaurusRepository.UpdateAsync(id, request);
+        }
+    }
+}

+ 243 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminUserController.cs

@@ -0,0 +1,243 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ExcelDataReader;
+using GxPress.Auth;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.User;
+using GxPress.Result.User;
+using GxPress.Service.Interface;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace GxPress.Api.AdminControllers
+{
+    /// <summary>
+    /// 用户
+    /// </summary>
+    [Route("/api/admin/user")]
+    [ApiController]
+    [Authorize]
+    public class AdminUserController : ControllerBase
+    {
+        private readonly JwtOptions _jwtOptions;
+        private readonly ILogger<AdminUserController> _logger;
+        private readonly IUserRepository _userRepository;
+        private readonly IDepartmentRepository _departmentRepository;
+        private readonly IUserService _userService;
+
+        public AdminUserController(IUserRepository userRepository, IOptions<JwtOptions> jwtOptions,
+            ILogger<AdminUserController> logger, IDepartmentRepository departmentRepository, IUserService userService)
+        {
+            _userRepository = userRepository;
+            _departmentRepository = departmentRepository;
+            _jwtOptions = jwtOptions.Value;
+            _logger = logger;
+            _userService = userService;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<User> Add([FromBody] User request)
+        {
+            if (!string.IsNullOrEmpty(request.Description) && request.Description.Length > 500)
+            {
+                throw new Exception("保存失败,字符数不能超出500");
+            }
+            request.Id = await _userRepository.InsertAsync(request);
+            if (request.Id > 0)
+            {
+                //添加环信
+                await _userRepository.CreateMiUserAsync(request);
+            }
+            return request;
+        }
+
+
+
+        /// <summary>
+        /// 用户详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<User> GetDetail(int id)
+        {
+            return await _userRepository.GetAsync(id);
+        }
+
+        /// <summary>
+        /// 删除用户
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _userRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 删除用户
+        /// </summary>
+        /// <param name="userIds"></param>
+        /// <returns></returns>
+        [HttpDelete]
+        public async Task<bool> Delete([FromBody] IEnumerable<int> userIds)
+        {
+            return await _userService.DeleteUsersAsync(userIds);
+        }
+
+        /// <summary>
+        /// 更新用户信息
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> Update(int id, [FromBody] User request)
+        {
+            if (!string.IsNullOrEmpty(request.Description) && request.Description.Length > 500)
+            {
+                throw new Exception("保存失败,字符数不能超出500");
+            }
+            return await _userRepository.UpdateAsync(id, request);
+        }
+
+        /// <summary>
+        /// 分页列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        public async Task<PagedList<UserResult>> GetPagedList([FromBody] UserPageSearchRequest request)
+        {
+            var result = await _userService.GetPagedListAsync(request);
+            return result;
+        }
+
+        /// <summary>
+        /// 分页列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("all")]
+        public async Task<List<UserResult>> GetList([FromBody] ArticleSearchRequest request)
+        {
+            var result = await _userRepository.GetListAsync(request);
+            return result;
+        }
+
+        /// <summary>
+        /// 修改用户角色
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("actions/change_role")]
+        public async Task<bool> ChangeRole([FromBody] UserChangeRoleRequest request)
+        {
+            return await _userRepository.ChangeRoleAsync(request.UserIds, request.RoleId);
+        }
+
+        /// <summary>
+        /// 修改用户角色
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("actions/change_department")]
+        public async Task<bool> ChangeDepartment([FromBody] UserChangeDepartmentRequest request)
+        {
+            return await _userRepository.ChangeDepartmentAsync(request.UserIds, request.DepartmentId);
+        }
+
+        /// <summary>
+        /// 分析Excel数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("upload_user")]
+        public async Task<bool> UserExcelUpload([FromBody] UserExcelUploadRequest request)
+        {
+            if (request.DepartmentId == 0)
+                throw new BusinessException("请选择部门");
+            var relativePath = request.ExcelUrl;
+            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+            //获取excel分析
+            var stream = System.IO.File.Open("wwwroot/" + relativePath, FileMode.Open, FileAccess.Read);
+            IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream);
+            var result = reader.AsDataSet();
+            var sheet = result.Tables["Sheet1"];
+            var error = string.Empty;
+            var listUser = new List<User>();
+            for (int i = 1; i < sheet.Rows.Count; i++) //行
+            {
+                var user = new User();
+                if (i == 1)
+                    continue;
+                var name = sheet.Rows[i][1].ToString().Trim(); //姓名
+                if (string.IsNullOrEmpty(name))
+                    error = "姓名必填";
+                user.Name = name;
+                var phone = sheet.Rows[i][2].ToString().Trim(); //手机号码
+                if (phone.Length != 11)
+                    error = "手机号码有误";
+                user.Phone = phone;
+                var email = sheet.Rows[i][3].ToString().Trim(); //邮箱
+                if (!string.IsNullOrWhiteSpace(email))
+                {
+                    if (email.Contains("@"))
+                        email = email.Replace("@", "@");
+                    if (!GxPress.Common.Tools.VerifyHelper.IsEmailValid(email))
+                        error = "邮箱有误";
+                }
+                user.Email = email;
+                user.DepartmentId = request.DepartmentId;
+                var sex = sheet.Rows[i][4].ToString().Trim(); //性别
+                user.Gender = sex == "男" ? "Male" : "Female";
+                var city = sheet.Rows[i][5].ToString().Trim(); //城市
+                user.City = city;
+                var isLeader = sheet.Rows[i][6].ToString().Trim(); //是否部门负责人
+                var entryDataTime = sheet.Rows[i][7].ToString().Trim(); //入职时间
+                user.IsLeader = isLeader == "是" ? true : false;
+                if (!string.IsNullOrEmpty(entryDataTime))
+                    user.EntryDataTime = DateTime.Parse(entryDataTime);
+                if (!string.IsNullOrEmpty(error))
+                    break;
+                listUser.Add(user);
+            }
+            //判断重复
+            foreach (var user in listUser)
+                if (listUser.Count(n => n.Email == user.Phone) > 1)
+                    throw new BusinessException("手机有重复请检查");
+            if (!string.IsNullOrEmpty(error)) throw new BusinessException(error);
+            //计算
+            await _userRepository.UpdateUserExcelAsync(listUser);
+            return true;
+        }
+        /// <summary>
+        /// 筛选用户导出
+        /// </summary>
+        /// <param name="userIds"></param>
+        /// <returns></returns>
+        [HttpPost("excel")]
+        public async Task<FileStreamResult> ExcelUser(List<int> userIds)
+        {
+            if (userIds.Count == 0)
+                throw new BusinessException("请选择用户");
+            var fileName = await _userService.ExcelUserAsync(userIds);
+            return File(new FileStream(fileName, FileMode.Open), "application/octet-stream", "员工数据.xls");
+        }
+    }
+}

File diff suppressed because it is too large
+ 477 - 0
GxPress/Api/GxPress.Api/AdminControllers/AdminUtilsController.cs


+ 32 - 0
GxPress/Api/GxPress.Api/AppControllers/AboutController.cs

@@ -0,0 +1,32 @@
+using GxPress.Common.Tools;
+using GxPress.Result.About;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// app
+    /// </summary>
+    [Route("api/app/about")]
+    [ApiController]
+    [Authorize]
+    public class AboutController : ControllerBase
+    {
+        /// <summary>
+        /// 关于 对付对付
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("info")]
+        public AboutResult About()
+        {
+            var addressUrlDownload=  ConfigHelper.GetValue("ServiceAddress:AddressUrlDownload");
+            var aboutResult = new AboutResult
+            {
+                AboutUrl = StringUtils.AddDomain("/static/aboutus.html"),
+                DownloadUrl =StringUtils.AddDomain($"{addressUrlDownload}/mobile/download")
+            };
+            return aboutResult;
+        }
+    }
+}

+ 100 - 0
GxPress/Api/GxPress.Api/AppControllers/AddressBookGroupController.cs

@@ -0,0 +1,100 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Request.AddressBookGroup;
+using GxPress.Result.AddressBook;
+using GxPress.Result.AddressBookGroup;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 用户通讯录组
+    /// </summary>
+    [Route("api/app/address-book-group")]
+    [ApiController]
+    [Authorize]
+    public class AddressBookGroupController : ControllerBase
+    {
+        private readonly ILogger<AddressBookGroupController> _logger;
+        private readonly IAddressBookGroupRepository _addressBookGroupRepository;
+        private readonly ILoginContext _loginContext;
+
+        public AddressBookGroupController(ILogger<AddressBookGroupController> logger, IAddressBookGroupRepository addressBookGroupRepository, ILoginContext loginContext)
+        {
+            _logger = logger;
+            _addressBookGroupRepository = addressBookGroupRepository;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _addressBookGroupRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update")]
+        public async Task<bool> Update(AddressBookGroupUpRequest request)
+        {
+            return await _addressBookGroupRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 获取
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<AddressBookGroupResult>> GetAddressBookGroupList(AddressBookGroupSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _addressBookGroupRepository.GetAddressBookGroupListAsync(request);
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(AddressBookGroupInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _addressBookGroupRepository.InsertAsync(request);
+        }
+        /// <summary>
+        /// 获取用户通讯录组
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list-group")]
+        public async Task<AddressBookListResult> GetAddressBookList()
+        {
+            AddressBookListRequest request = new AddressBookListRequest { UserId = _loginContext.AccountId };
+            return await _addressBookGroupRepository.GetAddressBookListAsync(request);
+        }
+        /// <summary>
+        /// 添加联系人
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add-address-book-user")]
+        public async Task<bool> InsertAddressBookUser(AddressBookInUserRequest request)
+        {
+            return await _addressBookGroupRepository.InsertAddressBookUserAsync(request);
+        }
+
+
+    }
+}

+ 82 - 0
GxPress/Api/GxPress.Api/AppControllers/AddressBookGroupUserController.cs

@@ -0,0 +1,82 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Request.AddressBookGroupUser;
+using GxPress.Result.AddressBookGroupUser;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 通讯录用户信息
+    /// </summary>
+    [Route("api/app/address-book-group-user")]
+    [ApiController]
+    [Authorize]
+    public class AddressBookGroupUserController : ControllerBase
+    {
+        private readonly ILogger<AppVersionController> _logger;
+        private readonly IAddressBookGroupUserRepository _addressBookGroupUserRepository;
+        private readonly ILoginContext _loginContext;
+        public AddressBookGroupUserController(ILogger<AppVersionController> logger, IAddressBookGroupUserRepository addressBookGroupUserRepository, ILoginContext loginContext)
+        {
+            _logger = logger;
+            _addressBookGroupUserRepository = addressBookGroupUserRepository;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _addressBookGroupUserRepository.DeleteAsync(id);
+        }
+        /// <summary>
+        /// 删除自建分组用户
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("delete")]
+        public async Task<bool> Deletes(AddressBookGroupUserDeleteRequest request)
+        {
+            return await _addressBookGroupUserRepository.DeletesAsync(request.Ids);
+        }
+        /// <summary>
+        /// 获取
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<AddressBookGroupUserListResult> GetAddressBookGroupUserList(
+            AddressBookGroupUserSearchRequest request)
+        {
+            var userId = _loginContext.AccountId;
+            return await _addressBookGroupUserRepository.GetAddressBookGroupUserListAsync(request, userId);
+        }
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(AddressBookGroupUserInRequest request)
+        {
+            return await _addressBookGroupUserRepository.InsertAsync(request);
+        }
+        /// <summary>
+        /// 移动分组成员
+        /// </summary>
+        /// /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("move")]
+        public async Task<bool> AddressBookGroupUserMove(AddressBookGroupUserMoveRequest request)
+        {
+            return await _addressBookGroupUserRepository.AddressBookGroupUserMoveAsync(request);
+        }
+    }
+}

+ 69 - 0
GxPress/Api/GxPress.Api/AppControllers/AdminVerifyController.cs

@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Request.App.AdminVerify;
+using GxPress.Result.App.AdminVerify;
+using GxPress.Service.Interface.AdminVerify;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 验证信息
+    /// </summary>
+    [Route("api/app/admin-verify")]
+    [ApiController]
+    [Authorize]
+    public class AdminVerifyController : ControllerBase
+    {
+        private readonly IAdminVerifyService _adminVerifyService;
+        private readonly ILoginContext _loginContext;
+        public AdminVerifyController(IAdminVerifyService adminVerifyService,ILoginContext loginContext)
+        {
+            _adminVerifyService = adminVerifyService;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 清空
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("delete")]
+        public async Task<bool> DeleteAllAsync()
+        {
+            return await _adminVerifyService.DeleteAllAsync(_loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("update")]
+        public async Task<bool> UpdateAsync(AdminVerifyUpdateRequest request)
+        {
+            return await _adminVerifyService.UpdateAsync(request.Id, request.AdminVerifyTypeConst);
+        }
+
+        /// <summary>
+        /// 根据用户查询
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<IEnumerable<AdminVerifySearchResult>> GetAllAsync()
+        {
+            return await _adminVerifyService.GetAllAsync(_loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 查询未处理条数
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("count")]
+        public async Task<int> GetUDisposeCount()
+        {
+            return await _adminVerifyService.GetUDisposeCount(_loginContext.AccountId);
+        }
+    }
+}

+ 49 - 0
GxPress/Api/GxPress.Api/AppControllers/AnalyzeController.cs

@@ -0,0 +1,49 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Request.Analyze;
+using GxPress.Request.App.Analyze;
+using GxPress.Result.App.Analyze;
+using GxPress.Service.Interface.Analyze;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/analyze")]
+    [ApiController]
+    [Authorize]
+    public class AnalyzeController : ControllerBase
+    {
+        private readonly IAnalyzeService _analyzeService;
+        private readonly ILoginContext _loginContext;
+        public AnalyzeController(IAnalyzeService analyzeService,ILoginContext loginContext)
+        {
+            _analyzeService = analyzeService;
+            _loginContext=loginContext;
+        }
+
+        /// <summary>
+        /// 设置 点赞 转发 收藏
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("set")]
+        public async Task<bool> SetAnalyzeAsync(AnalyzeRequest request)
+        {
+            request.UserId=_loginContext.AccountId;
+            return await _analyzeService.SetAnalyzeAsync(request);
+        }
+
+        /// <summary>
+        /// 获取点赞数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<PraisePageResult>> GetPraisePageAsync(PraisePageSearchRequest request)
+        {
+            return await _analyzeService.GetPraisePageAsync(request);
+        }
+    }
+}

+ 80 - 0
GxPress/Api/GxPress.Api/AppControllers/AppCarController.cs

@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Entity.WorkCar;
+using GxPress.Repository.Interface.WorkCar;
+using GxPress.Request.App.WorkCar;
+using GxPress.Result;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 车辆
+    /// </summary>
+    [Route("api/app/car")]
+    [ApiController]
+    [Authorize]
+    public class AppCarController : ControllerBase
+    {
+        private readonly ILoginContext _loginContext;
+        private readonly ICarTypeRepository _carTypeRepository;
+        private readonly ICarOrderRepository _carOrderRepository;
+        private readonly ICarRepository _carRepository;
+
+        public AppCarController(ILoginContext loginContext, ICarTypeRepository carTypeRepository, ICarOrderRepository carOrderRepository, ICarRepository carRepository)
+        {
+            _loginContext = loginContext;
+            _carTypeRepository = carTypeRepository;
+            _carOrderRepository = carOrderRepository;
+            _carRepository = carRepository;
+        }
+
+        /// <summary>
+        /// 获取车辆类型列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("type")]
+        public async Task<IEnumerable<CarType>> TypeList()
+        {
+            return await _carTypeRepository.GetListAsync();
+        }
+
+        /// <summary>
+        /// 预定车辆
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("actions/order")]
+        public async Task<DefaultResult> Order([FromBody] CarRequest request)
+        {
+            var orderedCarIds =
+                await _carOrderRepository.GetOrderedCarIds(request.TypeId, request.StartDate, request.EndDate);
+            var carId = await _carRepository.GetAvailableCarId(request.TypeId, orderedCarIds);
+            if (carId == 0)
+            {
+                throw new Exception("本时段车辆已预订,请更换预订时间或车辆类型");
+            }
+
+            var order = new CarOrder
+            {
+               UserId = _loginContext.AccountId,
+               CarId = carId,
+               Reasons = request.Reasons,
+               Destination = request.Destination,
+               TypeId = request.TypeId,
+               StartDate = request.StartDate,
+               EndDate = request.EndDate,
+               Hour = request.Hour
+            };
+
+            await _carOrderRepository.InsertAsync(order);
+
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+    }
+}

+ 37 - 0
GxPress/Api/GxPress.Api/AppControllers/AppController.cs

@@ -0,0 +1,37 @@
+using GxPress.Common.Exceptions;
+using GxPress.Result;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+
+
+    public class AppController : ControllerBase
+    {
+        public AppResult AppResult { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="success"></param>
+        /// <param name="msg"></param>
+        /// <param name="msg1"></param>
+        /// <returns></returns>
+        public JsonResult JsonResult(bool success, string msg, string msg1)
+        {
+            var appJsonData = new AppResult();
+            if (success)
+            {
+                appJsonData.Code = 1;
+                appJsonData.Msg = msg;
+            }
+            else
+            {
+                throw new BusinessException(msg1);
+            }
+
+            var json = new JsonResult(appJsonData);
+            return json;
+        }
+    }
+}

+ 156 - 0
GxPress/Api/GxPress.Api/AppControllers/AppFlowController.Actions.cs

@@ -0,0 +1,156 @@
+using System;
+using System.Threading.Tasks;
+using Datory;
+using GxPress.Common.Tools;
+using GxPress.EnumConst;
+using GxPress.Result;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    public partial class AppFlowController
+    {
+
+        /// <summary>
+        /// 动作 - 审批
+        /// </summary>
+        /// <param name="request">审批意见</param>
+        /// <returns></returns>
+        [HttpPost("action/check")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsCheck([FromBody] CheckRequest request)
+        {
+            if (!string.IsNullOrEmpty(request.Message) && request.Message.Length > 500)
+            {
+                throw new Exception("审批意见不能操作500字,请重新输入");
+            }
+            await _flowService.CheckAsync(request.TodoId, request.IsChecked, request.Message);
+
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 下载
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/download")]
+        [AllowAnonymous]
+        public async Task<DownloadResult> ActionsDownload([FromBody] ActionRequest request)
+        {
+            // var url = await _flowService.DownloadAsync(request.FlowId);
+            // url = Request.Scheme + "://" + Request.Host.Host +
+            //           (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
+            //           "/" + url;
+            var url = await docService.MakeDoc(request.FlowId, _loginContext.AccountId);
+            return new DownloadResult
+            {
+                DownloadUrl = StringUtils.AddDomain(url),
+                PreviewUrl = StringUtils.GetPreviewDocUrl(url)
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 催办
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/remind")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsRemind([FromBody] ActionRequest request)
+        {
+            return new DefaultResult
+            {
+                Value = await _flowService.RemindAsync(request.FlowId, _loginContext.AccountId)
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 上会
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/meeting")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsMeeting([FromBody] ActionRequest request)
+        {
+            //await _flowRepository.UpdateStateAsync(request.FlowId, nameof(FlowState.Meeting));
+            //修改当前用户的审核状态
+            await _flowTodoRepository.UpdateAsync(Q.Set(nameof(Entity.WorkFlow.FlowTodo.IsDone), true).Set(nameof(Entity.WorkFlow.FlowTodo.IsChecked), false).Set(nameof(Entity.WorkFlow.FlowTodo.DoneType), 1).Where(nameof(Entity.WorkFlow.FlowTodo.FlowId), request.FlowId).Where(nameof(Entity.WorkFlow.FlowTodo.Type), nameof(TodoTypeConst.ApproverCheck)).Where(nameof(Entity.WorkFlow.FlowTodo.UserId), _loginContext.AccountId));
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 撤销上会
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/cancelMeeting")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsCancelMeeting([FromBody] ActionRequest request)
+        {
+            //await _flowRepository.UpdateStateAsync(request.FlowId, nameof(FlowState.Checking));
+            //修改当前操作人为带审核
+            await _flowTodoRepository.UpdateAsync(Q.Where(nameof(Entity.WorkFlow.FlowTodo.FlowId), request.FlowId).Where(nameof(Entity.WorkFlow.FlowTodo.UserId), _loginContext.AccountId).Set(nameof(Entity.WorkFlow.FlowTodo.IsDone), false).Set(nameof(Entity.WorkFlow.FlowTodo.IsChecked), false).Set(nameof(Entity.WorkFlow.FlowTodo.DoneType), 0).Set(nameof(Entity.WorkFlow.FlowTodo.IsOperate), true));
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 转审
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/transferCheck")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsTransferCheck([FromBody] ActionTransferCheckRequest request)
+        {
+            await _flowService.TransferCheckAsync(request.TodoId, request.TransferUserIds, request.Message, request.FileIds);
+            // //修改当前用户的审核状态
+            // await _flowTodoRepository.UpdateAsync(Q.Set(nameof(Entity.WorkFlow.FlowTodo.IsDone), true).Where(nameof(Entity.WorkFlow.FlowTodo.Id), request.TodoId).Where(nameof(Entity.WorkFlow.FlowTodo.UserId), _loginContext.AccountId));
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+
+        /// <summary>
+        /// 动作 - 重新提交
+        /// </summary>
+        /// <param name="request">请求</param>
+        /// <returns></returns>
+        [HttpPost("action/reAdd")]
+        [AllowAnonymous]
+        public async Task<DefaultResult> ActionsReAddCheck([FromBody] ActionRequest request)
+        {
+            await _flowService.ReAddAsync(request.FlowId);
+
+            return new DefaultResult
+            {
+                Value = true
+            };
+        }
+        /// <summary>
+        /// 上会待定
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("action/wait")]
+        public async Task<DefaultResult> ActionsWait(ActionRequest request)
+        {
+            return new DefaultResult
+            {
+                Value = await _flowService.ActionsWait(request.FlowId, _loginContext.AccountId)
+            };
+        }
+    }
+}

+ 138 - 0
GxPress/Api/GxPress.Api/AppControllers/AppFlowController.Dto.cs

@@ -0,0 +1,138 @@
+using System.Collections.Generic;
+using GxPress.Entity.WorkFlow;
+using GxPress.EnumConst;
+
+namespace GxPress.Api.AppControllers
+{
+    public partial class AppFlowController
+    {
+        public class TodoListResult
+        {
+            /// <summary>
+            /// 当前页
+            /// </summary>
+            public int Count { get; set; }
+
+            /// <summary>
+            /// 每页显示多少项
+            /// </summary>
+            public IEnumerable<FlowTodoResult> Items { get; set; }
+        }
+
+        public class GetCountResult
+        {
+            /// <summary>
+            /// 我审批的 - 待审批
+            /// </summary>
+            public int MyCheckingCount { get; set; }
+
+            /// <summary>
+            /// 我审批的 - 已审批
+            /// </summary>
+            public int MyCheckedCount { get; set; }
+
+            /// <summary>
+            /// 我发起的 - 待审批
+            /// </summary>
+            public int SubmittedCheckingCount { get; set; }
+
+            /// <summary>
+            /// 我发起的 - 已审批
+            /// </summary>
+            public int SubmittedCheckedCount { get; set; }
+
+            /// <summary>
+            /// 抄送我的 - 未读
+            /// </summary>
+            public int CcUnreadCount { get; set; }
+
+            /// <summary>
+            /// 抄送我的 - 全部
+            /// </summary>
+            public int CcAllCount { get; set; }
+        }
+
+        public class FlowTodoResult : FlowTodo
+        {
+            public FlowState State { get; set; }
+            /// <summary>
+            /// 当前页
+            /// </summary>
+            public string Title { get; set; }
+
+            public string AvatarUrl { get; set; }
+
+            /// <summary>
+            /// 每页显示多少项
+            /// </summary>
+            public List<string> Summaries { get; set; }
+        }
+
+        public class CheckRequest
+        {
+            /// <summary>
+            /// 工作流Id
+            /// </summary>
+            public int FlowId { get; set; }
+
+            /// <summary>
+            /// 待办Id
+            /// </summary>
+            public int TodoId { get; set; }
+
+            /// <summary>
+            /// 是否审核通过
+            /// </summary>
+            public bool IsChecked { get; set; }
+
+            /// <summary>
+            /// 留言
+            /// </summary>
+            public string Message { get; set; }
+        }
+
+        public class ActionRequest
+        {
+            /// <summary>
+            /// 工作流Id
+            /// </summary>
+            public int FlowId { get; set; }
+        }
+
+        public class ActionTransferCheckRequest
+        {
+            /// <summary>
+            /// 待办Id
+            /// </summary>
+            public int TodoId { get; set; }
+
+            /// <summary>
+            /// 转审用户Id列表
+            /// </summary>
+            public List<int> TransferUserIds { get; set; }
+
+            /// <summary>
+            /// 审批意见
+            /// </summary>
+            public string Message { get; set; }
+
+            /// <summary>
+            /// 附件Id列表
+            /// </summary>
+            public List<int> FileIds { get; set; }
+        }
+
+        public class DownloadResult
+        {
+            /// <summary>
+            /// 下载地址
+            /// </summary>
+            public string DownloadUrl { get; set; }
+
+            /// <summary>
+            /// 预览
+            /// </summary>
+            public string PreviewUrl { get; set; }
+        }
+    }
+}

+ 312 - 0
GxPress/Api/GxPress.Api/AppControllers/AppFlowController.cs

@@ -0,0 +1,312 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Api.AdminControllers;
+using GxPress.Auth;
+using GxPress.Entity.WorkFlowDto;
+using GxPress.EnumConst;
+using GxPress.Repository.Interface;
+using GxPress.Repository.Interface.WorkFlow;
+using GxPress.Repository.Interface.WorkProcess;
+using GxPress.Request.App.Flow;
+using GxPress.Result.App;
+using GxPress.Result.App.Flow;
+using GxPress.Service.Interface;
+using GxPress.Service.Interface.Doc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 通讯录用户信息
+    /// </summary>
+    [Route("api/app/flow")]
+    [ApiController]
+    [Authorize]
+    public partial class AppFlowController : ControllerBase
+    {
+        private readonly ILogger<AppVersionController> _logger;
+        private readonly IWebHostEnvironment _environment;
+        private readonly ILoginContext _loginContext;
+        private readonly IFlowMessageRepository _flowMessageRepository;
+        private readonly IFlowTodoRepository _flowTodoRepository;
+        private readonly IProcessRepository _processRepository;
+        private readonly IProcessService _processService;
+        private readonly IFlowService _flowService;
+        private readonly IUserRepository _userRepository;
+        private readonly IFlowRepository _flowRepository;
+        private readonly IDocService docService;
+
+        public AppFlowController(
+            ILogger<AppVersionController> logger,
+            IWebHostEnvironment environment,
+            ILoginContext loginContext,
+            IFlowMessageRepository flowMessageRepository,
+            IFlowTodoRepository flowTodoRepository,
+            IProcessRepository processRepository,
+            IProcessService processService,
+            IFlowService flowService,
+            IUserRepository userRepository,
+            IFlowRepository flowRepository, IDocService docService
+            )
+        {
+            _logger = logger;
+            _environment = environment;
+            _loginContext = loginContext;
+            _flowMessageRepository = flowMessageRepository;
+            _flowTodoRepository = flowTodoRepository;
+            _processRepository = processRepository;
+            _processService = processService;
+            _flowService = flowService;
+            _userRepository = userRepository;
+            _flowRepository = flowRepository;
+            this.docService = docService;
+        }
+
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task Delete(int id)
+        {
+            await _flowService.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 添加工作项
+        /// </summary>
+        /// <param name="flow">工作项</param>
+        /// <returns></returns>
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task<FlowDto> Add([FromBody] FlowDto flow)
+        {
+            flow.State = FlowState.Checking;
+            flow.UserId = _loginContext.AccountId;
+            if (flow.Id > 0)
+                await _flowService.DeleteAsync(flow.Id);
+            flow.Id = await _flowService.AddAsync(flow);
+            return flow;
+        }
+
+        /// <summary>
+        /// 获取详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        [AllowAnonymous]
+        public async Task<FlowResult> Get(int id)
+        {
+            await _flowTodoRepository.UpdateCCIsDoneAsync(_loginContext.AccountId, id);
+            return await _flowService.GetFlowResult(id, _loginContext.AccountId);
+        }
+        /// <summary>
+        /// 获取详情 web专属
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("web/{id}")]
+        [AllowAnonymous]
+        public async Task<FlowResult> GetWeb(int id)
+        {
+            //await _flowTodoRepository.UpdateCCIsDoneAsync(_loginContext.AccountId, id);
+            return await _flowService.GetFlowResult(id, 0);
+        }
+        /// <summary>
+        /// 获取工作项列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<ListResult> List([FromQuery] FlowListRequest request)
+        {
+            var userId = _loginContext.AccountId;
+
+            if (request.Type == nameof(FlowListTypeConst.MyChecking))
+            {
+                return await _flowService.ListMyCheckingAsync(userId, request, nameof(FlowListTypeConst.MyChecking));
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.MyChecked))
+            {
+                return await _flowService.ListMyCheckedAsync(userId, request, nameof(FlowListTypeConst.MyChecked));
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.CcUnread))
+            {
+                return await _flowService.ListCcUnreadAsync(userId, request);
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.CcAll))
+            {
+                return await _flowService.ListCcAllAsync(userId, request);
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.SubmittedChecking))
+            {
+                return await _flowService.ListSubmittedCheckingAsync(userId, request);
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.SubmittedChecked))
+            {
+                return await _flowService.ListSubmittedCheckedAsync(userId, request);
+            }
+
+            return new ListResult();
+        }
+        /// <summary>
+        /// 获取工作项列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<ListResult> PostList(FlowListRequest request)
+        {
+            var userId = _loginContext.AccountId;
+
+            if (request.Type == nameof(FlowListTypeConst.MyChecking))
+            {
+                return await _flowService.ListMyCheckingAsync(userId, request, nameof(FlowListTypeConst.MyChecking));
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.MyChecked))
+            {
+                return await _flowService.ListMyCheckedAsync(userId, request, nameof(FlowListTypeConst.MyChecked));
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.CcUnread))
+            {
+                return await _flowService.ListCcUnreadAsync(userId, request);
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.CcAll))
+            {
+                return await _flowService.ListCcAllAsync(userId, request, nameof(FlowListTypeConst.CcAll));
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.SubmittedChecking))
+            {
+                return await _flowService.ListSubmittedCheckingAsync(userId, request, nameof(FlowListTypeConst.SubmittedChecking));
+            }
+
+            if (request.Type == nameof(FlowListTypeConst.SubmittedChecked))
+            {
+                return await _flowService.ListSubmittedCheckedAsync(userId, request);
+            }
+
+            return new ListResult();
+        }
+
+        /// <summary>
+        /// 待办事项
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("todo")]
+        [AllowAnonymous]
+        public async Task<ListResult> TodoList([FromQuery] AdminFlowController.ListRequest request)
+        {
+            var userId = _loginContext.AccountId;
+            var flowListRequest = new FlowListRequest();
+            flowListRequest.Page = request.Page;
+            flowListRequest.PerPage = request.PerPage;
+            var result = await _flowService.ListMyCheckingAsync(userId, flowListRequest, nameof(FlowListTypeConst.MyChecking));
+            return new ListResult
+            {
+                Count = result.Count,
+                Items = result.Items
+            };
+            // var flowTodoList = await _flowService.GetTodoListAsync(userId, request.Page, request.PerPage, request.ProcessId);
+            // var resultList = new List<FlowTodoResult>();
+            // foreach (var flowTodo in flowTodoList)
+            // {
+            //     //新增
+            //     if (flowTodo.IsDone)
+            //         continue;
+            //     var flow = await _flowService.GetAsync(flowTodo.FlowId);
+            //     var user = await _userRepository.GetAsync(flow.UserId);
+            //     if (user == null || flow == null) continue;
+
+            //     var result = new FlowTodoResult
+            //     {
+            //         Id = flowTodo.Id,
+            //         ProcessId = flowTodo.ProcessId,
+            //         FlowId = flowTodo.FlowId,
+            //         UserId = flowTodo.UserId,
+            //         Type = flowTodo.Type,
+            //         State = flow.State,
+            //         IsDone = false,
+            //         CreatedDate = flowTodo.CreatedDate
+            //     };
+            //     var (title, summaries) = await _flowService.GetFlowTitleAndSummaryAsync(user, flow.ProcessId, flow.Id);
+            //     result.Title = title;
+            //     result.AvatarUrl = _userRepository.GetAvatarUrl(user);
+            //     result.Summaries = summaries;
+            //     resultList.Add(result);
+            // }
+
+            // return new TodoListResult
+            // {
+            //     Count = await _flowService.GetTodoCountAsync(userId),
+            //     Items = resultList
+            // };
+
+            //    //return resultList.ToList();
+            //}
+        }
+
+        /// <summary>
+        /// 获取数字
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("count")]
+        [AllowAnonymous]
+        public async Task<GetCountResult> GetCount()
+        {
+            var userId = _loginContext.AccountId;
+            var request = new FlowListRequest();
+
+            var result = new GetCountResult
+            {
+                MyCheckingCount =
+                   await _flowTodoRepository.GetCountAsync(userId, nameof(TodoTypeConst.ApproverCheck), false,
+                    request),
+                MyCheckedCount =
+                    await _flowTodoRepository.GetCountAsync(userId, nameof(TodoTypeConst.ApproverCheck), true, request),
+                SubmittedCheckingCount = await _flowRepository.GetCountByUserIdAsync(userId, true, request),
+                //SubmittedCheckedCount= await _flowTodoRepository.GetUReadCountAsync(userId, "CarbonCopy",false,request),
+                SubmittedCheckedCount = await _flowRepository.GetCountByUserIdAsync(userId, false, request),
+                CcUnreadCount =
+                    await _flowTodoRepository.GetReadCountAsync(userId, nameof(TodoTypeConst.CarbonCopy), request, false),
+                CcAllCount = await _flowTodoRepository.GetReadCountAsync(userId, nameof(TodoTypeConst.CarbonCopy), request, true)
+            };
+            return result;
+        }
+
+        /// <summary>
+        /// 获取筛选
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("filter")]
+        [AllowAnonymous]
+        public async Task<List<Option>> Filter()
+        {
+            var processes = await _processRepository.GetListByDepartmentIdAsync(_loginContext.DepartmentId);
+            var list = processes.Select(x => new Option
+            {
+                Label = x.Name,
+                Value = x.Id
+            }).ToList();
+            list.Insert(0, new Option
+            {
+                Label = "全部",
+                Value = 0
+            });
+            return list;
+        }
+    }
+}

File diff suppressed because it is too large
+ 746 - 0
GxPress/Api/GxPress.Api/AppControllers/AppMeetingController.cs


+ 89 - 0
GxPress/Api/GxPress.Api/AppControllers/AppProcessController.cs

@@ -0,0 +1,89 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface.WorkProcess;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using GxPress.Entity.WorkProcess;
+using GxPress.Result.App.Process;
+using GxPress.Service.Interface;
+using System.Linq;
+using GxPress.Common.Tools;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/process")]
+    [ApiController]
+    [Authorize]
+    public class AppProcessController : ControllerBase
+    {
+        private readonly IProcessGroupRepository _processGroupRepository;
+        private readonly IProcessRepository _processRepository;
+        private readonly IProcessService _processService;
+        private readonly ILoginContext _loginContext;
+
+        public AppProcessController(IProcessGroupRepository processGroupRepository, IProcessRepository processRepository, IProcessService processService, ILoginContext loginContext)
+        {
+            _processGroupRepository = processGroupRepository;
+            _processRepository = processRepository;
+            _processService = processService;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 获取工作流程列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet]
+        [AllowAnonymous]
+        public async Task<IEnumerable<Process>> GetProcessList()
+        {
+            return await _processRepository.GetListByDepartmentIdAsync(_loginContext.DepartmentId);
+        }
+
+        /// <summary>
+        /// 获取工作流程
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<GetProcessResult> GetProcess(int id)
+        {
+            var processDto = await _processService.GetAsync(id);
+            var result = new GetProcessResult
+            {
+                Id = processDto.Id,
+                Name = processDto.Name,
+                IconUrl =StringUtils.AddDomain(processDto.IconUrl),
+                Description = processDto.Description,
+                FormFields = processDto.FormFields,
+                AllowApproverCheck = processDto.AllowApproverCheck,
+                AllowCarbonCopy = processDto.AllowCarbonCopy
+            };
+            result.ApproverCheckUserIds = new List<int>();
+            //获取流程接点
+            foreach (var item in processDto.ProcessNodes)
+                //添加系统审核人
+                result.ApproverCheckUserIds.AddRange(item.ApproverChecks.Select(n => n.UserId));
+            result.ApproverCheckUserIds.Add(_loginContext.AccountId);
+            return result;
+        }
+
+        /// <summary>
+        /// 获取流程组与流程列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("groups")]
+        [AllowAnonymous]
+        public async Task<IEnumerable<ProcessGroup>> GetProcessGroupList()
+        {
+            var groups = await _processGroupRepository.GetListAsync();
+            foreach (var processGroup in groups)
+            {
+                var processes = await _processRepository.GetListByGroupIdAsync(processGroup.Id);
+                processGroup.Processes = processes;
+            }
+
+            return groups;
+        }
+    }
+}

+ 43 - 0
GxPress/Api/GxPress.Api/AppControllers/AppReportController.cs

@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Common.Tools;
+using GxPress.Entity;
+using GxPress.Repository.Interface.AppReport;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// App数据报表
+    /// </summary>
+    [Route("api/app/app-report")]
+    [ApiController]
+    [Authorize]
+
+    public class AppReportController : ControllerBase
+    {
+        private readonly IAppReportRepository _appReportRepository;
+        public AppReportController(IAppReportRepository appReportRepository)
+        {
+            _appReportRepository = appReportRepository;
+        }
+        /// <summary>
+        /// 查询
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<Entity.AppReport>> GetAppReportList()
+        {
+            var result = await _appReportRepository.GetAppReportListAsync();
+            var appReportList = result as AppReport[] ?? result.ToArray();
+            foreach (var appReport in appReportList)
+            {
+                appReport.IocUrl = StringUtils.AddDomain(appReport.IocUrl);
+            }
+
+            return appReportList;
+        }
+    }
+}

+ 53 - 0
GxPress/Api/GxPress.Api/AppControllers/AppVersionController.cs

@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.AppVersion;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// APP版本管理
+    /// </summary>
+    [Route("api/app/app-version")]
+    [ApiController]
+    [Authorize]
+    public class AppVersionController : ControllerBase
+    {
+        private readonly ILogger<AppVersionController> _logger;
+        private readonly IAppVersionRepository _appVersionRepository;
+
+        public AppVersionController(ILogger<AppVersionController> logger, IAppVersionRepository appVersionRepository)
+        {
+            _logger = logger;
+            _appVersionRepository = appVersionRepository;
+        }
+
+
+        /// <summary>
+        /// app检查是否更新
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("get-version")]
+        [AllowAnonymous]
+        public async Task<AppVersion> GetAppVersion(AppVersionSearchRequest request)
+        {
+            return await _appVersionRepository.GetAppVersionAsync(request);
+        }
+        /// <summary>
+        /// 查询
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("app-list")]
+        [AllowAnonymous]
+        public async Task<IEnumerable<AppVersion>> GetAppVersionsAll()
+        {
+            return await _appVersionRepository.GetAppVersionsAsync();
+        }
+
+    }
+}

+ 123 - 0
GxPress/Api/GxPress.Api/AppControllers/ArticleController.cs

@@ -0,0 +1,123 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.Article;
+using GxPress.Request.BlacklistArticle;
+using GxPress.Result.Article;
+using GxPress.Service.Interface;
+using GxPress.Service.Interface.Article;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using GxPress.Repository.Interface.WorkFlow;
+using GxPress.Request.App.Flow;
+using GxPress.Service.Interface.Visit;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 审批文章/通知
+    /// </summary>
+    [Route("api/app/article")]
+    [ApiController]
+    [Authorize]
+    public class ArticleController : ControllerBase
+    {
+        private readonly IArticleRepository _articleRepository;
+        private readonly IBlacklistArticleRepository _blacklistArticleRepository;
+        private readonly IArticleService _articleService;
+        private readonly ILoginContext _loginContext;
+        private readonly IFlowService _flowService;
+        private readonly IUserRepository _userRepository;
+        private readonly IFlowFieldValueRepository _flowFieldValueRepository;
+        private readonly IVisitService _visitService;
+        public ArticleController(IArticleRepository articleRepository, IBlacklistArticleRepository blacklistArticleRepository,
+            ILoginContext loginContext, IArticleService articleService, IFlowService flowService, IUserRepository userRepository, IFlowFieldValueRepository flowFieldValueRepository, IVisitService visitService)
+        {
+            _articleRepository = articleRepository;
+            _blacklistArticleRepository = blacklistArticleRepository;
+            _loginContext = loginContext;
+            _articleService = articleService;
+            _flowService = flowService;
+            _userRepository = userRepository;
+            _flowFieldValueRepository = flowFieldValueRepository;
+            _visitService = visitService;
+        }
+
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("user-article-list")]
+        public async Task<PagedList<ArticleResult>> GetUserList([FromBody] ArticleSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            //屏蔽文章查询文章
+            var blacklistArticleSearchRequest = new BlacklistArticleSearchRequest { UserId = request.UserId };
+            var blacklistArticles = await _blacklistArticleRepository.GetListAsync(blacklistArticleSearchRequest);
+            var pagedList = await _articleRepository.GetUserListAsync(request, blacklistArticles);
+            foreach (var item in pagedList.Items)
+                item.ReadCount = await _visitService.GetCountAsync(1, item.Id);
+            var resultList = new List<Result.Article.ArticleResult>();
+            if (!string.IsNullOrWhiteSpace(request.Keyword))
+            {
+                //获取代办事项
+                var userId = _loginContext.AccountId;
+                var flowListRequest = new FlowListRequest();
+                flowListRequest.Page = request.Page;
+                flowListRequest.PerPage = request.PerPage;
+                flowListRequest.Keyword = request.Keyword;
+                var flowTodoList = await _flowService.ListMyCheckingAsync(userId, flowListRequest, nameof(GxPress.EnumConst.FlowListTypeConst.MyChecking));
+                foreach (var flowTodo in flowTodoList.Items)
+                {
+                    var result = new Result.Article.ArticleResult
+                    {
+                        Id = flowTodo.Id,
+                        ProcessId = flowTodo.ProcessId,
+                        FlowId = flowTodo.Id,
+                        UserId = flowTodo.UserId,
+                        Type = nameof(GxPress.EnumConst.TodoTypeConst.ApproverCheck),
+                        State = flowTodo.State,
+                        IsDone = false,
+                        CreatedDate = flowTodo.CreatedDate
+                    };
+                    result.Title = flowTodo.Title;
+                    result.AvatarUrl = flowTodo.AvatarUrl;
+                    result.Summaries = flowTodo.Summaries;
+                    result.SourceType = 1;
+                    resultList.Add(result);
+                }
+            }
+            resultList.AddRange(pagedList.Items);
+            pagedList.Total = resultList.Count();
+            pagedList.Items = resultList;
+            return pagedList;
+        }
+
+        /// <summary>
+        /// 文章详情
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("detail/{id}")]
+        public async Task<ArticleResult> Get(int id)
+        {
+            var article = await _articleService.GetAsync(id, _loginContext.AccountId);
+            return article;
+        }
+
+
+        /// <summary>
+        /// 文章详情 web页面
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("web-detail/{id}")]
+        [AllowAnonymous]
+        public async Task<ArticleResult> GetWeb(int id)
+        {
+            var article = await _articleService.GetAsync(id, 0);
+            return article;
+        }
+    }
+}

+ 38 - 0
GxPress/Api/GxPress.Api/AppControllers/ArticleGroupController.cs

@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.ArticleGroup;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 文章组
+    /// </summary>
+    [Route("api/app/article-group")]
+    [ApiController]
+    [Authorize]
+    public class ArticleGroupController : Controller
+    {
+        private readonly IArticleGroupRepository _processGroupRepository;
+        private readonly ILoginContext _loginContext;
+        public ArticleGroupController(IArticleGroupRepository processGroupRepository, ILoginContext loginContext)
+        {
+            
+            _processGroupRepository = processGroupRepository;
+            _loginContext = loginContext;
+        }
+        /// <summary>
+        /// 列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<IEnumerable<ArticleGroup>> GetList()
+        {
+            return await _processGroupRepository.GetListAsync(_loginContext.AccountId);
+        }
+    }
+}

+ 62 - 0
GxPress/Api/GxPress.Api/AppControllers/ArticleGroupUserController.cs

@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Request.ArticleGroupUser;
+using GxPress.Result.ArticleGroupUser;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 我的频道
+    /// </summary>
+    [Route("api/app/article-group-user")]
+    [ApiController]
+    [Authorize]
+    public class ArticleGroupUserController : ControllerBase
+    {
+        private readonly IArticleGroupUserRepository _articleGroupUserRepository;
+        private readonly ILoginContext _loginContext;
+        public ArticleGroupUserController(IArticleGroupUserRepository articleGroupUserRepository,ILoginContext loginContext)
+        {
+            _articleGroupUserRepository = articleGroupUserRepository;
+            _loginContext = loginContext;
+        }
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _articleGroupUserRepository.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Add([FromBody]ArticleGroupUserInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _articleGroupUserRepository.InsertAsync(request)>0;
+        }
+        /// <summary>
+        /// 获取用户的频道
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<ArticleGroupUserListResult>> GetArticleGroupUserListByUserId(
+            [FromBody] ArticleGroupUserSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _articleGroupUserRepository.GetListAsync(request);
+        }
+    }
+}

+ 60 - 0
GxPress/Api/GxPress.Api/AppControllers/BlacklistArticleController.cs

@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Api.AdminControllers;
+using GxPress.Auth;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.BlacklistArticle;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using GxPress.Service.Interface.BlacklistArticle;
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 用户屏蔽文章
+    /// </summary>
+    [Route("api/app/blacklist-article")]
+    [ApiController]
+    [Authorize]
+    public class BlacklistArticleController : ControllerBase
+    {
+        private readonly JwtOptions _jwtOptions;
+        private readonly ILogger<AdminController> _logger;
+        private readonly IBlacklistArticleRepository _blacklistArticleRepository;
+        private readonly ILoginContext _loginContext;
+        private readonly IBlacklistArticleService _blacklistArticleService;
+        public BlacklistArticleController(IOptions<JwtOptions> jwtOptions, ILogger<AdminController> logger, IBlacklistArticleRepository blacklistArticleRepository, ILoginContext loginContext, IBlacklistArticleService blacklistArticleService)
+        {
+            _jwtOptions = jwtOptions.Value;
+            _logger = logger;
+            _blacklistArticleRepository = blacklistArticleRepository;
+            _loginContext = loginContext;
+            _blacklistArticleService = blacklistArticleService;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(BlacklistArticleInRequest request)
+        {
+            var userId = _loginContext.AccountId;
+            return await _blacklistArticleService.InsertAsync(userId, request);
+        }
+
+        /// <summary>
+        /// 查询用户屏蔽文章类型值
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<BlacklistArticle>> GetList()
+        {
+            var request = new BlacklistArticleSearchRequest { UserId = _loginContext.AccountId };
+            return await _blacklistArticleRepository.GetListAsync(request);
+        }
+    }
+}

+ 72 - 0
GxPress/Api/GxPress.Api/AppControllers/BlacklistController.cs

@@ -0,0 +1,72 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.BlacklistUser;
+using GxPress.Service.Interface.IM;
+using GxPress.Service.Interface.OftenContact;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 用户黑名单
+    /// </summary>
+    [Route("api/app/blacklist")]
+    [ApiController]
+    [Authorize]
+    public class BlacklistController : ControllerBase
+    {
+        private readonly ILogger<BlacklistController> _logger;
+        private readonly IBlacklistUserRepository _blacklistUserRepository;
+        private readonly ILoginContext _loginContext;
+        private readonly IOftenContactService _oftenContactService;
+        private readonly IIMService _imService;
+
+        public BlacklistController(ILogger<BlacklistController> logger,
+            IBlacklistUserRepository blacklistUserRepository, ILoginContext loginContext,
+            IOftenContactService oftenContactService, IIMService imService)
+        {
+            _logger = logger;
+            _blacklistUserRepository = blacklistUserRepository;
+            _loginContext = loginContext;
+            _oftenContactService = oftenContactService;
+            _imService = imService;
+        }
+
+        /// <summary>
+        /// 获取黑名单
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<IEnumerable<BlacklistUser>> GetBlacklistUser()
+        {
+            var request = new BlacklistUserSearchRequest { UserId = _loginContext.AccountId };
+            return await _blacklistUserRepository.GetBlacklistUserAsync(request);
+        }
+
+        /// <summary>
+        /// 添加黑名单
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(BlacklistUserInRequest request)
+        {
+            return await _imService.AddBlacklistUserAsync(_loginContext.AccountId, request.UserId);
+        }
+        /// <summary>
+        /// 删除黑名单
+        /// </summary>
+        /// <param name="blackUserId"></param>
+        /// <returns></returns>
+        [HttpDelete("{blackUserId}")]
+        public async Task<bool> Delete(int blackUserId)
+        {
+            return await _imService.ReMoveBlacklistUserAsync(blackUserId, _loginContext.AccountId);
+        }
+    }
+}

+ 56 - 0
GxPress/Api/GxPress.Api/AppControllers/ChatRecordController.cs

@@ -0,0 +1,56 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.ChatRecord;
+using GxPress.Result.App.ChatRecord;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 聊天信息
+    /// </summary>
+    [Route("api/app/chat-record")]
+    [ApiController]
+    [Authorize]
+    public class ChatRecordController : ControllerBase
+    {
+        private readonly ILogger<AppVersionController> _logger;
+        private readonly IChatRecordRepository _chatRecordRepository;
+        private readonly ILoginContext _loginContext;
+
+        public ChatRecordController(ILogger<AppVersionController> logger, IChatRecordRepository chatRecordRepository,ILoginContext loginContext)
+        {
+            _logger = logger;
+            _chatRecordRepository = chatRecordRepository;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 添加聊天信息
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(ChatRecordInRequest request)
+        {
+            request.SendUserId = _loginContext.AccountId;
+            return await _chatRecordRepository.InsertAsync(request);
+        }
+
+        /// <summary>
+        /// 聊天消息查询
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("history")]
+        public  async Task<PagedList<ChatRecordSearchHistoryResult>> SearchChatRecordHistoryAsync(ChatRecordSearchHistoryRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _chatRecordRepository.SearchChatRecordHistoryAsync(request);
+        }
+    }
+}

+ 67 - 0
GxPress/Api/GxPress.Api/AppControllers/CollectionController.cs

@@ -0,0 +1,67 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Request.App.Collection;
+using GxPress.Result.App.Collection;
+using GxPress.Service.Interface.Collection;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 收藏
+    /// </summary>
+    [Route("api/app/collection")]
+    [ApiController]
+    [Authorize]
+    public class CollectionController : ControllerBase
+    {
+        private readonly ILogger<CollectionController> _logger;
+        private readonly ICollectionService _collectionService;
+        private readonly ILoginContext _loginContext;
+
+
+        public CollectionController(ILogger<CollectionController> logger, ICollectionService collectionService, ILoginContext loginContext)
+        {
+            _logger = logger;
+            _collectionService = collectionService;
+            _loginContext = loginContext;
+        }
+        /// <summary>
+        /// 添加收藏
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> Insert(CollectionInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _collectionService.Insert(request);
+        }
+        /// <summary>
+        /// 收藏
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<PagedList<CollectionListPageResult>> PageList(CollectionPageSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _collectionService. PageListAsync(request);
+        }
+
+        /// <summary>
+        /// 获取收藏详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+
+        public async Task<CollectionResult> GetCollectionDetail(int id)
+        {
+            return await _collectionService.GetCollectionDetailAsync(id);
+        }
+    }
+}

+ 63 - 0
GxPress/Api/GxPress.Api/AppControllers/CommentController.cs

@@ -0,0 +1,63 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.Comment;
+using GxPress.Result.Comment;
+using Microsoft.AspNetCore.Mvc;
+using GxPress.Common.Exceptions;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 评论
+    /// </summary>
+    [Route("api/app/comment")]
+    [ApiController]
+    public class CommentController : ControllerBase
+    {
+        private readonly ICommentRepository _commentRepository;
+        private readonly ILoginContext _loginContext;
+        public CommentController(ICommentRepository commentRepository, ILoginContext loginContext)
+        {
+            _commentRepository = commentRepository;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 添加评论
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Add([FromBody] CommentInRequest request)
+        {
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            request.UserId = _loginContext.AccountId;
+            if (string.IsNullOrWhiteSpace(request.Content))
+                throw new BusinessException("评论内容为空");
+            return await _commentRepository.CommentInAsync(request) > 0;
+        }
+        /// <summary>
+        /// 分页显示数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<CommentPageResult>> GetPagedList([FromBody] CommentSearchPageRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _commentRepository.GetPagedList(request);
+        }
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpDelete("delete")]
+        public async Task<bool> Delete([FromBody] CommentDeleteRequest request)
+        {
+            return await _commentRepository.DeleteCommentAsync(request);
+        }
+    }
+}

+ 33 - 0
GxPress/Api/GxPress.Api/AppControllers/DepartmentController.cs

@@ -0,0 +1,33 @@
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.Department;
+using GxPress.Result.Department;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/department")]
+    [ApiController]
+    [Authorize]
+    public class DepartmentController : ControllerBase
+    {
+        private readonly IDepartmentRepository _departmentRepository;
+
+        public DepartmentController(IDepartmentRepository departmentRepository)
+        {
+            _departmentRepository = departmentRepository;
+        }
+
+        /// <summary>
+        /// 根据部门ID获取成员以及下级部门
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("user-list")]
+        public async Task<DepartmentUserResult> GetDepartmentUserResult(DepartmentUserRequest request)
+        {
+            return await _departmentRepository.GetDepartmentUserResultAsync(request);
+        }
+    }
+}

+ 55 - 0
GxPress/Api/GxPress.Api/AppControllers/ElasticsSearchController.cs

@@ -0,0 +1,55 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Common.Tools;
+using GxPress.Request.App.ElasticSearch;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/elastics")]
+    [ApiController]
+    [Authorize]
+    public class ElasticsSearchController : ControllerBase
+    {
+        private readonly ILoginContext _loginContext;
+        public ElasticsSearchController(ILoginContext loginContext)
+        {
+            _loginContext = loginContext;
+        }
+        /// <summary>
+        /// 删除
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<Nest.Result> Delete(string id)
+        {
+            var elasticsSearchHelper = new ElasticSearchHelper();
+            return await elasticsSearchHelper.Delete(id);
+        }
+        /// <summary>
+        /// 搜索结果
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<PagedList<TedeData>> Search(ElasticSearchRequest request)
+        {
+            var elasticsSearchHelper = new ElasticSearchHelper();
+            var searchResult = await elasticsSearchHelper.SearchAsync(request.Key,request.SearchType,_loginContext.AccountId,request.Page,request.PerPage);
+            return searchResult;
+        }
+        /// <summary>
+        /// 根据ID查询
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<TedeData> Get(string id)
+        {
+            var elasticsSearchHelper = new ElasticSearchHelper();
+            return await elasticsSearchHelper.Get(id);
+        }
+    }
+}

+ 57 - 0
GxPress/Api/GxPress.Api/AppControllers/FeedbackController.cs

@@ -0,0 +1,57 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Feedback;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 意见反馈
+    /// </summary>
+    [Route("api/app/Feedback")]
+    [ApiController]
+    [Authorize]
+    public class FeedbackController : ControllerBase
+    {
+        private readonly ILogger<AppVersionController> _logger;
+        private readonly IFeedbackRepository _feedbackRepository;
+        private readonly ILoginContext _loginContext;
+        public FeedbackController(ILogger<AppVersionController> logger, IFeedbackRepository feedbackRepository,ILoginContext loginContext)
+        {
+            _logger = logger;
+            _feedbackRepository = feedbackRepository;
+            _loginContext = loginContext;
+        }
+
+        ///// <summary>
+        ///// 查询分页数据
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost("page")]
+        //[AllowAnonymous]
+        //public async Task<PagedList<FeedbackPageResult>> GetPageList([FromBody] FeedbackPageRequest request)
+        //{
+        //    return await _feedbackRepository.GetPagedList(request);
+        //}
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> Add([FromBody] FeedbackInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var feedback = new Feedback
+            {
+                UserId = request.UserId, Content = request.Content, FeedbackType = request.FeedbackType
+            };
+            return await _feedbackRepository.InsertAsync(feedback) > 0;
+        }
+    }
+}

+ 232 - 0
GxPress/Api/GxPress.Api/AppControllers/FileController.cs

@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Tools;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.FileLibrary;
+using GxPress.Result.App.FileLibrary;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using GxPress.Service.Interface.FileLibrary;
+using GxPress.Repository.Interface.VerificationCode;
+using Datory;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/file")]
+    [ApiController]
+    [Authorize]
+    public class FileController : ControllerBase
+    {
+        private readonly IWebHostEnvironment _environment;
+        private readonly IFileLibraryRepository _fileLibraryRepository;
+        private readonly IFileLibraryService fileLibraryService;
+        private readonly ILoginContext _loginContext;
+        private readonly IVerificationCodeRepository verificationCodeRepository;
+        public FileController(IWebHostEnvironment environment, IFileLibraryRepository fileLibraryRepository, ILoginContext loginContext, IFileLibraryService fileLibraryService, IVerificationCodeRepository verificationCodeRepository)
+        {
+            _environment = environment;
+            _fileLibraryRepository = fileLibraryRepository;
+            _loginContext = loginContext;
+            this.fileLibraryService = fileLibraryService;
+            this.verificationCodeRepository = verificationCodeRepository;
+        }
+
+        /// <summary>
+        /// App上传
+        /// </summary>
+        /// <param name="file"></param>
+        /// <returns></returns>
+        [AllowAnonymous]
+        [HttpPost("upload")]
+        public async Task<ResultPath> Upload(IFormFile file)
+        {
+            if (file == null) throw new BusinessException("请选择需要上传的文件");
+            byte[] bytes;
+            await using (var ms = new MemoryStream())
+            {
+                file.CopyTo(ms);
+                bytes = ms.ToArray();
+            }
+            var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), file.FileName,
+                bytes);
+            saveResult.AbsolutePath = Request.Scheme + "://" + Request.Host.Host +
+                                      (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
+                                      saveResult.RelativePath;
+            saveResult.FileName = file.FileName;
+            saveResult.FileType = saveResult.FileName.Split('.')[saveResult.FileName.Split('.').Length - 1];
+            //图片种类
+            string imageType =
+                "bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,wmf,webp";
+            var imageTypeList = StringUtils.StringCollectionToStringList(imageType);
+            if (imageTypeList.Contains(saveResult.FileType.ToLower()))
+            {
+                saveResult.FileType = "image";
+                saveResult.MinAbsolutePath = StringUtils.AddDomainMin(saveResult.RelativePath);
+            }
+            //添加
+            var fileLibrary = new FileLibrary
+            {
+                FileName = saveResult.FileName,
+                FileType = saveResult.FileType,
+                FileUrl = saveResult.RelativePath,
+                UserId = 0,
+                Size = file.Length
+            };
+            saveResult.Size = file.Length;
+            saveResult.FileId = await fileLibraryService.InsertAsync(fileLibrary);
+            return saveResult;
+        }
+
+        /// <summary>
+        /// App多文件上传
+        /// </summary>
+        /// <param name="file"></param>
+        /// <returns></returns>
+        [HttpPost("uploads")]
+        [AllowAnonymous]
+        public async Task<List<ResultPath>> Uploads(List<IFormFile> file)
+        {
+            if (file == null) throw new BusinessException("请选择需要上传的文件");
+            List<ResultPath> result = new List<ResultPath>();
+            foreach (var item in file)
+            {
+                byte[] bytes;
+                await using (var ms = new MemoryStream())
+                {
+                    item.CopyTo(ms);
+                    bytes = ms.ToArray();
+                }
+
+                var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), item.FileName,
+                    bytes);
+                saveResult.AbsolutePath = Request.Scheme + "://" + Request.Host.Host +
+                                          (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
+                                          saveResult.RelativePath;
+                saveResult.FileName = item.FileName;
+                saveResult.FileType = item.FileName.Split('.')[item.FileName.Split('.').Length - 1];
+                //图片种类
+                string imageType =
+                    "bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,wmf,webp";
+                var imageTypeList = StringUtils.StringCollectionToStringList(imageType);
+                if (imageTypeList.Contains(saveResult.FileType.ToLower()))
+                {
+                    saveResult.MinAbsolutePath = StringUtils.AddDomainMin(saveResult.RelativePath);
+                    if (saveResult.FileType.ToLower() == "webp")
+                        saveResult = Common.Tools.FileHelper.WebPToImage(StringUtils.GetWebRootPath(_environment.WebRootPath), item.FileName,saveResult,Request.Scheme + "://" + Request.Host.Host +
+                                          (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty));
+                    saveResult.FileType = "image";
+                }
+                //添加
+                var fileLibrary = new FileLibrary
+                {
+                    FileName = saveResult.FileName,
+                    FileType = saveResult.FileType,
+                    FileUrl = saveResult.RelativePath,
+                    UserId = 0,
+                    Size = item.Length
+                };
+                saveResult.Size = item.Length;
+                saveResult.FileId = await _fileLibraryRepository.InsertAsync(fileLibrary);
+                result.Add(saveResult);
+            }
+
+            return result;
+        }
+
+
+        /// <summary>
+        /// 根据ID查询文件数据
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<FileLibraryResult> GetFileLibraryById(int id)
+        {
+            return await _fileLibraryRepository.GetFileLibraryByIdAsync(id);
+        }
+
+        /// <summary>
+        /// 根据ID获取文件数据
+        /// </summary>
+        /// <param name="ids"></param>
+        /// <returns></returns>
+        [HttpPost("find")]
+        public async Task<IEnumerable<FileLibraryResult>> GetFileLibraryByIds([FromBody] GetFileLibraryByIdsRequest ids)
+        {
+            return await _fileLibraryRepository.GetFileLibraryByIdsAsync(ids.FileLibraryByIds);
+        }
+
+        /// <summary>
+        /// App多文件上传
+        /// </summary>
+        /// <param name="file"></param>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        [HttpPost("upload-files")]
+        [AllowAnonymous]
+        public async Task<List<ResultPath>> UploadFiles(List<IFormFile> file, [FromForm] string code)
+        {
+            if (string.IsNullOrWhiteSpace(code))
+                throw new BusinessException("code无效或为空值");
+            if (file == null) throw new BusinessException("请选择需要上传的文件");
+            //获取verificationCode
+            var verificationCode = await verificationCodeRepository.GetAsync(Q.Where(nameof(Entity.VerificationCode.VerificationCode.Code), code).OrderByDesc(nameof(Entity.VerificationCode.VerificationCode.CreatedDate)));
+            if (verificationCode == null)
+                throw new BusinessException("验证码无效");
+            var verificationCodeTime = Convert.ToDateTime(verificationCode.CreatedDate).AddMinutes(verificationCode.ExpireTime);
+            if (verificationCodeTime < DateTime.Now)
+                throw new BusinessException("验证码已经过期");
+            List<ResultPath> result = new List<ResultPath>();
+            foreach (var item in file)
+            {
+
+                byte[] bytes;
+                await using (var ms = new MemoryStream())
+                {
+                    item.CopyTo(ms);
+                    bytes = ms.ToArray();
+                }
+
+                var saveResult = FileHelper.SaveFile(StringUtils.GetWebRootPath(_environment.WebRootPath), item.FileName,
+                    bytes);
+                saveResult.AbsolutePath = Request.Scheme + "://" + Request.Host.Host +
+                                          (Request.Host.Port > 0 ? $":{Request.Host.Port}" : string.Empty) +
+                                          saveResult.RelativePath;
+                saveResult.FileName = item.FileName;
+                saveResult.FileType = item.FileName.Split('.')[item.FileName.Split('.').Length - 1];
+                //图片种类
+                string imageType =
+                    "bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,wmf,webp";
+                var imageTypeList = StringUtils.StringCollectionToStringList(imageType);
+                if (imageTypeList.Contains(saveResult.FileType.ToLower()))
+                {
+                    saveResult.FileType = "image";
+                    saveResult.MinAbsolutePath = StringUtils.AddDomainMin(saveResult.RelativePath);
+                }
+                //
+                //添加
+                var fileLibrary = new FileLibrary
+                {
+                    FileName = saveResult.FileName,
+                    FileType = saveResult.FileType,
+                    FileUrl = saveResult.RelativePath,
+                    UserId = verificationCode.UserId,
+                    Size = item.Length
+                };
+                saveResult.Size = item.Length;
+                saveResult.FileId = await fileLibraryService.InsertAsync(fileLibrary);
+                result.Add(saveResult);
+            }
+
+            return result;
+        }
+    }
+}

+ 36 - 0
GxPress/Api/GxPress.Api/AppControllers/FinanceController.cs

@@ -0,0 +1,36 @@
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.Finance;
+using GxPress.Result.Finance;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// APP财务数据
+    /// </summary>
+    [Route("api/app/finance")]
+    [ApiController]
+    public class FinanceController : ControllerBase
+    {
+        private readonly ILogger<FinanceController> _logger;
+        private readonly IFinanceRepository _repository;
+
+        public FinanceController(ILogger<FinanceController> logger, IFinanceRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+        /// <summary>
+        /// 财务图表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        public async Task<FinanceResult> GetFinanceChart(FinanceRequest request)
+        {
+            return await _repository.GetFinanceChartAsync(request);
+        }
+    }
+}

+ 190 - 0
GxPress/Api/GxPress.Api/AppControllers/GroupChatController.cs

@@ -0,0 +1,190 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.IM;
+using GxPress.Request.GroupChat;
+using GxPress.Result.App.GroupChat;
+using GxPress.Service.Interface;
+using GxPress.Service.Interface.AdminVerify;
+using GxPress.Service.Interface.IM;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 群
+    /// </summary>
+    [Route("api/app/group-chat")]
+    [ApiController]
+    [Authorize]
+    public class GroupChatController : ControllerBase
+    {
+        private readonly IGroupChatRepository _groupChatRepository;
+        private readonly IGroupChatUserRepository _groupChatUserRepository;
+        private readonly IIMService _imService;
+        private readonly ILoginContext _loginContext;
+        private readonly IAdminVerifyService _adminVerifyService;
+        private readonly IGroupChatUserService _groupChatUserService;
+
+        public GroupChatController(IGroupChatRepository groupChatRepository, ILoginContext loginContext,
+            IIMService imService, IAdminVerifyService adminVerifyService,
+            IGroupChatUserRepository groupChatUserRepository, IGroupChatUserService groupChatUserService)
+        {
+            _groupChatRepository = groupChatRepository;
+            _imService = imService;
+            _loginContext = loginContext;
+            _adminVerifyService = adminVerifyService;
+            _groupChatUserRepository = groupChatUserRepository;
+            _groupChatUserService = groupChatUserService;
+        }
+        ///// <summary>
+        ///// 添加
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost("add")]
+        //public async Task<bool> Insert(GroupChatInRequest request)
+        //{
+        //    request.UserId = _loginContext.AccountId;
+        //    return await _groupChatRepository.InsertAsync(request);
+        //}
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update")]
+        public async Task<bool> Update(GroupChatUpRequest request)
+        {
+            return await _groupChatRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 群组解散群
+        /// </summary>
+        /// <param name="groupChatImId"></param>
+        /// <returns></returns>
+        [HttpDelete("{groupChatImId}")]
+        public async Task<bool> DeleteGroupChat(string groupChatImId)
+        {
+            return await _imService.DeleteGroupChatAsync(groupChatImId, _loginContext.AccountId);
+        }
+        /// <summary>
+        /// 根据UserId查询群
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("group-chat-search")]
+        public async Task<IEnumerable<GroupChat>> GetGroupChatByUserId()
+        {
+            var request = new GroupChatSearchRequest { UserId = _loginContext.AccountId };
+            return await _groupChatRepository.GetGroupChatByUserIdAsync(request);
+        }
+
+        /// <summary>
+        /// 是否管理员同意
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("up-is-admin")]
+        public async Task<bool> UpIsAdmin(GroupChatUpIsAdminRequest request)
+        {
+            return await _groupChatRepository.UpIsAdminAsync(request);
+        }
+
+        /// <summary>
+        /// 创建群
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<GroupChatInfoResult> CreateGroupChat(GroupChatInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            //添加群成员
+            var insertGroupChatUsersRequest = new InsertGroupChatUsersRequest();
+            insertGroupChatUsersRequest.UserId = request.UserId;
+            insertGroupChatUsersRequest.UserIds = request.UserIds;
+            insertGroupChatUsersRequest.SourceType = 2;
+            //创建群
+            var result = await _imService.CreateGroupChatAsync(request);
+            if (result.Success)
+            {
+                insertGroupChatUsersRequest.GroupChatImId = result.GroupChatImId;
+                insertGroupChatUsersRequest.IsFound = true;
+                await _groupChatUserService.InsertAsync(insertGroupChatUsersRequest);
+                //获取群信息
+                return await _groupChatRepository.GetGroupChatInfoByImIdAsync(result.GroupChatImId);
+            }
+            return new GroupChatInfoResult();
+        }
+
+        /// <summary>
+        /// 添加群用户
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add-users")]
+        public async Task<bool> InsertGroupChatUsers(InsertGroupChatUsersRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _groupChatUserService.InsertAsync(request);
+        }
+
+        /// <summary>
+        /// 群删除成员
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("remove-users")]
+        public async Task<bool> RemoveGroupChatUsers(InsertGroupChatUsersRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _imService.RemoveGroupChatUsersAsync(request);
+        }
+        /// <summary>
+        /// 禁言
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("in-mute")]
+        public async Task<bool> InMute(SetGroupChatMuteRequest request)
+        {
+            return await _imService.InMute(request.GroupChatImId);
+        }
+        /// <summary>
+        /// 解除禁言
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("remove-mute")]
+        public async Task<bool> RemoveMute(SetGroupChatMuteRequest request)
+        {
+            return await _imService.RemoveMute(request.GroupChatImId);
+        }
+        /// <summary>
+        /// 根据groupChatGuid获取群信息
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("guid")]
+        public async Task<GroupChat> GetGroupChatByGuid(GroupChatByGuidRequest request)
+        {
+            return await _groupChatRepository.GetGroupChatByGuidAsync(request.GroupChatGuid);
+        }
+
+        /// <summary>
+        /// set群是否开启
+        /// </summary>
+        /// <param name="groupChatImId"></param>
+        /// <returns></returns>
+        [HttpPut("{groupChatImId}")]
+        public async Task<bool> SetIsOpenQrCoder(string groupChatImId)
+        {
+            return await _groupChatRepository.SetIsOpenQrCoderAsync(groupChatImId, _loginContext.AccountId);
+        }
+    }
+}

+ 157 - 0
GxPress/Api/GxPress.Api/AppControllers/GroupChatUserController.cs

@@ -0,0 +1,157 @@
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Tools;
+using GxPress.Repository.Interface;
+using GxPress.Request.GroupChatUser;
+using GxPress.Result.GroupChatUser;
+using GxPress.Service.Interface;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 群聊组员
+    /// </summary>
+    [Route("api/app/group-chat-user")]
+    [ApiController]
+    [Authorize]
+    public class GroupChatUserController : ControllerBase
+    {
+        private readonly IGroupChatUserRepository _groupChatUserRepository;
+        private readonly IGroupChatUserService _groupChatUserService;
+        private readonly IGroupChatRepository _groupChatRepository;
+        private readonly IOftenContactRepository _oftenContactRepository;
+        private readonly ILoginContext _loginContext;
+
+        public GroupChatUserController(IGroupChatUserRepository groupChatUserRepository,
+            IGroupChatUserService groupChatUserService, IGroupChatRepository groupChatRepository,
+            ILoginContext loginContext, IOftenContactRepository oftenContactRepository)
+        {
+            _groupChatUserRepository = groupChatUserRepository;
+            _groupChatUserService = groupChatUserService;
+            _groupChatRepository = groupChatRepository;
+            _loginContext = loginContext;
+            _oftenContactRepository = oftenContactRepository;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(GroupChatUserInRequest request)
+        {
+            return await _groupChatUserRepository.InsertAsync(request);
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update")]
+        public async Task<bool> Update(GroupChatUserUpRequest request)
+        {
+            return await _groupChatUserRepository.UpdateAsync(request);
+        }
+
+
+
+        /// <summary>
+        /// 根据群ID查询群
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("group-chat-user-search")]
+        public async Task<GroupChatUserByGroupChatIdResultList> GetGroupChatUserByGroupChatId(
+            GroupChatUserSearchRequest request)
+        {
+            var userId = _loginContext.AccountId;
+            var groupChat = await _groupChatRepository.GetGroupChatByImIdAsync(request.GroupChatImId);
+            if (groupChat == null)
+                throw new BusinessException("群不存在!");
+            var result = new GroupChatUserByGroupChatIdResultList
+            {
+                GroupChat = groupChat,
+                Item = await _groupChatUserRepository.GetGroupChatUserByGroupChatIdAsync(request)
+            };
+            //判断是否是管理员
+            result.GroupChat.IsAdmin = result.GroupChat.UserId == _loginContext.AccountId;
+            //result.GroupChat.AvatarUrl = StringUtils.AddDomainMin(result.GroupChat.AvatarUrl);
+             //result.GroupChat.QRCoder = StringUtils.AddDomain(result.GroupChat.QRCoder);
+            result.IsAdmin = result.GroupChat.UserId == _loginContext.AccountId;
+            result.IsUser = result.Item.Any(n => n.UserId == userId);
+            result.IsTop = await _oftenContactRepository.GetIsTopAsync(userId, groupChat.GroupChatImId);
+            var groupChatUserIsDisturbRequest = new GroupChatUserIsDisturbRequest
+            {
+                UserId = userId,
+                GroupChatId = groupChat.Id
+            };
+            result.IsDisturb = await _groupChatUserRepository.IsDisturbAsync(groupChatUserIsDisturbRequest);
+            return result;
+        }
+
+        /// <summary>
+        /// 根据群GUID查询群
+        /// </summary>
+        /// <param name="guid"></param>
+        /// <returns></returns>
+        [HttpGet("{guid}")]
+        public async Task<GroupChatUserByGroupChatIdResultList> GetGroupChatUserByGroupChatGuid(string guid)
+        {
+            var userId = _loginContext.AccountId;
+            var groupChatUserSearchRequest = new GroupChatUserSearchRequest();
+            var groupChat = await _groupChatRepository.GetGroupChatByGuidAsync(guid);
+            if (groupChat == null)
+                throw new BusinessException("群不存在!");
+            groupChatUserSearchRequest.GroupChatImId = groupChat.GroupChatImId;
+            var result = new GroupChatUserByGroupChatIdResultList
+            {
+                GroupChat = groupChat,
+                Item = await _groupChatUserRepository.GetGroupChatUserByGroupChatIdAsync(groupChatUserSearchRequest)
+            };
+            //判断是否是管理员
+            result.GroupChat.IsAdmin = result.GroupChat.UserId == _loginContext.AccountId;
+            result.GroupChat.AvatarUrl = StringUtils.AddDomainMin(result.GroupChat.AvatarUrl);
+            result.GroupChat.QRCoder = StringUtils.AddDomain(result.GroupChat.QRCoder);
+            result.IsAdmin = result.GroupChat.UserId == _loginContext.AccountId;
+            result.IsUser = result.Item.Any(n => n.UserId == userId);
+            result.IsTop = await _oftenContactRepository.GetIsTopAsync(userId, groupChat.GroupChatImId);
+            var groupChatUserIsDisturbRequest = new GroupChatUserIsDisturbRequest
+            {
+                UserId = userId,
+                GroupChatId = groupChat.Id
+            };
+            result.IsDisturb = await _groupChatUserRepository.IsDisturbAsync(groupChatUserIsDisturbRequest);
+            return result;
+        }
+
+        /// <summary>
+        /// 是否免打扰
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("up-is-disturb")]
+        public async Task<bool> UpIsDisturb(GroupChatUserIsDisturbRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _groupChatUserRepository.UpIsDisturbAsync(request);
+        }
+
+        /// <summary>
+        /// 是否置顶
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("up-is-top")]
+        public async Task<bool> UpIsTop(GroupChatUserIsTopRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _groupChatUserRepository.UpIsTopAsync(request);
+        }
+    }
+}

+ 223 - 0
GxPress/Api/GxPress.Api/AppControllers/GroupController.cs

@@ -0,0 +1,223 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.Group;
+using GxPress.Request.App.GroupUser;
+using GxPress.Request.App.Topic;
+using GxPress.Result.App.Group;
+using GxPress.Result.App.GroupUser;
+using GxPress.Result.App.Topic;
+using GxPress.Service.Interface.Group;
+using GxPress.Service.Interface.Topic;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 小组
+    /// </summary>
+    [Route("api/app/group")]
+    [ApiController]
+    [Authorize]
+    public class GroupController : ControllerBase
+    {
+        private readonly ILogger<GroupController> _logger;
+        private readonly IGroupRepository _groupRepository;
+        private readonly IGroupUserRepository _groupUserRepository;
+        private readonly IGroupFolderRepository _groupFolderRepository;
+        private readonly IGroupService _groupService;
+        private readonly ILoginContext _loginContext;
+        private readonly ITopicRepository _topicRepository;
+        private readonly ITopicService _topicService;
+
+        public GroupController(ILogger<GroupController> logger, IGroupRepository groupRepository,
+            IGroupFolderRepository groupFolderRepository, IGroupUserRepository groupUserRepository,
+            ILoginContext loginContext, IGroupService groupService, ITopicRepository topicRepository, ITopicService topicService)
+        {
+            _logger = logger;
+            _groupFolderRepository = groupFolderRepository;
+            _groupRepository = groupRepository;
+            _groupUserRepository = groupUserRepository;
+            _loginContext = loginContext;
+            _groupService = groupService;
+            _topicRepository = topicRepository;
+            _topicService = topicService;
+        }
+
+        /// <summary>
+        /// 新建小组
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("insert")]
+        public async Task<GroupDetailResult> Insert(GroupInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var result = await _groupService.InsertGroup(request);
+            //插入小组用户
+            if (result.Id > 0 && request.UserIds.Count > 0)
+            {
+                var groupUserInRequest = new GroupUserInRequest();
+                groupUserInRequest.UserId = request.UserId;
+                groupUserInRequest.UserIds = request.UserIds;
+                groupUserInRequest.SourceType = 2;
+                groupUserInRequest.GroupId = result.Id;
+                await _groupService.InsertsAsync(groupUserInRequest);
+            }
+            return result;
+        }
+
+        /// <summary>
+        ///  添加小组成员
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("insert-user")]
+        public async Task<bool> AddGroupUser(GroupUserInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _groupService.InsertsAsync(request);
+        }
+
+        /// <summary>
+        /// 删除小组成员
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("delete-user")]
+        public async Task<bool> DeleteGroupUser(GroupUserDeRequest request)
+        {
+            return await _groupService.DeleteAsync(request);
+        }
+
+        /// <summary>
+        /// 退出小组
+        /// </summary>
+        /// <param name="groupId"></param>
+        /// <returns></returns>
+        [HttpDelete("{groupId}")]
+        public async Task<bool> DeleteAsync(int groupId)
+        {
+            return await _groupService.DeleteAsync(_loginContext.AccountId, groupId);
+        }
+
+        /// <summary>
+        /// 根据文件夹ID查询小组列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("find")]
+        public async Task<PagedList<GroupUserFindResult>> FindGroupByGroupFolderId(GroupSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _groupService.FindGroupByGroupFolderIdAsync(request);
+        }
+
+        /// <summary>
+        /// 获取小组详情
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("detail")]
+        public async Task<GroupDetailResult> GroupDetailAsync(GroupDetailRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _groupService.GroupDetailAsync(request);
+        }
+
+        /// <summary>
+        /// 修改小组
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update")]
+        public async Task<bool> Update(GroupUpRequest request)
+        {
+            return await _groupRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        ///设置权限
+        /// 1 超级管理员 2 管理员 3普通用户
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update-user")]
+        public async Task<bool> UpdateGroupUser(GroupUserUpRequest request)
+        {
+            return await _groupUserRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 根据GroupId获取话题列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<PagedList<TopicListPageResult>> FindTopicByGroupId(TopicDetailListRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _topicService.FindTopicByGroupIdAsync(request);
+        }
+
+        /// <summary>
+        /// 加入是否管理员同意
+        /// </summary>
+        /// <param name="groupId"></param>
+        /// <returns></returns>
+        [HttpPut("set-admin/{groupId}")]
+        public async Task<bool> SetGroupIsAdmin(int groupId)
+        {
+            return await _groupRepository.SetGroupIsAdminAsync(groupId);
+        }
+        /// <summary>
+        /// 是否禁言
+        /// </summary>
+        /// <param name="groupId"></param>
+        /// <returns></returns>
+        [HttpPut("set-words/{groupId}")]
+        public async Task<bool> SetGroupIsWords(int groupId)
+        {
+            return await _groupRepository.SetGroupIsWordsAsync(groupId);
+        }
+
+        /// <summary>
+        /// 扫描二维码获取小组详情
+        /// </summary>
+        /// <param name="guId"></param>
+        /// <returns></returns>
+        [HttpGet("{guId}")]
+        public async Task<GroupDetailResult> GroupDetailByGuId(string guId)
+        {
+            var userId = _loginContext.AccountId;
+            return await _groupService.GroupDetailByGuIdAsync(guId, userId);
+        }
+
+        /// <summary>
+        /// 设置用户是否免打扰
+        /// </summary>
+        /// <param name="groupId"></param>
+        /// <returns></returns>
+        [HttpPut("set-disturb/{groupId}")]
+        public async Task<bool> SetIsUDisturbAsync(int groupId)
+        {
+            var userId = _loginContext.AccountId;
+            return await _groupUserRepository.SetIsUDisturbAsync(groupId, userId);
+        }
+
+        /// <summary>
+        /// 搜索小组成员
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search-group-user")]
+        public async Task<IEnumerable<GroupUserListResult>> SearchGroupUserAsync(TopicDetailListRequest request)
+        {
+            return await _groupRepository.SearchGroupUserAsync(request);
+        }
+    }
+}

+ 39 - 0
GxPress/Api/GxPress.Api/AppControllers/HumanAffairsController.cs

@@ -0,0 +1,39 @@
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.HumanAffairs;
+using GxPress.Result.HumanAffairs;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// App人事数据
+    /// </summary>
+    [Route("api/app/human-affairs")]
+    [ApiController]
+    [Authorize]
+    public class HumanAffairsController : ControllerBase
+    {
+        private readonly ILogger<AppControllers.HumanAffairsController> _logger;
+        private readonly IHumanAffairsRepository _repository;
+
+        public HumanAffairsController(ILogger<AppControllers.HumanAffairsController> logger, IHumanAffairsRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+        /// <summary>
+        /// App人事图表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        [AllowAnonymous]
+        public async Task<HumanAffairsResult> GetHumanAffairsChart(HumanAffairsRequest request)
+        {
+            return await _repository.GetHumanAffairsChartAsync(request);
+        }
+    }
+}

+ 29 - 0
GxPress/Api/GxPress.Api/AppControllers/ImController.cs

@@ -0,0 +1,29 @@
+using System.Threading.Tasks;
+using GxPress.Request.App.IM;
+using GxPress.Service.Interface.IM;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/im")]
+    [ApiController]
+    public class ImController : ControllerBase
+    {
+        private readonly IIMService _imService;
+
+        public ImController(IIMService imService)
+        {
+            _imService = imService;
+        }
+        /// <summary>
+        /// 强制下线
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("disconnect")]
+        public async Task<bool> Disconnect(DisconnectRequest request)
+        {
+            return await _imService.DisconnectAsync(request.ImId);
+        }
+    }
+}

+ 197 - 0
GxPress/Api/GxPress.Api/AppControllers/MiddleController.cs

@@ -0,0 +1,197 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.Middle;
+using GxPress.Request.Notice;
+using GxPress.Request.NoticeFolder;
+using GxPress.Result.App.Middle;
+using GxPress.Service.Interface.Middle;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 中间件
+    /// </summary>
+    [Route("api/app/middle")]
+    [ApiController]
+    [Authorize]
+    public class MiddleController : ControllerBase
+    {
+        public readonly IMiddleService _middleService;
+        public readonly ILoginContext _loginContext;
+        private readonly IFolderUserRepository _folderUserRepository;
+
+        public MiddleController(IMiddleService middleService, ILoginContext loginContext,
+            IFolderUserRepository folderUserRepository)
+        {
+            _middleService = middleService;
+            _loginContext = loginContext;
+            _folderUserRepository = folderUserRepository;
+        }
+
+        /// <summary>
+        /// 排序
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("sort")]
+        public async Task<bool> MiddleSort(MiddleSortRequest request)
+        {
+            return await _middleService.MiddleSortAsync(request);
+        }
+        /// <summary>
+        /// 创建文件夹
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add-folder")]
+        public async Task<bool> Insert(NoticeFolderInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var middleInsertRequest = new MiddleInsertRequest
+            {
+                FolderName = request.FolderName,
+                FolderType = request.TypeId,
+                ParentId = request.ParentId,
+                UserId = request.UserId,
+                RoleId = request.RoleId,
+                UserIds = request.UserIds,
+                UserMiddles = request.UserMiddles
+            };
+            return await _middleService.InsertAsync(middleInsertRequest) > 0;
+
+        }
+        /// <summary>
+        /// 设置置顶
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpPut("{id}")]
+        public async Task<bool> SetTop(int id)
+        {
+            return await _middleService.SetTopAsync(id);
+        }
+
+        /// <summary>
+        /// 删除记录
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("delete")]
+        public async Task<bool> Delete(NoticeDeRequest request)
+        {
+            var userId = _loginContext.AccountId;
+            request.UserId = userId;
+            return await _middleService.DeleteAsync(request);
+        }
+
+        /// <summary>
+        /// 恢复删除
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("recover-delete")]
+        public async Task<bool> RecoverDelete(NoticeDeRequest request)
+        {
+            return await _middleService.RecoverDeleteAsync(request);
+        }
+        /// <summary>
+        /// 恢复全部
+        /// </summary>
+        /// <param name="folderType">文件夹类型 1 通知 2话题 3 收藏 4笔记 5 普通站内信 6匿名站内信 7小组</param>
+        /// <returns></returns>
+        [HttpPut("recover-all/{folderType}")]
+        public async Task<bool> RecoverAllAsync(int folderType)
+        {
+            return await _middleService.RecoverAllAsync(folderType, _loginContext.AccountId);
+        }
+        /// <summary>
+        /// 删除全部
+        /// </summary>
+        /// <param name="folderType">文件夹类型 1 通知 2话题 3 收藏 4笔记 5 普通站内信 6匿名站内信 7小组</param>
+        /// <returns></returns>
+        [HttpDelete("delete-all/{folderType}")]
+        public async Task<bool> DeleteAllAsync(int folderType)
+        {
+            return await _middleService.DeleteAllAsync(folderType, _loginContext.AccountId);
+        }
+        /// <summary>
+        /// 移动
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("move")]
+        public async Task<bool> SetMove(MiddleMoveRequest request)
+        {
+            return await _middleService.SetMove(request);
+        }
+
+        /// <summary>
+        /// 修改文件夹名称
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update")]
+        public async Task<bool> UpdateFolderName(MiddleFolderNameRequest request)
+        {
+            return await _middleService.UpdateFolderNameAsync(request);
+        }
+
+        /// <summary>
+        /// 查询文件夹
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search-folder")]
+        public async Task<List<MiddleSearchFolderResult>> SearchFolderAsync(MiddleSearchFolderRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _middleService.SearchFolderAsync(request);
+        }
+
+        /// <summary>
+        /// 获取话题 笔记共享范围文件夹
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search-note-folder")]
+        public async Task<List<MiddleSearchFolderResult>> SearchNoteFolderAsync(MiddleSearchFolderRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _middleService.SearchNoteFolderAsync(request);
+        }
+        /// <summary>
+        /// 修改文件夹名称或权限
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("update-role")]
+        public async Task<bool> UpdateFolderRole(MiddleUpdateFolderRoleRequest request)
+        {
+            return await _middleService.UpdateFolderRoleAsync(request);
+        }
+        /// <summary>
+        /// 根据文件夹ID查询文件夹信息
+        /// </summary>
+        /// <param name="middleId"></param>
+        /// <returns></returns>
+        [HttpGet("find-folder-info/{middleId}")]
+        public async Task<MiddleFolderInfoResult> GetFolderUser(int middleId)
+        {
+            return await _middleService.GetFolderInfo(middleId);
+        }
+
+        /// <summary>
+        /// 获取默认的共享文件夹范围
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("enjoy-default/{folderType}")]
+        public async Task<MiddleDefaultResult> GetEnjoyDefault(int folderType)
+        {
+            return await _middleService.GetEnjoyDefaultAsync(_loginContext.AccountId,folderType);
+        }
+    }
+}

+ 136 - 0
GxPress/Api/GxPress.Api/AppControllers/MissiveController.cs

@@ -0,0 +1,136 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Common.Tools;
+using GxPress.Repository.Interface.Missive;
+using GxPress.Request.App.Missive;
+using GxPress.Result.App.Missive;
+using GxPress.Service.Interface.Missive;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System.Linq;
+using System;
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 站内信
+    /// </summary>
+    [Route("api/app/missive")]
+    [ApiController]
+    [Authorize]
+    public class MissiveController : ControllerBase
+    {
+        private readonly IMissiveRepository _missiveRepository;
+        private readonly IMissiveAnalyzeRepository _missiveAnalyzeRepository;
+        private readonly IMissiveService _missiveService;
+        private readonly ILoginContext _loginContext;
+
+        public MissiveController(IMissiveRepository missiveRepository, IMissiveService missiveService,
+            ILoginContext loginContext, IMissiveAnalyzeRepository missiveAnalyzeRepository)
+        {
+            _missiveRepository = missiveRepository;
+            _missiveService = missiveService;
+            _loginContext = loginContext;
+            _missiveAnalyzeRepository = missiveAnalyzeRepository;
+        }
+
+
+        /// <summary>
+        /// 根据站内信ID获取详情
+        /// </summary>
+        /// <param name="missiveId"></param>
+        /// <returns></returns>
+        [HttpGet("get/{missiveId}")]
+        public async Task<MissiveInfoResult> GetMissiveInfo(int missiveId)
+        {
+            return await _missiveService.GetMissiveInfoAsync(missiveId, _loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 添加/修改站内信
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> Insert(MissiveInRequest request)
+        {
+            // request.HtmlContent = StringUtils.RemoveEmoji(request.HtmlContent);
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            // request.Title = StringUtils.RemoveEmoji(request.Title);
+            request.UserId = _loginContext.AccountId;
+            request.MissiveAddresseeUserIds.Remove(request.UserId);
+            request.MissiveCcUserIds.Remove(request.UserId);
+            return await _missiveService.InsertOrUpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 获取站内信列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<PagedList<MissiveSearchResult>> GetMissiveSearchResult(MissiveSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _missiveService.GetMissiveSearchResultAsync(request);
+        }
+
+        /// <summary>
+        ///  文章点赞 评论点赞 文章收藏 文章转发 已废弃
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("analyze")]
+        public async Task<bool> AddMissiveAnalyze([FromBody] MissiveAnalyzeRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _missiveAnalyzeRepository.SetMissiveAnalyzeAsync(request);
+        }
+
+
+        /// <summary>
+        /// 获取站内信详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<MissiveDetailResult> GetMissiveDetail(int id)
+        {
+            return await _missiveService.GetMissiveDetailAsync(id);
+        }
+        /// <summary>
+        /// 获取站内信详情-web专属
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("web/{id}")]
+        [AllowAnonymous]
+        public async Task<MissiveInfoResult> GetWebMissiveDetail(int id)
+        {
+            var missiveInfos = await _missiveService.GetMissiveInfoAsync(id, 0);
+            missiveInfos.Items = missiveInfos.Items.OrderByDescending(n => Convert.ToDateTime(n.CreatedDate)).ToList();
+            return missiveInfos;
+        }
+        /// <summary>
+        /// 获取站内信已读未读数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("read")]
+        public async Task<IEnumerable<MissiveReadListResult>> GetMissiveReadListAsync(MissiveReadListRequest request)
+        {
+            return await _missiveService.GetMissiveReadListAsync(request);
+        }
+
+        /// <summary>
+        /// 站内信撤回
+        /// </summary>
+        /// <param name="missiveId"></param>
+        /// <returns></returns>
+        [HttpPut("recall/{missiveId}")]
+        public async Task<bool> RecallAsync(int missiveId)
+        {
+            return await _missiveService.RecallAsync(missiveId);
+        }
+    }
+}

+ 101 - 0
GxPress/Api/GxPress.Api/AppControllers/NoteController.cs

@@ -0,0 +1,101 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Request.App.Note;
+using GxPress.Result.App.Note;
+using GxPress.Service.Interface.Note;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 个人笔记
+    /// </summary>
+    [Route("api/app/note")]
+    [ApiController]
+    [Authorize]
+    public class NoteController : ControllerBase
+    {
+        private readonly ILogger<NoteController> _logger;
+        private readonly INoteService _noteService;
+        private readonly ILoginContext _loginContext;
+
+        public NoteController(ILogger<NoteController> logger, INoteService noteService, ILoginContext loginContext)
+        {
+            _logger = logger;
+            _noteService = noteService;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 添加笔记
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> InsertNote(NoteInRequest request)
+        {
+            // request.HtmlContent = StringUtils.RemoveEmoji(request.HtmlContent);
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            request.UserId = _loginContext.AccountId;
+            return await _noteService.InsertNoteAsync(request);
+        }
+
+        /// <summary>
+        /// 获取笔记分页
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<PagedList<NotePageListRequest>> NotePageList(NoteSearchPageListRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _noteService.NotePageListAsync(request);
+        }
+        /// <summary>
+        /// 获取笔记详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<NoteDetailResult> GetNoteDetail(int id)
+        {
+            var note = await _noteService.GetNoteDetailAsync(id, _loginContext.AccountId);
+            return note;
+        }
+        /// <summary>
+        /// 获取笔记详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("web/{id}")]
+        public async Task<NoteDetailResult> GetWebNoteDetail(int id)
+        {
+            var note = await _noteService.GetNoteDetailAsync(id, 0);
+            return note;
+        }
+
+        /// <summary>
+        /// 修改笔记
+        /// </summary>
+        /// <param name="note"></param>
+        /// <returns></returns>
+        [HttpPut("update")]
+        public async Task<bool> UpdateNote(Entity.Note.Note note)
+        {
+            // note.HtmlContent = StringUtils.RemoveEmoji(note.HtmlContent);
+            // note.Content = StringUtils.RemoveEmoji(note.Content);
+            // note.Title = StringUtils.RemoveEmoji(note.Title);
+            return await _noteService.UpdateNoteAsync(note);
+        }
+        /// <summary>
+        /// 删除笔记
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> DeleteAsync(int id) => await _noteService.DeleteAsync(id, _loginContext.AccountId);
+    }
+}

+ 151 - 0
GxPress/Api/GxPress.Api/AppControllers/NoticeController.cs

@@ -0,0 +1,151 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Common.Tools;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Notice;
+using GxPress.Request.NoticeAnalyze;
+using GxPress.Result.Notice;
+using GxPress.Service.Interface.Notice;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 通知
+    /// </summary>
+    [Route("api/app/notice")]
+    [ApiController]
+    [Authorize]
+    public class NoticeController : ControllerBase
+    {
+        private readonly INoticeRepository _noticeRepository;
+        private readonly INoticeFolderRepository _noticeFolderRepository;
+        private readonly INoticeService _noticeService;
+        private readonly ILoginContext _loginContext;
+
+        public NoticeController(INoticeRepository noticeRepository, INoticeFolderRepository noticeFolderRepository,INoticeService noticeService, ILoginContext loginContext)
+        {
+            _noticeRepository = noticeRepository;
+            _noticeFolderRepository = noticeFolderRepository;
+            _noticeService = noticeService;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 添加通知
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> Insert(NoticeInRequest request)
+        {
+            // request.HtmlContent = StringUtils.RemoveEmoji(request.HtmlContent);
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            request.UserId = _loginContext.AccountId;
+            var boolValue = await _noticeService.InsertAsync(request);
+            return boolValue;
+        }
+
+        /// <summary>
+        /// 自己删除
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpDelete("delete")]
+        public async Task<bool> Delete(NoticeDeRequest request)
+        {
+            return await _noticeRepository.DeleteAsync(request);
+        }
+        /// <summary>
+        /// 获取通知详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("app-detail/{id}")]
+        public async Task<Result.Notice.NoticeDetailResult> GetNoticeDetailResult(int id)
+        {
+            return await _noticeService.GetNoticeDetailAsync(id, _loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// app通知分页列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list-page")]
+        public async Task<PagedList<NoticeListPageResult>> GetNoticeListPage(NoticePageSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _noticeService.GetNoticeListPageAsync(request);
+        }
+        /// <summary>
+        /// 恢复删除通知
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("recover")]
+        public async Task<bool> RecoverDelete(NoticeDeRequest request)
+        {
+            return await _noticeRepository.RecoverDeleteAsync(request);
+        }
+        /// <summary>
+        /// 详情
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("detail/{id}")]
+        public async Task<NoticeEditDetailResult> Detail(int id)
+        {
+            return await _noticeService.NoticeEditDetailAsync(id);
+        }
+
+        /// <summary>
+        /// 详情 web专属
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("web-detail/{id}")]
+        [AllowAnonymous]
+        public async Task<NoticeEditDetailResult> WebDetail(int id)
+        {
+            return await _noticeService.NoticeEditDetailAsync(id);
+        }
+        /// <summary>
+        /// 修改详情
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("edit")]
+        public async Task<bool> Edit([FromBody] NoticeUpRequest request)
+        {
+            // request.HtmlContent = StringUtils.RemoveEmoji(request.HtmlContent);
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            request.UserId = _loginContext.AccountId;
+            return await _noticeService.NoticeUpAsync(request);
+        }
+        /// <summary>
+        /// 查询通知已读未读信息
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("read")]
+        public async Task<IEnumerable<NoticeReadListResult>> NoticeReadList(NoticeReadListRequest request)
+        {
+            return await _noticeService.NoticeReadListAsync(request);
+        }
+        /// <summary>
+        /// 撤销通知
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpPut("recall/{id}")]
+        public async Task<bool> RecallAsync(int id)
+        {
+            return await _noticeService.RecallAsync(id);
+        }
+    }
+}

+ 118 - 0
GxPress/Api/GxPress.Api/AppControllers/NoticeFolderController.cs

@@ -0,0 +1,118 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.Middle;
+using GxPress.Request.NoticeFolder;
+using GxPress.Result.NoticeFolder;
+using GxPress.Service.Interface.Middle;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 通知文件夹
+    /// </summary>
+    [Route("api/app/notice-folder")]
+    [ApiController]
+    public class NoticeFolderController : ControllerBase
+    {
+
+        private readonly INoticeFolderRepository _noticeFolderRepository;
+        private readonly ILoginContext _loginContext;
+        private readonly IMiddleService _middleService;
+
+        public NoticeFolderController(INoticeFolderRepository noticeFolderRepository, ILoginContext loginContext,
+            IMiddleService middleService)
+        {
+            _noticeFolderRepository = noticeFolderRepository;
+            _loginContext = loginContext;
+            _middleService = middleService;
+        }
+
+        /// <summary>
+        /// 创建通知文件夹
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add")]
+        public async Task<bool> Insert(NoticeFolderInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var middleInsertRequest = new MiddleInsertRequest
+            {
+                FolderName = request.FolderName,
+                FolderType = 1,
+                ParentId = request.ParentId,
+                UserId = request.UserId
+            };
+            return await _middleService.InsertAsync(middleInsertRequest) > 0;
+
+        }
+
+        ///// <summary>
+        ///// 删除通知文件夹
+        ///// </summary>
+        ///// <param name="id"></param>
+        ///// <returns></returns>
+        //[HttpDelete("{id}")]
+        //public async Task<bool> Delete(int id)
+        //{
+        //    return await _noticeFolderRepository.DeleteAsync(id);
+
+        //}
+
+        ///// <summary>
+        ///// 修改通知文件夹
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost("update")]
+        //public async Task<bool> Update(NoticeFolderUpRequest request)
+        //{
+        //    return await _noticeFolderRepository.UpdateAsync(request);
+        //}
+
+        ///// <summary>
+        ///// 插入通知文件夹
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost("add-notice")]
+        //public async Task<bool> InsertNotice(NoticeFolderInNoticeRequest request)
+        //{
+        //    return await _noticeFolderRepository.InsertNoticeAsync(request);
+        //}
+
+        ///// <summary>
+        ///// 文件夹移除通知
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost("remove-notice")]
+        //public async Task<bool> NoticeFolderDeleteNotice(NoticeFolderDeleteNoticeRequest request)
+        //{
+        //    return await _noticeFolderRepository.NoticeFolderDeleteNoticeAsync(request);
+        //}
+        /// <summary>
+        /// 获取通知文件夹
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("find")]
+        public async Task<IEnumerable<NoticeFolderFindResult>> GetNoticeFolderByUserId(NoticeFolderFindRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _noticeFolderRepository.GetNoticeFolderByUserIdAsync(request);
+        }
+        ///// <summary>
+        ///// 设置文件夹置顶
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost("set-is-top")]
+        //public async Task<bool> SetNoticeFolderIsTop(NoticeFolderFindRequest request)
+        //{
+        //    return await _noticeFolderRepository.SetNoticeFolderIsTopAsync(request);
+        //}
+    }
+}

+ 98 - 0
GxPress/Api/GxPress.Api/AppControllers/OftenContactController.cs

@@ -0,0 +1,98 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.OftenContact;
+using GxPress.Result.App.OftenContact;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using GxPress.Service.Interface.OftenContact;
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    ///  好友
+    /// </summary>
+    [Route("api/app/often-contact")]
+    [ApiController]
+    [Authorize]
+    public partial class OftenContactController : ControllerBase
+    {
+        private readonly ILogger<OftenContactController> _logger;
+        private readonly IOftenContactRepository _repository;
+        private readonly ILoginContext _loginContext;
+        private readonly IOftenContactService _oftenContactService;
+        public OftenContactController(ILogger<OftenContactController> logger, IOftenContactRepository repository, ILoginContext loginContext, IOftenContactService oftenContactService)
+        {
+            _logger = logger;
+            _repository = repository;
+            _loginContext = loginContext;
+            _oftenContactService = oftenContactService;
+        }
+
+        /// <summary>
+        /// 根据文件ID获取用户和下面的数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<System.Collections.Generic.IEnumerable<OftenContactInfo>> GetOftenContactsAsync(OftenContactSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _oftenContactService.GetOftenContacts(request);
+        }
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<OftenContactDto> Insert(OftenContactInRequest request)
+        {
+            var result = new OftenContactDto();
+            result = await _oftenContactService.InsertAsync(request, _loginContext.AccountId);
+            return result;
+        }
+        /// <summary>
+        /// /// 移除文件夹关系
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("remove")]
+        public async Task<bool> RemoveOftenContact(OftenContactDeRequest request)
+        {
+            return await _repository.RemoveOftenContactAsync(request);
+        }
+        /// <summary>
+        /// 设置置顶
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("is-top")]
+        public async Task<bool> SetOftenContactIsTop(OftenContactDeRequest request)
+        {
+            return await _repository.SetOftenContactIsTopAsync(request);
+        }
+
+        /// <summary>
+        /// 移动到文件夹
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("move")]
+        public async Task<bool> MoveOftenContactToIndividualGroup(OftenContactUpRequest request)
+        {
+            return await _repository.MoveOftenContactToIndividualGroupAsync(request);
+        }
+
+        /// <summary>
+        /// 删除聊天界面
+        /// </summary>
+        /// <param name="oftenContactIds"></param>
+        /// <returns></returns>
+        [HttpPost("delete")]
+        public async Task<bool> DeleteAsync(OftenContactsDeRequest oftenContactIds)
+        {
+            return await _repository.DeleteAsync(oftenContactIds.OftenContactIds);
+        }
+    }
+}

+ 39 - 0
GxPress/Api/GxPress.Api/AppControllers/PrintController.cs

@@ -0,0 +1,39 @@
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.Print;
+using GxPress.Result.Print;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// App出版数据
+    /// </summary>
+    [Route("api/app/print")]
+    [ApiController]
+    [Authorize]
+    public class PrintController : ControllerBase
+    {
+        private readonly ILogger<AppControllers.PrintController> _logger;
+        private readonly IPrintRepository _repository;
+
+        public PrintController(ILogger<AppControllers.PrintController> logger, IPrintRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+        /// <summary>
+        /// 出版数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        [AllowAnonymous]
+        public async Task<PrintResult> GetSellChart(PrintRequest request)
+        {
+            return await _repository.GetPrintChartAsync(request);
+        }
+    }
+}

+ 39 - 0
GxPress/Api/GxPress.Api/AppControllers/SellController.cs

@@ -0,0 +1,39 @@
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.Sell;
+using GxPress.Result.sell;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// APP发行数据
+    /// </summary>
+    [Route("api/app/sell")]
+    [ApiController]
+    [Authorize]
+    public class SellController : ControllerBase
+    {
+        private readonly ILogger<AppControllers.SellController> _logger;
+        private readonly ISellRepository _repository;
+
+        public SellController(ILogger<AppControllers.SellController> logger, ISellRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+        /// <summary>
+        /// 发行图表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        [AllowAnonymous]
+        public async Task<SellResult> GetSellChart(SellRequest request)
+        {
+            return await _repository.GetSellChartAsync(request);
+        }
+    }
+}

+ 40 - 0
GxPress/Api/GxPress.Api/AppControllers/ShareController.cs

@@ -0,0 +1,40 @@
+using GxPress.Auth;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 分享
+    /// </summary>
+    [Route("api/app/share")]
+    [ApiController]
+    [Authorize]
+    public class ShareController : ControllerBase
+    {
+        private readonly ILoginContext _loginContext;
+        public ShareController(ILoginContext loginContext)
+        {
+            _loginContext = loginContext;
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="typeId"></param>
+        /// <param name="sourceId"></param>
+        /// <returns></returns>
+        [HttpGet("url")]
+        public ShareDto GetShareUrl([FromQuery]int typeId, [FromQuery] int sourceId)
+        {
+            var shareDto = new ShareDto();
+            return shareDto;
+        }
+    }
+    /// <summary>
+    /// 共享
+    /// </summary>
+    public class ShareDto
+    {
+        public string Url { get; set; }
+    }
+}

+ 44 - 0
GxPress/Api/GxPress.Api/AppControllers/SlideController.cs

@@ -0,0 +1,44 @@
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Common.Page;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 审批轮播
+    /// </summary>
+    [Route("api/app/slide")]
+    [ApiController]
+    [Authorize]
+    public class SlideController : ControllerBase
+    {
+        private readonly ISlideRepository _slideRepository;
+
+        public SlideController(ISlideRepository slideRepository)
+        {
+            _slideRepository = slideRepository;
+        }
+
+      
+        /// <summary>
+        /// App列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("list")]
+        public async Task<PagedList<Slide>> GetList()
+        {
+            var pagedList =new PagedList<Slide>();
+            var result = await _slideRepository.GetListAsync();
+            var pagedListItems = result as Slide[] ?? result.ToArray();
+            pagedList.Items = pagedListItems;
+            pagedList.Total = pagedListItems.Count();
+            return pagedList;
+        }
+
+
+    }
+}

+ 39 - 0
GxPress/Api/GxPress.Api/AppControllers/StorehouseController.cs

@@ -0,0 +1,39 @@
+using System.Threading.Tasks;
+using GxPress.Repository.Interface;
+using GxPress.Request.Storehouse;
+using GxPress.Result.Storehouse;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// APP仓库数据
+    /// </summary>
+    [Route("api/app/storehouse")]
+    [ApiController]
+    [Authorize]
+    public class StorehouseController : ControllerBase
+    {
+        private readonly ILogger<StorehouseController> _logger;
+        private readonly IStorehouseRepository _repository;
+
+        public StorehouseController(ILogger<StorehouseController> logger, IStorehouseRepository repository)
+        {
+            _logger = logger;
+            _repository = repository;
+        }
+        /// <summary>
+        /// 库存图标
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("chart")]
+        [AllowAnonymous]
+        public async Task<StorehouseResult> GetStorehouseChart(StorehouseRequest request)
+        {
+            return await _repository.GetStorehouseChartAsync(request);
+        }
+    }
+}

+ 28 - 0
GxPress/Api/GxPress.Api/AppControllers/TestController.cs

@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Service.Interface.Doc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/test")]
+    [ApiController]
+    [Authorize]
+    public class TestController : ControllerBase
+    {
+        private readonly IDocService docService;
+        private readonly ILoginContext _loginContext;
+        public TestController(IDocService docService, ILoginContext loginContext)
+        {
+            this.docService = docService;
+            _loginContext = loginContext;
+        }
+        [HttpGet("{id}")]
+        public async Task<bool> MakeDoc(int id)
+        {
+            await docService.MakeDoc(id, _loginContext.AccountId);
+            return true;
+        }
+    }
+}

+ 39 - 0
GxPress/Api/GxPress.Api/AppControllers/ThesaurusController.cs

@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GxPress.Entity;
+using GxPress.Repository.Interface;
+using GxPress.Request.Thesaurus;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 冷热词库
+    /// </summary>
+    [Route("api/app/thesaurus")]
+    [ApiController]
+    [Authorize]
+    public class ThesaurusController : ControllerBase
+    {
+        private readonly IThesaurusRepository _thesaurusRepository;
+
+        public ThesaurusController( IThesaurusRepository thesaurusRepository)
+        {
+          
+            _thesaurusRepository = thesaurusRepository;
+        }
+
+        /// <summary>
+        /// app获取热词冷词
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("get-thesaurus")]
+        public async Task<IEnumerable<Thesaurus>> GetAppVersion(ThesaurusSearchRequest request)
+        {
+            return await _thesaurusRepository.GetTopListAsync(request);
+        }
+
+    }
+}

+ 60 - 0
GxPress/Api/GxPress.Api/AppControllers/TopicCommentController.cs

@@ -0,0 +1,60 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.TopicAnalyze;
+using GxPress.Request.App.TopicComment;
+using GxPress.Result.App.TopicComment;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    [Route("api/app/topic-comment")]
+    [ApiController]
+    [Authorize]
+    public class TopicCommentController : ControllerBase
+    {
+        private readonly ITopicCommentRepository _topicCommentRepository;
+        private readonly ITopicAnalyzeRepository _topicAnalyzeRepository;
+        private readonly ILoginContext _loginContext;
+        public TopicCommentController(ITopicCommentRepository topicCommentRepository, ITopicAnalyzeRepository topicAnalyzeRepository, ILoginContext loginContext)
+        {
+            _topicCommentRepository = topicCommentRepository;
+            _topicAnalyzeRepository = topicAnalyzeRepository;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 添加评论
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Add([FromBody] TopicCommentInRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _topicCommentRepository.TopicCommentInAsync(request) > 0;
+        }
+        /// <summary>
+        /// 分页显示数据 已废弃
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<PagedList<TopicCommentPageResult>> GetPagedList([FromBody] TopicCommentSearchPageRequest request)
+        {
+            return await _topicCommentRepository.GetPagedList(request);
+        }
+        /// <summary>
+        /// 评论点赞 已废弃
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("laud")]
+        public async Task<bool> AddArticleAnalyze([FromBody] TopicAnalyzeRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _topicAnalyzeRepository.SetTopicAnalyzeAsync(request);
+        }
+    }
+}

+ 249 - 0
GxPress/Api/GxPress.Api/AppControllers/TopicController.cs

@@ -0,0 +1,249 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Common.Tools;
+using GxPress.Entity.Topic;
+using GxPress.Repository.Interface;
+using GxPress.Repository.Interface.Topic;
+using GxPress.Request.App.Topic;
+using GxPress.Request.App.TopicAnalyze;
+using GxPress.Request.App.TopicComment;
+using GxPress.Result.App.Topic;
+using GxPress.Result.App.TopicComment;
+using GxPress.Service.Interface.Middle;
+using GxPress.Service.Interface.Topic;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// APP话题
+    /// </summary>
+    [Route("api/app/topic")]
+    [ApiController]
+    [Authorize]
+    public class TopicController : ControllerBase
+    {
+        private readonly ILogger<TopicController> _logger;
+        private readonly ITopicRepository _topicRepository;
+        private readonly ILoginContext _loginContext;
+        private readonly ITopicService _topicService;
+        private readonly ITopicGroupRepository _topicGroupRepository;
+        private readonly ITopicGroupUserRepository _topicGroupUserRepository;
+        private readonly ITopicAnalyzeRepository _topicAnalyzeRepository;
+        private readonly ITopicCommentRepository _topicCommentRepository;
+        private readonly IMiddleService _middleService;
+
+        public TopicController(ILogger<TopicController> logger, ITopicRepository repository, ILoginContext loginContext,
+            ITopicService topicService, ITopicGroupRepository topicGroupRepository,
+            ITopicGroupUserRepository topicGroupUserRepository, ITopicAnalyzeRepository topicAnalyzeRepository,
+            ITopicCommentRepository topicCommentRepository, IMiddleService middleService)
+        {
+            _logger = logger;
+            _topicRepository = repository;
+            _loginContext = loginContext;
+            _topicService = topicService;
+            _topicGroupRepository = topicGroupRepository;
+            _topicGroupUserRepository = topicGroupUserRepository;
+            _topicAnalyzeRepository = topicAnalyzeRepository;
+            _topicCommentRepository = topicCommentRepository;
+            _middleService = middleService;
+        }
+
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add")]
+        public async Task<bool> Insert(TopicInRequest request)
+        {
+            // request.HtmlContent = StringUtils.RemoveEmoji(request.HtmlContent);
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            // request.Title = StringUtils.RemoveEmoji(request.Title);
+            request.UserId = _loginContext.AccountId;
+            return await _topicService.InsertTopicAsync(request);
+        }
+        
+        /// <summary>
+        /// 获取话题详情
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("app-detail")]
+        public async Task<TopicDetailResult> GetTopicDetailResult(TopicDetailRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var topicDetail = await _topicService.GetTopicDetailResultAsync(request);
+            return topicDetail;
+        }
+        /// <summary>
+        /// 获取话题详情 web专属
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("web-app-detail")]
+        [AllowAnonymous]
+        public async Task<TopicDetailResult> GetWebTopicDetailResult(TopicDetailRequest request)
+        {
+            var topicDetail = await _topicService.GetTopicDetailResultAsync(request);
+            return topicDetail;
+        }
+
+
+        /// <summary>
+        /// app话题分页列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list-page")]
+        public async Task<PagedList<TopicListPageResult>> GetTopicListPage(TopicPageSearchRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _topicService.GetTopicPageAsync(request);
+        }
+
+        /// <summary>
+        /// 获取用户话题分组
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("group")]
+        public async Task<IEnumerable<TopicGroup>> GetTopicGroups()
+        {
+            return await _topicGroupRepository.GetTopicGroupsAsync(_loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 添加话题分组
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add-group")]
+        public async Task<bool> InsertTopicGroup(TopicGroupInRequest request)
+        {
+            var topicGroup = new TopicGroup { Name = request.Name, UserId = _loginContext.AccountId };
+            return await _topicGroupRepository.InsertAsync(topicGroup);
+        }
+
+        /// <summary>
+        /// 修改分组名称
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("update-group")]
+        public async Task<bool> UpdateGroup(TopicGroupInRequest request)
+        {
+            return await _topicGroupRepository.UpdateAsync(request);
+        }
+
+        /// <summary>
+        /// 根据话题分组Id删除数据
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpDelete("delete_group")]
+        public async Task<bool> DeleteTopicGroup([FromBody] TopicGroupDeRequest request)
+        {
+            return await _topicService.DeleteTopicGroupAsync(request.Ids);
+        }
+
+        /// <summary>
+        /// 根据分组ID查询用户
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpGet("{id}")]
+        public async Task<PagedList<TopicGroupUserResult>> GetTopicGroupUserById(int id)
+        {
+            return await _topicGroupUserRepository.GetTopicGroupUserById(id);
+        }
+
+        /// <summary>
+        /// 添加话题小组成员
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("add-group-user")]
+        public async Task<bool> InsertAsync([FromBody]TopicGroupUserInRequest request)
+        {
+            return await _topicService.InsertTopicGroupUserAsync(request.UserIds.Distinct().ToList(), request.TopicGroupId);
+        }
+
+        /// <summary>
+        /// 根据ID删除话题分组成员
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpDelete("group-user")]
+        public async Task<bool> DeleteUser(TopicGroupDeRequest request)
+        {
+            return await _topicService.DeleteTopicGroupUserAsync(request.Ids);
+        }
+
+        /// <summary>
+        /// 排序
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("sort")]
+        public async Task<bool> MoveSort(TopicMoveSortRequest request)
+        {
+
+            return await _topicGroupRepository.MoveSortAsync(request.FirstId, request.SecondId, _loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 移动到
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("move")]
+        public async Task<bool> MoveToGroup(MoveToGroupRequest request)
+        {
+            return await _topicService.MoveToGroupAsync(request);
+        }
+
+        /// <summary>
+        /// 根据分组ID和姓名查询用户
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<PagedList<TopicGroupUserResult>> SearchTopicGroupUsers(SearchTopicGroupUsersRequest request)
+        {
+            return await _topicGroupUserRepository.SearchTopicGroupUsersAsync(request);
+        }
+
+
+
+        /// <summary>
+        /// 删除话题
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpDelete("{id}")]
+        public async Task<bool> Delete(int id)
+        {
+            return await _topicService.DeleteAsync(id);
+        }
+
+        /// <summary>
+        /// 修改话题
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("update")]
+        public async Task<bool> Update(TopicUpdateRequest request)
+        {
+            // request.HtmlContent = StringUtils.RemoveEmoji(request.HtmlContent);
+            // request.Content = StringUtils.RemoveEmoji(request.Content);
+            // request.Title = StringUtils.RemoveEmoji(request.Title);
+            request.UserId = _loginContext.AccountId;
+            return await _topicService.UpdateAsync(request);
+        }
+    }
+}

+ 456 - 0
GxPress/Api/GxPress.Api/AppControllers/UserController.cs

@@ -0,0 +1,456 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Security.Claims;
+using System.Text;
+using System.Threading.Tasks;
+using Datory.Utils;
+using GxPress.Api.Tools;
+using GxPress.Auth;
+using GxPress.Common.Exceptions;
+using GxPress.Common.Validation;
+using GxPress.Entity;
+using GxPress.EnumConst;
+using GxPress.Repository.Interface;
+using GxPress.Request.App.User;
+using GxPress.Request.User;
+using GxPress.Result.App.FileLibrary;
+using GxPress.Result.App.User;
+using GxPress.Result.User;
+using GxPress.Service.Interface;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Distributed;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 用户
+    /// </summary>
+    [Route("/api/app/user")]
+    [ApiController]
+    [Authorize]
+    public class UserController : ControllerBase
+    {
+        private readonly JwtOptions _jwtOptions;
+        private readonly ILogger<UserController> _logger;
+        private readonly IUserRepository _userRepository;
+        private readonly IDepartmentRepository _departmentRepository;
+        private readonly ILoginContext _loginContext;
+        private readonly IUserService _userService;
+        private readonly IFileLibraryRepository fileLibraryRepository;
+        private readonly IDistributedCache _cache;
+        public UserController(IUserRepository userRepository, IOptions<JwtOptions> jwtOptions,
+            ILogger<UserController> logger, IDepartmentRepository departmentRepository, ILoginContext loginContext,
+            IUserService userService, IFileLibraryRepository fileLibraryRepository, IDistributedCache cache)
+        {
+            _userRepository = userRepository;
+            _departmentRepository = departmentRepository;
+            _userService = userService;
+            _jwtOptions = jwtOptions.Value;
+            _logger = logger;
+            _loginContext = loginContext;
+            this.fileLibraryRepository = fileLibraryRepository;
+            _cache = cache;
+        }
+
+        ///// <summary>
+        ///// 添加
+        ///// </summary>
+        ///// <param name="request"></param>
+        ///// <returns></returns>
+        //[HttpPost]
+        //public async Task<User> Add([FromBody] User request)
+        //{
+        //    request.Id = await _userRepository.InsertAsync(request);
+        //    return request;
+        //}
+
+        /// <summary>
+        /// 登录
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("signin")]
+        [AllowAnonymous]
+        public async Task<UserSignInResult> SignIn(UserSignInRequest request)
+        {
+            var result = await _userRepository.SignInAsync(request);
+            var claims = new[]
+            {
+                new Claim(ClaimTypes.NameIdentifier, result.UserId.ToString()),
+                new Claim(ClaimTypes.Role, AccountTypeConst.User.ToString())
+            };
+            result.Token = TokenHelper.BuildToken(_jwtOptions, claims);
+            return result;
+        }
+        /// <summary>
+        /// 绑定opendId
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("set-opend-Id")]
+        [AllowAnonymous]
+        public async Task<UserSignInResult> SetOpenId(UserSignInRequest request)
+        {
+            var success = await _userRepository.UpdateByOpendIdAsync(request);
+            if (success)
+            {
+                var result = await _userRepository.SignInAsync(request);
+                var claims = new[]
+                {
+                new Claim(ClaimTypes.NameIdentifier, result.UserId.ToString()),
+                new Claim(ClaimTypes.Role, AccountTypeConst.User.ToString())
+            };
+                result.Token = TokenHelper.BuildToken(_jwtOptions, claims);
+                return result;
+            }
+            return new UserSignInResult();
+        }
+        /// <summary>
+        /// 查询opendId是否存在
+        /// </summary>
+        /// <param name="opendId"></param>
+        /// <returns></returns>
+        [HttpGet("find-opend-Id/{opendId}")]
+        [AllowAnonymous]
+        public async Task<bool> FindOpenId(string opendId)
+        {
+            var user = await _userRepository.GetByOpenIdAsync(opendId);
+            if (user == null)
+                return false;
+            return true;
+        }
+
+        /////// <summary>
+        /////// 登录验证码发送
+        /////// </summary>
+        /////// <param name="phone"></param>
+        /////// <returns></returns>
+        ////[HttpGet("sendSmsCode")]
+        ////[AllowAnonymous]
+        ////public async Task<bool> SendSmsCode([FromQuery] [Required] [Mobile] string phone)
+        ////{
+        ////    var user = await _userRepository.GetByPhoneAsync(phone);
+
+        ////    //用户不存在
+        ////    if (user == null)
+        ////    {
+        ////        throw new BusinessException("该用户不存在");
+        ////    }
+
+        ////    //TODO 短信验证码发送
+        ////    //return await _smsService.
+        ////    //SendValidationCodeAsync(phone);
+        ////    var key = $"login:{phone}";
+        ////    if (await RedisHelper.ExistsAsync(key)) throw new BusinessException("发送太频繁");
+        ////    var code = RandomGenerator.GetNumberString(6);
+        ////    _logger.LogInformation("{phone}验证码:{code}", phone, code);
+        ////    //发送验证码阿里云
+        ////    IClientProfile profile =
+        ////        DefaultProfile.GetProfile("cn-hangzhou", "LTAI2E47R4DlcYfo", "5epQRUGRrDSoF7yukyYf4HX6dUlvF3");
+        ////    DefaultAcsClient client = new DefaultAcsClient(profile);
+        ////    CommonRequest request = new CommonRequest
+        ////    {
+        ////        Method = MethodType.POST,
+        ////        Domain = "dysmsapi.aliyuncs.com",
+        ////        Version = "2017-05-25",
+        ////        Action = "SendSms"
+        ////    };
+        ////    request.AddQueryParameters("PhoneNumbers", $"{phone}");
+        ////    request.AddQueryParameters("SignName", "泰德合众");
+        ////    request.AddQueryParameters("TemplateCode", "SMS_168126117");
+        ////    request.AddQueryParameters("TemplateParam", "{\"code\":\"" + code + "\"}");
+        ////    try
+        ////    {
+        ////        CommonResponse response = client.GetCommonResponse(request);
+        ////        _logger.LogInformation(Encoding.Default.GetString(response.HttpResponse.Content));
+        ////    }
+        ////    catch (ServerException e)
+        ////    {
+        ////        throw new BusinessException(e.Message);
+        ////    }
+
+        //return await RedisHelper.SetAsync(key, code, 300);
+
+        ////}
+        /// <summary>
+        /// 登录验证码发送
+        /// </summary>
+        /// <param name="phone"></param>
+        /// <returns></returns>
+        [HttpGet("sendSmsCode")]
+        [AllowAnonymous]
+        public async Task<bool> SendSmsCode([FromQuery] [Required] [Mobile] string phone)
+        {
+            var user = await _userRepository.GetByPhoneAsync(phone);
+
+            //用户不存在
+            if (user == null)
+            {
+                throw new BusinessException("该用户不存在");
+            }
+
+            //TODO 短信验证码发送
+            //return await _smsService.
+            //SendValidationCodeAsync(phone);
+            var key = $"login:{phone}";
+            //if (await RedisHelper.ExistsAsync(key)) throw new BusinessException("发送太频繁");
+            var code = "180606";
+            _logger.LogInformation($"{key}", phone, code);
+            var codeByte = Encoding.UTF8.GetBytes(Utilities.JsonSerialize(code));
+            await _cache.SetAsync($"{key}", codeByte, new DistributedCacheEntryOptions
+            {
+                AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300)
+            });
+            // var result = await RedisHelper.SetAsync(key, code, 300);
+            // if (result == false)
+            //     throw new BusinessException("发送失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 更换手机号码验证码发送
+        /// </summary>
+        /// <param name="phone"></param>
+        /// <returns></returns>
+        [HttpGet("send-sms-code")]
+        public async Task<bool> SendSmsCodeReplace([FromQuery] [Required] [Mobile] string phone)
+        {
+            var user = await _userRepository.GetByPhoneAsync(phone);
+            if (user != null)
+                throw new BusinessException("号码以被使用");
+            //TODO 短信验证码发送
+            //return await _smsService.
+            //SendValidationCodeAsync(phone);
+            var key = $"login:{phone}";
+            // if (await RedisHelper.ExistsAsync(key)) throw new BusinessException("发送太频繁");
+            var code = "180606";
+            _logger.LogInformation("{phone}验证码:{code}", phone, code);
+            //var result = await RedisHelper.SetAsync(key, code, 300);
+            //if (result == false)
+            //    throw new BusinessException("发送失败");
+            return true;
+        }
+
+        /// <summary>
+        /// app查询用户详情
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("detail")]
+        public async Task<UserDetail> GetDetail()
+        {
+            var id = _loginContext.AccountId;
+            var user = await _userRepository.GetAsync(id);
+            if (user == null)
+                throw new BusinessException("用户id有误");
+            return await _userRepository.GetDetailAsync(id);
+        }
+
+        /// <summary>
+        /// app查询他人用户详情
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("detail/{id}")]
+        public async Task<UserDetail> GetDetail(int id)
+        {
+            if (id <= 0)
+                throw new BusinessException("用户id有误");
+            return await _userService.GetUserByIdAsync(_loginContext.AccountId, id);
+        }
+        /// <summary>
+        /// app更新用户信息
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("update")]
+        public async Task<bool> Update([FromBody] User request)
+        {
+            var id = _loginContext.AccountId;
+            var result = await _userRepository.UpdateAsync(id, request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 私信
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("update-user-private-letter")]
+        public async Task<bool> UpdateUserPrivateLetter()
+        {
+            UserPrivateLetterRequest request = new UserPrivateLetterRequest { Id = _loginContext.AccountId };
+            var result = await _userRepository.UpdateUserPrivateLetterAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 通知
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("update-user-notice")]
+        public async Task<bool> UpdateUserNotice()
+        {
+            var request = new UserNoticeRequest { Id = _loginContext.AccountId };
+            var result = await _userRepository.UpdateUserNoticeAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 回复
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("update-user-reply")]
+        public async Task<bool> UpdateUserReply()
+        {
+            var request = new UserReplyRequest { Id = _loginContext.AccountId };
+            var result = await _userRepository.UpdateUserReplyAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 静音
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("update-user-mute")]
+        public async Task<bool> UpdateUserMute()
+        {
+            var request = new UserMuteRequest { Id = _loginContext.AccountId };
+            var result = await _userRepository.UpdateUserMuteAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 震动
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("update-user-shake")]
+        public async Task<bool> UpdateUserShake()
+        {
+            var request = new UserShakeRequest { Id = _loginContext.AccountId };
+            var result = await _userRepository.UpdateUserShakeAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 用户修改手机号码
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update-user-phone")]
+        public async Task<bool> UpdateUserPhone(UserUpdatePhoneRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var result = await _userRepository.UpdateUserPhoneAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 邮箱验证码
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("send-email-verify-code")]
+        public async Task<bool> SendEmailVerifyCode(UserEmailVerifyCodeRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var result = await _userRepository.SendEmailVerifyCodeAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 修改邮箱
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("update-user-email")]
+        public async Task<bool> UpdateUserEmail(UserUpdateEmailRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            var result = await _userRepository.UpdateUserEmailAsync(request);
+            if (result == false)
+                throw new BusinessException("更新失败");
+            return true;
+        }
+
+        /// <summary>
+        /// 查询联系人
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("search")]
+        public async Task<IEnumerable<UserInfoResult>> SearchUserName(SearchUserNameRequest request)
+        {
+            return await _userRepository.SearchUserNameAsync(request);
+        }
+
+        /// <summary>
+        /// 根据部门ID获取自建ID获取用户列表
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("find")]
+        public async Task<IEnumerable<UserInfoResult>> FindUser(FindUserRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _userService.FindUser(request);
+        }
+
+        /// <summary>
+        /// 根据部门ID获取自建ID获取用户列表
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        [HttpGet("find-name")]
+        public async Task<IEnumerable<UserInfoResult>> FindUserByName([FromQuery] string name)
+        {
+            return await _userRepository.UserByNameAsync(name);
+        }
+        /// <summary>
+        /// 根据GUID查询用户
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("guid")]
+        public async Task<UserDetail> FindUserByGuid(FindUserByGuidRequest request)
+        {
+            var user = await _userRepository.GetGuidAsync(request.Guid);
+            return user;
+        }
+        /// <summary>
+        /// 获取用户工作模块未读数据
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("user-uread-count")]
+        public async Task<UserCountResult> GetUserCountAsync()
+        {
+            return await _userService.GetUserCountAsync(_loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 根据用户名获取电脑上传的数据
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("user-file-library")]
+        public async Task<IEnumerable<FileLibraryResult>> GetFileLibraryByUserIdAsync()
+        {
+            return await fileLibraryRepository.GetFileLibraryByUserIdAsync(_loginContext.AccountId);
+        }
+    }
+}

+ 11 - 0
GxPress/Api/GxPress.Api/AppControllers/VerificationCodeController.Dto.cs

@@ -0,0 +1,11 @@
+namespace GxPress.Api.AppControllers
+{
+    public partial class VerificationCodeController
+    {
+        public class VerificationDto
+        {
+            public string ServiceUrl{get;set;}
+            public string Code { get; set; }
+        }
+    }
+}

+ 73 - 0
GxPress/Api/GxPress.Api/AppControllers/VerificationCodeController.cs

@@ -0,0 +1,73 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using GxPress.Service.Interface.VerificationCode;
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Request.App.VerificationCode;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 收藏上传验证码
+    /// </summary>
+    [Route("api/app/verification-code")]
+    [ApiController]
+    [Authorize]
+    public partial class VerificationCodeController : ControllerBase
+    {
+        private readonly IVerificationCodeService verificationCodeService;
+
+        private readonly ILoginContext _loginContext;
+        public VerificationCodeController(IVerificationCodeService verificationCodeService, ILoginContext loginContext)
+        {
+            this.verificationCodeService = verificationCodeService;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 生成验证码
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("send-code")]
+        public async Task<string> GetCodeAsync()
+        {
+            return await verificationCodeService.GetCodeAsync(_loginContext.AccountId);
+        }
+
+        /// <summary>
+        /// 生成验证码
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("app-send-code")]
+        public async Task<VerificationDto> GetAppCodeAsync()
+        {
+            var code = await verificationCodeService.GetCodeAsync(_loginContext.AccountId);
+            var result = new VerificationDto();
+            result.Code = code;
+            var serviceUrl = GxPress.Common.Tools.ConfigHelper.GetValue("ServiceAddress:AddressUrlDownload");
+            result.ServiceUrl = $"{serviceUrl}/mobile/pcupload";
+            return result;
+        }
+        /// <summary>
+        ///验证验证码码
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("confirmation-code")]
+        [AllowAnonymous]
+        public async Task<bool> ConfirmationCodeAsync(VerificationCodeRequest request)
+        {
+            //request.UserId=_loginContext.AccountId;
+            return await verificationCodeService.ConfirmationCodeAsync(request);
+        }
+        /// <summary>
+        /// 持久连接验证码
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost("Lasting-confirmation-code")]
+        [AllowAnonymous]
+        public async Task<bool> LastingConfirmationCode(VerificationCodeRequest request)
+        {
+            return await verificationCodeService.LastingConfirmationCodeAsync(request);
+        }
+    }
+}

+ 38 - 0
GxPress/Api/GxPress.Api/AppControllers/VisitController.cs

@@ -0,0 +1,38 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Repository.Interface.Visit;
+using GxPress.Request.App.Visit;
+using GxPress.Result.App.Visit;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 访问
+    /// </summary>
+    [Route("/api/app/visit")]
+    [ApiController]
+    [Authorize]
+    public class VisitController : ControllerBase
+    {
+        private readonly IVisitRepository _visitRepository;
+        private readonly ILoginContext _loginContext;
+        public VisitController(IVisitRepository visitRepository, ILoginContext loginContext)
+        {
+            _visitRepository = visitRepository;
+            _loginContext = loginContext;
+        }
+        /// <summary>
+        /// 通知查询
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        public async Task<PagedList<VisitResult>> GetVisitResultAsync(VisitPageSearchRequest request)
+        {
+            return await _visitRepository.GetVisitResultAsync(request);
+        }
+    }
+}

+ 121 - 0
GxPress/Api/GxPress.Api/AppControllers/WaitHandleController.cs

@@ -0,0 +1,121 @@
+using System.Threading.Tasks;
+using GxPress.Auth;
+using GxPress.Common.Page;
+using GxPress.Entity.WaitHandle;
+using GxPress.Request.App.WaitHandle;
+using GxPress.Result.App.WaitHandle;
+using GxPress.Service.Interface.WaitHandle;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace GxPress.Api.AppControllers
+{
+    /// <summary>
+    /// 待办事项
+    /// </summary>
+    [Route("api/app/wait-handle")]
+    [ApiController]
+    [Authorize]
+    public class WaitHandleController : ControllerBase
+    {
+        private readonly IWaitHandleService _waitHandleService;
+        private readonly ILoginContext _loginContext;
+
+        public WaitHandleController(IWaitHandleService waitHandleService, ILoginContext loginContext)
+        {
+            _waitHandleService = waitHandleService;
+            _loginContext = loginContext;
+        }
+
+        /// <summary>
+        /// 添加修改待办事项
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add-update")]
+        public async Task<WaitHandle> AddOrUpdateWaitHandleAsync(WaitHandleAddOrUpdateRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _waitHandleService.AddOrUpdateWaitHandleAsync(request);
+        }
+        /// <summary>
+        /// 删除待办事项
+        /// </summary>
+        /// <returns></returns>
+        [HttpDelete("delete")]
+        public async Task<bool> DeleteWaitHandleAsync(DeleteWaitHandleRequest request)
+        {
+            return await _waitHandleService.DeleteWaitHandleAsync(request);
+        }
+
+        /// <summary>
+        ///  待办搜索  Sort :hand  手动 time按时间 label 标签 level 优先级
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page")]
+        public async Task<PagedList<WaitHandle>> PageWaitHandleAsync(PageWaitHandleRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _waitHandleService.PageWaitHandleAsync(request);
+        }
+        /// <summary>
+        /// 添加修改标签
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPut("add-update-label")]
+        public async Task<bool> AddOrUpdateWaitHandleLabelAsync(WaitHandleLabelAddOrUpdateRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _waitHandleService.AddOrUpdateWaitHandleLabelAsync(request);
+        }
+        /// <summary>
+        /// 删除标签
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpDelete("delete-label")]
+        public async Task<bool> DeleteWaitHandleLabelAsync(DeleteWaitHandleRequest request)
+        {
+            return await _waitHandleService.DeleteWaitHandleLabelAsync(request);
+        }
+
+
+        /// <summary>
+        /// 标签
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("page-label")]
+        public async Task<PagedList<WaitHandleLabel>> PageWaitHandleLabelAsync(
+            PageWaitHandleRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _waitHandleService.PageWaitHandleLabelAsync(request);
+        }
+
+        /// <summary>
+        /// 待办搜索  1  手动 2 按时间 3 标签 4 优先级
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("list")]
+        public async Task<WaitHandleListResult> WaitHandleListAsync(ListWaitHandleRequest request)
+        {
+            request.UserId = _loginContext.AccountId;
+            return await _waitHandleService.WaitHandleListAsync(request);
+        }
+
+        /// <summary>
+        /// 设置待办事项
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        [HttpPut("set/{id}")]
+        public async Task<bool> IsFinishAsync(int id)
+        {
+            return await _waitHandleService.IsFinishAsync(id);
+        }
+    }
+}

+ 50 - 0
GxPress/Api/GxPress.Api/GxPress.Api.csproj

@@ -0,0 +1,50 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp3.0</TargetFramework>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DocumentationFile>bin\Debug\netcoreapp3.0\GxPress.Api.xml</DocumentationFile>
+    <NoWarn>1701;1702;1591</NoWarn>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="aliyun-net-sdk-core" Version="1.5.3" />
+    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
+    <PackageReference Include="ExcelDataReader" Version="3.6.0" />
+    <PackageReference Include="ExcelDataReader.DataSet" Version="3.6.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="3.1.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
+    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" />
+    <PackageReference Include="Minio" Version="3.1.7" />
+    <PackageReference Include="Quartz" Version="3.0.7" />
+    <PackageReference Include="Quartz.Plugins" Version="3.0.7" />
+    <PackageReference Include="Serilog" Version="2.8.0" />
+    <PackageReference Include="Serilog.AspNetCore" Version="3.0.0" />
+    <PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
+    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
+    <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
+    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
+    <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.0.0-rc4" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Infrastructure\GxPress.Auth\GxPress.Auth.csproj" />
+    <ProjectReference Include="..\..\Infrastructure\GxPress.Common\GxPress.Common.csproj" />
+    <ProjectReference Include="..\..\Model\GxPress.Mappings\GxPress.Mappings.csproj" />
+    <ProjectReference Include="..\..\Model\GxPress.Request\GxPress.Request.csproj" />
+    <ProjectReference Include="..\..\Repository\GxPress.Repository.Implement\GxPress.Repository.Implement.csproj" />
+    <ProjectReference Include="..\..\Repository\GxPress.Repository.Interface\GxPress.Repository.Interface.csproj" />
+    <ProjectReference Include="..\..\Service\GxPress.Service.Implement\GxPress.Service.Implement.csproj" />
+    <ProjectReference Include="..\..\Service\GxPress.Service.Interface\GxPress.Service.Interface.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="wwwroot\" />
+  </ItemGroup>
+</Project>

+ 30 - 0
GxPress/Api/GxPress.Api/Program.cs

@@ -0,0 +1,30 @@
+using GxPress.Common.Tools;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+
+namespace GxPress.Api
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        public static IHostBuilder CreateHostBuilder(string[] args)
+        {
+            return Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseUrls("http://0.0.0.0:83/");
+                    webBuilder.UseSerilog((hostingContext, loggerConfiguration) =>
+                    {
+                        loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration);
+                        loggerConfiguration.Enrich.FromLogContext();
+                    });
+                    webBuilder.UseStartup<Startup>();
+                });
+        }
+    }
+}

+ 83 - 0
GxPress/Api/GxPress.Api/ServiceExtensions/AuthenticationExtension.cs

@@ -0,0 +1,83 @@
+using System;
+using System.Text;
+using GxPress.Auth;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.IdentityModel.Tokens;
+
+namespace GxPress.Api.ServiceExtensions
+{
+    public static class AuthenticationExtension
+    {
+        /// <summary>
+        ///     添加Jwt认证授权
+        /// </summary>
+        /// <param name="services"></param>
+        /// <param name="configuration"></param>
+        /// <returns></returns>
+        public static IServiceCollection AddJwtAuthentication(this IServiceCollection services,
+            IConfiguration configuration)
+        {
+            var jwtSection = configuration.GetSection("JwtOptions");
+            var jwtOptions = new JwtOptions
+            {
+                Key = jwtSection["Key"],
+                Issuer = jwtSection["Issuer"],
+                Audience = jwtSection["Audience"],
+                Expires = TimeSpan.FromDays(int.Parse(jwtSection["Expires"]))
+            };
+
+            services.AddHttpContextAccessor();
+            services.Configure<JwtOptions>(jwtSection);
+            services.TryAddSingleton<ILoginContext, LoginContext>();
+
+            ////添加授权
+            //services.AddAuthorization(options =>
+            //{
+            //    options.AddPolicy("Permission", policy =>
+            //    {
+            //        policy.Requirements.Add(new PermissionRequirement());
+            //    });
+            //});
+            //services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
+
+            //添加认证
+            services.AddAuthentication(options =>
+            {
+                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+            })
+                .AddJwtBearer(options =>
+                {
+                    options.TokenValidationParameters = new TokenValidationParameters
+                    {
+                        ValidateIssuer = true,
+                        ValidateAudience = true,
+                        ValidateLifetime = true,
+                        ValidateIssuerSigningKey = true,
+                        ClockSkew = TimeSpan.FromMinutes(5),
+                        ValidIssuer = jwtOptions.Issuer,
+                        ValidAudience = jwtOptions.Audience,
+                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Key))
+                    };
+                });
+
+            return services;
+        }
+
+        /// <summary>
+        ///     使用jwt认证
+        /// </summary>
+        /// <param name="app"></param>
+        /// <returns></returns>
+        public static IApplicationBuilder UseJwtAuthorization(this IApplicationBuilder app)
+        {
+            app.UseAuthentication();
+            app.UseAuthorization();
+            return app;
+        }
+    }
+}

+ 22 - 0
GxPress/Api/GxPress.Api/ServiceExtensions/AutoMapperExtension.cs

@@ -0,0 +1,22 @@
+using AutoMapper;
+using GxPress.Mappings;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace GxPress.Api.ServiceExtensions
+{
+    public static class AutoMapperExtension
+    {
+        /// <summary>
+        /// 添加映射框架
+        /// </summary>
+        /// <param name="services"></param>
+        /// <returns></returns>
+        public static IServiceCollection AddMappers(this IServiceCollection services)
+        {
+            //ProcessMapping所在程序集的所有Profile都会被注册
+            services.AddAutoMapper(typeof(ProcessMapping));
+
+            return services;
+        }
+    }
+}

+ 27 - 0
GxPress/Api/GxPress.Api/ServiceExtensions/CachingExtension.cs

@@ -0,0 +1,27 @@
+using Microsoft.Extensions.DependencyInjection;
+
+namespace GxPress.Api.ServiceExtensions
+{
+    public static class CachingExtension
+    {
+        public static IServiceCollection AddDistributedCache(this IServiceCollection services, string cacheConnectionString)
+        {
+            var isSettings = false;
+            if (!string.IsNullOrEmpty(cacheConnectionString))
+            {
+                isSettings = true;
+                services.AddStackExchangeRedisCache(options =>
+                {
+                    options.Configuration = cacheConnectionString;
+                    options.InstanceName = "";
+                });
+            }
+
+            if (!isSettings)
+            {
+                services.AddDistributedMemoryCache();
+            }
+            return services;
+        }
+    }
+}

+ 39 - 0
GxPress/Api/GxPress.Api/ServiceExtensions/RepositoryExtension.cs

@@ -0,0 +1,39 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Microsoft.Extensions.DependencyInjection;
+using Datory;
+
+namespace GxPress.Api.ServiceExtensions
+{
+    public static class RepositoryExtension
+    {
+        /// <summary>
+        /// 注入仓储
+        /// </summary>
+        /// <param name="services"></param>
+        /// <returns></returns>
+        public static IServiceCollection AddRepositories(this IServiceCollection services)
+        {
+            var baseType = typeof(IRepository);
+
+            var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
+            var referencedAssemblies = Directory.GetFiles(path, "GxPress.Repository.*.dll").Select(Assembly.LoadFrom).ToArray();
+            var types = referencedAssemblies
+                .SelectMany(a => a.DefinedTypes)
+                .Select(type => type.AsType())
+                .Where(x => x != baseType && baseType.IsAssignableFrom(x)).ToArray();
+            var implementTypes = types.Where(x => x.IsClass).ToArray();
+            var interfaceTypes = types.Where(x => x.IsInterface).ToArray();
+            foreach (var implementType in implementTypes)
+            {
+                var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType));
+                if (interfaceType != null)
+                    services.AddScoped(interfaceType, implementType);
+            }
+
+            return services;
+        }
+    }
+}

+ 0 - 0
GxPress/Api/GxPress.Api/ServiceExtensions/RuntimeHelper.cs


Some files were not shown because too many files changed in this diff