├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── docfx.yml
│ └── gitee-mirror.yml
├── .gitignore
├── Delete BIN OBJ Folders.bat
├── Directory.Build.props
├── LICENSE
├── LinCms.Scaffolding.sln
├── LinCms.sln
├── README.md
├── azure-pipelines.yml
├── build-all.ps1
├── build_push.sh
├── docs
├── README.md
├── api
│ └── index.md
├── articles
│ ├── intro.md
│ └── toc.yml
├── docfx.json
├── images
│ ├── qq.png
│ ├── wechat.png
│ ├── 使用Bearer.PNG
│ ├── 登录接口.PNG
│ └── 返回access_token.PNG
├── index.md
├── sql
│ └── README.md
└── toc.yml
├── publish.bat
├── run.sh
├── src
├── LinCms.Application.Contracts
│ ├── Base
│ │ ├── BaseItems
│ │ │ ├── BaseItemDto.cs
│ │ │ ├── CreateUpdateBaseItemDto.cs
│ │ │ └── IBaseItemService.cs
│ │ └── BaseTypes
│ │ │ ├── BaseTypeDto.cs
│ │ │ ├── CreateUpdateBaseTypeDto.cs
│ │ │ └── IBaseTypeService.cs
│ ├── Blog
│ │ ├── ArticleDrafts
│ │ │ ├── ArticleDraftDto.cs
│ │ │ ├── IArticleDraftService.cs
│ │ │ └── UpdateArticleDraftDto.cs
│ │ ├── Articles
│ │ │ ├── ArticleDto.cs
│ │ │ ├── ArticleListDto.cs
│ │ │ ├── ArticleSearchDto.cs
│ │ │ ├── CreateUpdateArticleDto.cs
│ │ │ └── IArticleService.cs
│ │ ├── AuthorCenter
│ │ │ ├── ArticleCardDto.cs
│ │ │ └── IAuthorCenterService.cs
│ │ ├── Channels
│ │ │ ├── ChannelDto.cs
│ │ │ ├── ChannelSearchDto.cs
│ │ │ ├── CreateUpdateChannelDto.cs
│ │ │ ├── IChannelService.cs
│ │ │ └── NavChannelListDto.cs
│ │ ├── Classifys
│ │ │ ├── ClassifyDto.cs
│ │ │ ├── ClassifySearchDto.cs
│ │ │ ├── CreateUpdateClassifyDto.cs
│ │ │ └── IClassifyService.cs
│ │ ├── Collections
│ │ │ ├── CollectionDto.cs
│ │ │ ├── CollectionSearchDto.cs
│ │ │ ├── CreateCancelArticleCollectionDto.cs
│ │ │ ├── CreateUpdateCollectionDto.cs
│ │ │ ├── IArticleCollectionService.cs
│ │ │ └── ICollectionService.cs
│ │ ├── Comments
│ │ │ ├── CommentDto.cs
│ │ │ ├── CommentSearchDto.cs
│ │ │ ├── CreateCommentDto.cs
│ │ │ └── ICommentService.cs
│ │ ├── Notifications
│ │ │ ├── ArticleEntry.cs
│ │ │ ├── CommentEntry.cs
│ │ │ ├── CreateNotificationDto.cs
│ │ │ ├── IEventService.cs
│ │ │ ├── INotificationService.cs
│ │ │ ├── NotificationDto.cs
│ │ │ └── NotificationSearchDto.cs
│ │ ├── Tags
│ │ │ ├── CreateUpdateTagDto.cs
│ │ │ ├── ITagService.cs
│ │ │ ├── IUserTagService.cs
│ │ │ ├── TagDto.cs
│ │ │ ├── TagListDto.cs
│ │ │ ├── TagSearchDto.cs
│ │ │ └── UserTagDto.cs
│ │ ├── UserLikes
│ │ │ ├── CreateUpdateUserLikeDto.cs
│ │ │ └── IUserLikeService.cs
│ │ └── UserSubscribes
│ │ │ ├── IUserSubscribeService.cs
│ │ │ ├── SubscribeCountDto.cs
│ │ │ ├── UserSubscribeDto.cs
│ │ │ └── UserSubscribeSearchDto.cs
│ ├── Cms
│ │ ├── Account
│ │ │ ├── IAccountService.cs
│ │ │ ├── ITokenService.cs
│ │ │ ├── LoginCaptchaDto.cs
│ │ │ ├── LoginInputDto.cs
│ │ │ ├── RegisterDto.cs
│ │ │ ├── ResetEmailPasswordDto.cs
│ │ │ └── SendEmailCodeInput.cs
│ │ ├── Admins
│ │ │ ├── ResetPasswordDto.cs
│ │ │ ├── UpdateUserDto.cs
│ │ │ └── UserSearchDto.cs
│ │ ├── Files
│ │ │ ├── FileDto.cs
│ │ │ └── IFileService.cs
│ │ ├── Groups
│ │ │ ├── CreateGroupDto.cs
│ │ │ ├── GroupDto.cs
│ │ │ ├── IGroupService.cs
│ │ │ └── UpdateGroupDto.cs
│ │ ├── Logs
│ │ │ ├── ILogService.cs
│ │ │ ├── ISerilogService.cs
│ │ │ ├── LogDashboard.cs
│ │ │ ├── LogDto.cs
│ │ │ ├── LogSearchDto.cs
│ │ │ ├── SerilogSearchDto.cs
│ │ │ └── VisitLogUserDto.cs
│ │ ├── Permissions
│ │ │ ├── DispatchPermissionsDto.cs
│ │ │ ├── IPermissionService.cs
│ │ │ ├── PermissioCreateUpdateDto.cs
│ │ │ ├── PermissionDto.cs
│ │ │ └── RemovePermissionDto.cs
│ │ ├── Settings
│ │ │ ├── CreateUpdateSettingDto.cs
│ │ │ ├── ISettingService.cs
│ │ │ └── SettingDto.cs
│ │ └── Users
│ │ │ ├── ChangePasswordDto.cs
│ │ │ ├── CreateUserDto.cs
│ │ │ ├── IOAuth2Service.cs
│ │ │ ├── IUserIdentityService.cs
│ │ │ ├── IUserService.cs
│ │ │ ├── OAuthService.cs
│ │ │ ├── OpenUserDto.cs
│ │ │ ├── UpdateAvatarDto.cs
│ │ │ ├── UpdateNickNameDto.cs
│ │ │ ├── UpdateProfileDto.cs
│ │ │ ├── UserDto.cs
│ │ │ ├── UserIdentityDto.cs
│ │ │ ├── UserInformation.cs
│ │ │ └── UserNoviceDto.cs
│ ├── IApplicationService.cs
│ ├── ICrudAppService.cs
│ ├── LinCms.Application.Contracts.csproj
│ └── LinCms.Application.Contracts.xml
├── LinCms.Application
│ ├── AppliactionService.cs
│ ├── Base
│ │ ├── BaseItems
│ │ │ ├── BaseItemProfile.cs
│ │ │ └── BaseItemService.cs
│ │ └── BaseTypes
│ │ │ ├── BaseTypeProfile.cs
│ │ │ └── BaseTypeService.cs
│ ├── Blog
│ │ ├── Articles
│ │ │ ├── ArticleDraftService.cs
│ │ │ ├── ArticleProfile.cs
│ │ │ └── ArticleService.cs
│ │ ├── AuthorCenter
│ │ │ └── AuthorCenterService.cs
│ │ ├── Channels
│ │ │ ├── ChannelProfile.cs
│ │ │ └── ChannelService.cs
│ │ ├── Classifies
│ │ │ ├── ClassifyProfile.cs
│ │ │ └── ClassifyService.cs
│ │ ├── Collections
│ │ │ ├── ArticleCollectionService.cs
│ │ │ ├── CollectionProfile.cs
│ │ │ └── CollectionService.cs
│ │ ├── Comments
│ │ │ ├── CommentProfile.cs
│ │ │ └── CommentService.cs
│ │ ├── Notifications
│ │ │ ├── EventService.cs
│ │ │ ├── NotificationProfile.cs
│ │ │ └── NotificationService.cs
│ │ ├── Tags
│ │ │ ├── TagProfile.cs
│ │ │ ├── TagService.cs
│ │ │ └── UserTagService.cs
│ │ ├── UserLikes
│ │ │ ├── UserLikeProfile.cs
│ │ │ └── UserLikeService.cs
│ │ └── UserSubscribes
│ │ │ ├── UserSubscribeProfile.cs
│ │ │ └── UserSubscribeService.cs
│ ├── CapUnitOfWorkExtensions.cs
│ ├── Cms
│ │ ├── Account
│ │ │ ├── AccountContracts.cs
│ │ │ ├── AccountService.cs
│ │ │ └── JwtTokenService.cs
│ │ ├── Files
│ │ │ ├── LocalFileService.cs
│ │ │ └── QiniuService.cs
│ │ ├── Groups
│ │ │ ├── GroupProfile.cs
│ │ │ └── GroupService.cs
│ │ ├── Logs
│ │ │ ├── LogService.cs
│ │ │ └── SerilogService.cs
│ │ ├── Permissions
│ │ │ ├── PermissionProfile.cs
│ │ │ ├── PermissionService.cs
│ │ │ └── TreeBuilder.cs
│ │ ├── Settings
│ │ │ ├── SettingProfile.cs
│ │ │ └── SettingService.cs
│ │ └── Users
│ │ │ ├── GiteeOAuth2Service.cs
│ │ │ ├── GithubOAuth2Serivice.cs
│ │ │ ├── UserIdentityProfile.cs
│ │ │ ├── UserIdentityService.cs
│ │ │ ├── UserProfile.cs
│ │ │ └── UserService.cs
│ ├── CrudAppService.cs
│ └── LinCms.Application.csproj
├── LinCms.Core
│ ├── Aop
│ │ ├── Attributes
│ │ │ ├── CacheableAttribute.cs
│ │ │ ├── DisableAuditingAttribute.cs
│ │ │ ├── IgnoreMemberAttribute.cs
│ │ │ └── LoggerAttribute.cs
│ │ └── Filter
│ │ │ ├── LinCmsAuthorizeAttribute.cs
│ │ │ ├── LinCmsExceptionFilter.cs
│ │ │ └── LogActionFilterAttribute.cs
│ ├── Common
│ │ ├── EncryptUtil.cs
│ │ ├── LinCmsUtils.cs
│ │ └── LinConsts.cs
│ ├── Data
│ │ ├── Authorization
│ │ │ ├── PermissionAuthorizationRequirement.cs
│ │ │ └── ValidJtiRequirement.cs
│ │ ├── Enums
│ │ │ ├── CapMessageQueueType.cs
│ │ │ ├── CapStorageType.cs
│ │ │ ├── ErrorCode.cs
│ │ │ ├── Status.cs
│ │ │ ├── TokenType.cs
│ │ │ └── UserStatus.cs
│ │ ├── Options
│ │ │ ├── FileStorageOption.cs
│ │ │ ├── LocalFileOption.cs
│ │ │ ├── QiniuOption.cs
│ │ │ └── SiteOption.cs
│ │ ├── PagedAndSortedRequestDto.cs
│ │ ├── PermissionDefinition.cs
│ │ └── UnifyResponseDto.cs
│ ├── Domain
│ │ ├── Captcha
│ │ │ ├── CaptchaBO.cs
│ │ │ ├── CaptchaManager.cs
│ │ │ ├── CaptchaOption.cs
│ │ │ ├── ICaptchaManager.cs
│ │ │ └── ImgHelper.cs
│ │ ├── ITokenManager.cs
│ │ └── TokenManager.cs
│ ├── Entities
│ │ ├── Base
│ │ │ ├── BaseItem.cs
│ │ │ └── BaseType.cs
│ │ ├── BlackRecord.cs
│ │ ├── Blog
│ │ │ ├── Article.cs
│ │ │ ├── ArticleCollection.cs
│ │ │ ├── ArticleDraft.cs
│ │ │ ├── Channel.cs
│ │ │ ├── ChannelTag.cs
│ │ │ ├── Classify.cs
│ │ │ ├── Collection.cs
│ │ │ ├── Comment.cs
│ │ │ ├── Notification.cs
│ │ │ ├── Tag.cs
│ │ │ ├── TagArticle.cs
│ │ │ ├── UserLike.cs
│ │ │ ├── UserSubscribe.cs
│ │ │ └── UserTag.cs
│ │ ├── LinFile.cs
│ │ ├── LinGroup.cs
│ │ ├── LinGroupPermission.cs
│ │ ├── LinLog.cs
│ │ ├── LinPermission.cs
│ │ ├── LinUser.cs
│ │ ├── LinUserGroup.cs
│ │ ├── LinUserIdentity.cs
│ │ ├── SerilogDO.cs
│ │ └── Settings
│ │ │ └── LinSetting.cs
│ ├── Exceptions
│ │ └── LinCmsException.cs
│ ├── Extensions
│ │ ├── CollectionsExtensions.cs
│ │ ├── HttpContextExtensions.cs
│ │ └── LinCmsTimeConverter.cs
│ ├── IRepositories
│ │ ├── IFileRepository.cs
│ │ ├── ILogRepository.cs
│ │ ├── ISettingRepository.cs
│ │ └── IUserRepository.cs
│ ├── LinCms.Core.csproj
│ ├── LinCms.Core.xml
│ ├── Middleware
│ │ └── CustomExceptionMiddleWare.cs
│ └── Security
│ │ ├── CurrentUserExtensions.cs
│ │ └── LinCmsClaimTypes.cs
├── LinCms.Infrastructure
│ ├── FreeSql
│ │ ├── CodeFirstExtension.cs
│ │ ├── DataSeedContributor.cs
│ │ ├── FreeSqlExtension.cs
│ │ └── IDataSeedContributor.cs
│ ├── LinCms.Infrastructure.csproj
│ └── Repositories
│ │ ├── FileRepository.cs
│ │ ├── LogRepository.cs
│ │ ├── SettingRepository.cs
│ │ └── UserRepository.cs
├── LinCms.Plugins
│ ├── LinCms.Plugins.csproj
│ └── Poem
│ │ ├── Controllers
│ │ └── PoemController.cs
│ │ ├── Domain
│ │ └── LinPoem.cs
│ │ ├── Models
│ │ ├── CreateUpdatePoemDto.cs
│ │ └── PoemDto.cs
│ │ ├── PoemModule.cs
│ │ └── Services
│ │ ├── IPoemService.cs
│ │ ├── PoemProfile.cs
│ │ └── PoemService.cs
├── LinCms.Scaffolding
│ ├── App.cs
│ ├── CodeScaffolding.cs
│ ├── Entities
│ │ ├── CommandOption.cs
│ │ ├── EntityInfo.cs
│ │ ├── ProjectInfo.cs
│ │ ├── PropertyInfo.cs
│ │ └── SettingOptions.cs
│ ├── Extensions.cs
│ ├── LinCms.Scaffolding.csproj
│ ├── Program.cs
│ ├── Templates
│ │ ├── lin-cms-vue
│ │ │ ├── model
│ │ │ │ └── {{EntityInfo.NameCamelize}}.js.txt
│ │ │ ├── stage-config.js.txt
│ │ │ └── view
│ │ │ │ └── {{EntityInfo.NameCamelize}}
│ │ │ │ ├── {{EntityInfo.NameCamelize}}-form.vue.txt
│ │ │ │ └── {{EntityInfo.NameCamelize}}-list.vue.txt
│ │ ├── {{ProjectInfo.FullName}}.Application.Contracts
│ │ │ └── {{SettingOptions.Areas}}
│ │ │ │ └── {{EntityInfo.NamePluralized}}
│ │ │ │ ├── CreateUpdate{{EntityInfo.Name}}Dto.cs.txt
│ │ │ │ ├── I{{EntityInfo.Name}}Service.cs.txt
│ │ │ │ └── {{EntityInfo.Name}}Dto.cs.txt
│ │ ├── {{ProjectInfo.FullName}}.Application
│ │ │ └── {{SettingOptions.Areas}}
│ │ │ │ └── {{EntityInfo.NamePluralized}}
│ │ │ │ ├── {{EntityInfo.Name}}Profile.cs.txt
│ │ │ │ └── {{EntityInfo.Name}}Service.cs.txt
│ │ ├── {{ProjectInfo.FullName}}.Core
│ │ │ └── IRepositories
│ │ │ │ └── I{{EntityInfo.Name}}Repository.cs.txt
│ │ ├── {{ProjectInfo.FullName}}.Infrastructure
│ │ │ └── Repositories
│ │ │ │ └── {{EntityInfo.Name}}Repository.cs.txt
│ │ └── {{ProjectInfo.FullName}}.Web
│ │ │ └── Controllers
│ │ │ └── {{SettingOptions.Areas}}
│ │ │ └── {{EntityInfo.Name}}Controller.cs.txt
│ ├── Util.cs
│ └── appsettings.json
└── LinCms.Web
│ ├── Controllers
│ ├── ApiControllerBase.cs
│ ├── Base
│ │ ├── BaseItemController.cs
│ │ └── BaseTypeController.cs
│ ├── Blog
│ │ ├── ArticleController.cs
│ │ ├── ArticleDraftController.cs
│ │ ├── AuthorCenterController.cs
│ │ ├── ChannelController.cs
│ │ ├── ClassifyController.cs
│ │ ├── CollectionController.cs
│ │ ├── CommentController.cs
│ │ ├── NotificationController.cs
│ │ ├── TagController.cs
│ │ ├── UserLikeController.cs
│ │ ├── UserSubscribeController.cs
│ │ └── UserTagController.cs
│ ├── Cms
│ │ ├── AccountController.cs
│ │ ├── AdminController.cs
│ │ ├── FileController.cs
│ │ ├── GroupController.cs
│ │ ├── LogController.cs
│ │ ├── Oauth2Controller.cs
│ │ ├── PermissionController.cs
│ │ ├── SettingController.cs
│ │ └── UserController.cs
│ └── v1
│ │ ├── MonitorController.cs
│ │ └── QiniuController.cs
│ ├── Data
│ ├── Authorization
│ │ ├── PermissionAuthorizationHandler.cs
│ │ └── ValidJtiHandler.cs
│ └── MigrationStartupTask.cs
│ ├── Dockerfile
│ ├── Fonts
│ └── JetBrainsMono-Bold.ttf
│ ├── LinCms.Web.csproj
│ ├── LinCms.Web.xml
│ ├── Middleware
│ ├── AopCacheAsyncIntercept.cs
│ ├── AopCacheIntercept.cs
│ ├── AopCacheableActionFilter.cs
│ ├── BasicAuthenticationMiddleware.cs
│ ├── CacheableMethodInfoExtensions.cs
│ ├── IpLimitMiddleware.cs
│ └── RecaptchaVerifyActionFilter.cs
│ ├── Models
│ └── Options
│ │ └── GooglereCAPTCHAOptions.cs
│ ├── Properties
│ └── launchSettings.json
│ ├── RateLimitConfig.json
│ ├── Startup
│ ├── Configuration
│ │ ├── AutofacModule.cs
│ │ ├── RepositoryModule.cs
│ │ └── ServiceModule.cs
│ ├── JwtExtensions.cs
│ ├── Program.cs
│ ├── ServiceCollectionExtensions.cs
│ ├── ServiceProviderExtensions.cs
│ └── SwaggerExtensions.cs
│ ├── Utils
│ ├── LogHelper.cs
│ ├── MultipartRequestHelper.cs
│ ├── ReflexHelper.cs
│ ├── StopWords.cs
│ └── ToolGoodUtils.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── wwwroot
│ └── _Illegal.zip
└── test
└── LinCms.Test
├── Core
└── EmailSenderTest.cs
├── EnumTest.cs
├── ExpandObjTest.cs
├── LinCms.Test.csproj
├── LinCmsTest.cs
├── Md5CommonTest.cs
├── Properties
└── launchSettings.json
├── ReflexTest.cs
├── Repositories
└── Blog
│ ├── ArticleRepositoryTest.cs
│ ├── CommentRepositoryTest.cs
│ ├── TagRepositoryTest.cs
│ └── UserSubscribeRepositoryTest.cs
├── Service
├── Base
│ └── BaseTypeServiceTest.cs
├── Blog
│ └── ArticleServiceTest.cs
└── Cms
│ ├── LogServiceTest.cs
│ └── UserServiceTest.cs
├── Startup.cs
├── Utils
└── ToolWordTest.cs
├── appsettings.Development.json
└── appsettings.json
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.classpath
2 | **/.dockerignore
3 | **/.env
4 | **/.git
5 | **/.gitignore
6 | **/.project
7 | **/.settings
8 | **/.toolstarget
9 | **/.vs
10 | **/.vscode
11 | **/*.*proj.user
12 | **/*.dbmdl
13 | **/*.jfm
14 | **/azds.yaml
15 | **/bin
16 | **/charts
17 | **/docker-compose*
18 | **/Dockerfile*
19 | **/node_modules
20 | **/npm-debug.log
21 | **/obj
22 | **/secrets.dev.yaml
23 | **/values.dev.yaml
24 | LICENSE
25 | README.md
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # CS1570: XML 注释出现 XML 格式错误
4 | dotnet_diagnostic.CS1570.severity = none
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **重现步骤(可选):**
11 |
12 | **期望的结果是什么?**
13 |
14 | **实际的结果是什么?**
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **描述你希望的支持的新功能?**
11 |
12 | **你期望的 API 是怎样的?**
13 |
--------------------------------------------------------------------------------
/.github/workflows/docfx.yml:
--------------------------------------------------------------------------------
1 | name: .NET Core Deploy Docfx
2 |
3 | on:
4 | push:
5 | branches: [master]
6 | pull_request:
7 | branches: [master]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v2
16 | - name: Setup .NET Core
17 | uses: actions/setup-dotnet@v1
18 | with:
19 | dotnet-version: 7.0.101
20 | - name: Install dependencies
21 | run: dotnet restore LinCms.sln
22 | - name: Build solution
23 | run: dotnet build LinCms.sln --configuration Release --no-restore
24 |
25 | generate-docs:
26 | runs-on: windows-latest
27 | needs: build
28 |
29 | steps:
30 | - name: Checkout
31 | uses: actions/checkout@v2
32 | - name: Setup .NET Core
33 | uses: actions/setup-dotnet@v1
34 | with:
35 | dotnet-version: 7.0.101
36 | - name: Install dependencies
37 | run: dotnet restore LinCms.sln
38 | - name: Setup DocFX
39 | uses: crazy-max/ghaction-chocolatey@v1
40 | with:
41 | args: install docfx
42 | - name: DocFX Build
43 | working-directory: docs
44 | run: docfx docfx.json
45 | continue-on-error: false
46 | - name: Publish
47 | if: github.event_name == 'push'
48 | uses: peaceiris/actions-gh-pages@v3
49 | with:
50 | github_token: ${{ secrets.GITHUB_TOKEN }}
51 | publish_dir: docs/_site
52 | force_orphan: true
53 |
--------------------------------------------------------------------------------
/.github/workflows/gitee-mirror.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | - gh-pages
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Sync to Gitee 💕
14 | uses: wearerequired/git-mirror-action@master
15 | env:
16 | SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
17 | with:
18 | source-repo: "git@github.com:luoyunchong/lin-cms-dotnetcore.git"
19 | destination-repo: "git@gitee.com:igeekfan/lin-cms-dotnetcore.git"
20 |
--------------------------------------------------------------------------------
/Delete BIN OBJ Folders.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | @echo Deleting all BIN, OBJ folders...
3 | for /d /r . %%d in (bin,obj) do @if exist "%%d" rd /s/q "%%d"
4 | @echo.
5 | @echo BIN and OBJ folders successfully deleted :) Close the window.
6 | @echo.
7 | @echo.
8 | pause > nul
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | https://github.com/luoyunchong/lin-cms-dotnetcore
5 | true
6 | true
7 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 IGeekFan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LinCms.Scaffolding.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30223.230
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LinCms.Scaffolding", "src\LinCms.Scaffolding\LinCms.Scaffolding.csproj", "{FC1AC12F-338B-4608-ABF3-F301BF631F21}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {FC1AC12F-338B-4608-ABF3-F301BF631F21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {FC1AC12F-338B-4608-ABF3-F301BF631F21}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {FC1AC12F-338B-4608-ABF3-F301BF631F21}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {FC1AC12F-338B-4608-ABF3-F301BF631F21}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {60090452-8177-4B47-B59D-CE49B7D519F9}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 |
2 | trigger:
3 | - master
4 |
5 | pool:
6 | vmImage: 'ubuntu-latest'
7 |
8 | variables:
9 | dockerId: luoyunchong@foxmail.com
10 | namespace: igeekfan
11 | webimageName: lincms-web
12 | registry: registry.cn-hangzhou.aliyuncs.com
13 | linCmsWebdockerfilepath: src/LinCms.Web/Dockerfile
14 |
15 | steps:
16 | - script: |
17 | docker build -f $(linCmsWebdockerfilepath) -t $(webimageName) .
18 | echo $(pwd) | docker login --username $(dockerId) $(registry) --password-stdin
19 | docker tag $(webimageName) $(registry)/$(namespace)/$(webimageName)
20 | docker push $(registry)/$(namespace)/$(webimageName)
21 |
22 | displayName: push to lincms-web
--------------------------------------------------------------------------------
/build-all.ps1:
--------------------------------------------------------------------------------
1 | # COMMON PATHS
2 |
3 | $rootFolder = (Get-Item -Path "./" -Verbose).FullName
4 |
5 | # List of solutions
6 |
7 | $solutionPaths = (
8 | ""
9 | )
10 |
11 | # Build all solutions
12 |
13 | foreach ($solutionPath in $solutionPaths) {
14 | $solutionAbsPath = (Join-Path $rootFolder $solutionPath)
15 | Set-Location $solutionAbsPath
16 | dotnet build
17 | if (-Not $?) {
18 | Write-Host ("Build failed for the solution: " + $solutionPath)
19 | Set-Location $rootFolder
20 | exit $LASTEXITCODE
21 | }
22 | }
23 |
24 | Set-Location $rootFolder
--------------------------------------------------------------------------------
/build_push.sh:
--------------------------------------------------------------------------------
1 | SERVER_NAME=lincms-web
2 | SERVER_Dockerfile=src/LinCms.Web/Dockerfile
3 | CID=$(docker ps | grep "${SERVER_NAME}" | awk '{print $1}')
4 | IID=$(docker images | grep "${SERVER_NAME}" | awk '{print $3}')
5 |
6 | docker rmi ${SERVER_NAME}
7 | docker build -f ${SERVER_Dockerfile} -t "${SERVER_NAME}":latest .
8 | docker tag ${SERVER_NAME} registry.cn-hangzhou.aliyuncs.com/igeekfan/${SERVER_NAME}
9 | docker push registry.cn-hangzhou.aliyuncs.com/igeekfan/${SERVER_NAME}
10 | docker image prune -f
11 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/docs/README.md
--------------------------------------------------------------------------------
/docs/api/index.md:
--------------------------------------------------------------------------------
1 | # PLACEHOLDER
2 | TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*!
3 |
--------------------------------------------------------------------------------
/docs/articles/intro.md:
--------------------------------------------------------------------------------
1 | # Add your introductions here!
2 |
--------------------------------------------------------------------------------
/docs/articles/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Introduction
2 | href: intro.md
3 |
--------------------------------------------------------------------------------
/docs/docfx.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "src": [
5 | {
6 | "files": [
7 | "**/*.csproj"
8 | ],
9 | "exclude": [
10 | "**/bin/**",
11 | "**/obj/**"
12 | ],
13 | "src": "../src"
14 | }
15 | ],
16 | "dest": "api",
17 | "disableGitFeatures": false,
18 | "disableDefaultFilter": false
19 | }
20 | ],
21 | "build": {
22 | "content": [
23 | {
24 | "files": [
25 | "api/**.yml",
26 | "api/index.md"
27 | ]
28 | },
29 | {
30 | "files": [
31 | "articles/**.md",
32 | "articles/**/toc.yml",
33 | "toc.yml",
34 | "*.md"
35 | ]
36 | }
37 | ],
38 | "resource": [
39 | {
40 | "files": [
41 | "images/**"
42 | ]
43 | }
44 | ],
45 | "overwrite": [
46 | {
47 | "files": [
48 | "apidoc/**.md"
49 | ],
50 | "exclude": [
51 | "obj/**",
52 | "_site/**"
53 | ]
54 | }
55 | ],
56 | "dest": "_site",
57 | "globalMetadataFiles": [],
58 | "fileMetadataFiles": [],
59 | "template": [
60 | "default"
61 | ],
62 | "postProcessors": [],
63 | "markdownEngineName": "markdig",
64 | "noLangKeyword": false,
65 | "keepFileLink": false,
66 | "cleanupCacheHistory": false,
67 | "disableGitFeatures": false
68 | }
69 | }
--------------------------------------------------------------------------------
/docs/images/qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/docs/images/qq.png
--------------------------------------------------------------------------------
/docs/images/wechat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/docs/images/wechat.png
--------------------------------------------------------------------------------
/docs/images/使用Bearer.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/docs/images/使用Bearer.PNG
--------------------------------------------------------------------------------
/docs/images/登录接口.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/docs/images/登录接口.PNG
--------------------------------------------------------------------------------
/docs/images/返回access_token.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/docs/images/返回access_token.PNG
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # This is the **HOMEPAGE**.
2 | Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files.
3 | ## Quick Start Notes:
4 | 1. Add images to the *images* folder if the file is referencing an image.
5 |
--------------------------------------------------------------------------------
/docs/sql/README.md:
--------------------------------------------------------------------------------
1 | ## Code First
2 |
3 | 会自动创建数据库和初始化数据。
4 |
5 | - 默认账号:admin
6 |
7 | - 默认密码123qwe
--------------------------------------------------------------------------------
/docs/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Articles
2 | href: articles/
3 | - name: Api Documentation
4 | href: api/
5 | homepage: api/index.md
6 |
--------------------------------------------------------------------------------
/publish.bat:
--------------------------------------------------------------------------------
1 |
2 | @echo off
3 |
4 | dotnet clean
5 | dotnet restore
6 | dotnet build
7 |
8 | DEL /F/Q/S "D:\Publishes\lin-cms-dotnetcore" > NUL && RMDIR /Q/S "D:\Publishes\lin-cms-dotnetcore"
9 |
10 | ::dotnet publish -c Release -r win-x64 --self-contained false -o "D:\Publishes\lin-cms-dotnetcore\win-x64"
11 | ::dotnet publish -c Release -r win-x86 --self-contained false -o "D:\Publishes\lin-cms-dotnetcore\win-x86"
12 | ::dotnet publish -c Release -r osx-x64 --self-contained false -o "D:\Publishes\lin-cms-dotnetcore\osx-x64"
13 | dotnet publish -c Release -r linux-x64 --self-contained false -o "D:\Publishes\lin-cms-dotnetcore\linux-x64"
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | SERVER_NAME=lincms-web
2 |
3 | #判断是否存在webnotebook容器
4 | docker ps | grep lincms-web &> /dev/null
5 | #如果不存在,则Remove
6 | if [ $? -ne 0 ]
7 | then
8 | echo "${SERVER_NAME} container not exist continue.. "
9 | else
10 | echo "remove ${SERVER_NAME} container"
11 | docker rm ${SERVER_NAME} -f
12 | fi
13 |
14 | docker images | grep registry.cn-hangzhou.aliyuncs.com/igeekfan/${SERVER_NAME} &> /dev/null
15 |
16 | if [ $? -ne 0 ]
17 | then
18 | echo "image does not exist , continue..."
19 | else
20 | echo "image exists !!! remove it"
21 | docker rmi --force registry.cn-hangzhou.aliyuncs.com/igeekfan/${SERVER_NAME}
22 | fi
23 | #从阿里云拉取刚刚push的镜像
24 | docker pull registry.cn-hangzhou.aliyuncs.com/igeekfan/${SERVER_NAME}
25 |
26 | sudo docker run --restart \
27 | unless-stopped \
28 | -p 5011:8080 \
29 | -v /var/www/lin-cms-dotnetcore/wwwroot/:/app/wwwroot:rw \
30 | -v /var/www/lin-cms-dotnetcore/appsettings.Production.json/:/app/appsettings.Production.json:rw \
31 | --privileged=true \
32 | --name ${SERVER_NAME} \
33 | -d registry.cn-hangzhou.aliyuncs.com/igeekfan/${SERVER_NAME}
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Base/BaseItems/BaseItemDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Base.BaseItems;
5 |
6 | public class BaseItemDto : EntityDto
7 | {
8 | public long BaseTypeId { get; set; }
9 | public string ItemCode { get; set; }
10 | public string ItemName { get; set; }
11 | public bool Status { get; set; }
12 | public int? SortCode { get; set; }
13 | public DateTime CreateTime { get; set; }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Base/BaseItems/CreateUpdateBaseItemDto.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.DataAnnotations;
3 |
4 | namespace LinCms.Base.BaseItems;
5 |
6 | public class CreateUpdateBaseItemDto : IValidatableObject
7 | {
8 | public int BaseTypeId { get; set; }
9 | [Required(ErrorMessage = "编码为必填项")]
10 | public string ItemCode { get; set; }
11 | [Required(ErrorMessage = "字典类别为必填项")]
12 | public string ItemName { get; set; }
13 | public bool Status { get; set; }
14 | public int? SortCode { get; set; }
15 | public IEnumerable Validate(ValidationContext validationContext)
16 | {
17 | if (BaseTypeId == 0)
18 | {
19 | yield return new ValidationResult("请选择类别", new List() { "BaseTypeId" });
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Base/BaseItems/IBaseItemService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 |
4 | namespace LinCms.Base.BaseItems;
5 |
6 | public interface IBaseItemService
7 | {
8 | Task DeleteAsync(int id);
9 |
10 | Task> GetListAsync(string typeCode);
11 |
12 | Task GetAsync(int id);
13 |
14 | Task CreateAsync(CreateUpdateBaseItemDto createBaseItem);
15 |
16 | Task UpdateAsync(int id, CreateUpdateBaseItemDto updateBaseItem);
17 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Base/BaseTypes/BaseTypeDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Base.BaseTypes;
5 |
6 | public class BaseTypeDto : EntityDto
7 | {
8 | public string TypeCode { get; set; }
9 | public string FullName { get; set; }
10 | public int? SortCode { get; set; }
11 | public DateTime CreateTime { get; set; }
12 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Base/BaseTypes/CreateUpdateBaseTypeDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Base.BaseTypes;
4 |
5 | public class CreateUpdateBaseTypeDto
6 | {
7 | [Required(ErrorMessage = "类别编码为必填项")]
8 | public string TypeCode { get; set; }
9 | [Required(ErrorMessage = "类别名称为必填项")]
10 | public string FullName { get; set; }
11 | public int? SortCode { get; set; }
12 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Base/BaseTypes/IBaseTypeService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 |
4 | namespace LinCms.Base.BaseTypes;
5 |
6 | public interface IBaseTypeService
7 | {
8 | Task DeleteAsync(long id);
9 |
10 | Task> GetListAsync();
11 |
12 | Task GetAsync(int id);
13 |
14 | Task CreateAsync(CreateUpdateBaseTypeDto createBaseType);
15 |
16 | Task UpdateAsync(int id, CreateUpdateBaseTypeDto updateBaseType);
17 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/ArticleDrafts/ArticleDraftDto.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Blog.ArticleDrafts;
2 |
3 | public class ArticleDraftDto
4 | {
5 | public string Title { get; set; }
6 | public string Content { get; set; }
7 | public int Editor { get; set; }
8 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/ArticleDrafts/IArticleDraftService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace LinCms.Blog.ArticleDrafts;
5 |
6 | public interface IArticleDraftService
7 | {
8 | Task UpdateAsync(Guid id, UpdateArticleDraftDto updateArticleDto);
9 |
10 | Task GetAsync(Guid id);
11 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/ArticleDrafts/UpdateArticleDraftDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Blog.ArticleDrafts;
4 |
5 | public class UpdateArticleDraftDto
6 | {
7 | [MaxLength(200)]
8 | public string Title { get; set; }
9 |
10 | [Required(ErrorMessage = "随笔内容不能为空")]
11 | public string Content { get; set; }
12 |
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Articles/ArticleListDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Blog.Tags;
5 | using LinCms.Cms.Users;
6 | using LinCms.Common;
7 | using LinCms.Entities.Blog;
8 |
9 | namespace LinCms.Blog.Articles;
10 |
11 | public class ArticleListDto : Entity, ICreateAuditEntity
12 | {
13 | ///
14 | /// 技术频道Id
15 | ///
16 | public Guid? ChannelId { get; set; }
17 | ///
18 | /// 几小时/秒前
19 | ///
20 | public string TimeSpan => LinCmsUtils.GetTimeDifferNow(CreateTime.ToDateTime());
21 |
22 | private readonly DateTime _now = DateTime.Now;
23 | public bool IsNew => DateTime.Compare(_now.AddDays(-2), CreateTime.ToDateTime()) <= 0;
24 |
25 | public string Title { get; set; }
26 | public string Keywords { get; set; }
27 | public string Excerpt { get; set; }
28 | public int ViewHits { get; set; }
29 | public int CommentQuantity { get; set; }
30 | public int LikesQuantity { get; set; }
31 | public string Thumbnail { get; set; }
32 | public string ThumbnailDisplay { get; set; }
33 | public bool IsAudit { get; set; }
34 | public bool Recommend { get; set; }
35 | public bool IsStickie { get; set; }
36 | public string Archive { get; set; }
37 | public ArticleType ArticleType { get; set; }
38 | public long? CreateUserId { get; set; }
39 | public string CreateUserName { get; set; }
40 |
41 | public DateTime CreateTime { get; set; }
42 | public string Author { get; set; }
43 | public bool IsLiked { get; set; }
44 |
45 | public OpenUserDto UserInfo { get; set; }
46 |
47 | public List Tags { get; set; }
48 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Articles/ArticleSearchDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Data;
3 |
4 | namespace LinCms.Blog.Articles;
5 |
6 | public class ArticleSearchDto : PageDto
7 | {
8 | ///
9 | /// 分类Id
10 | ///
11 | public Guid? ClassifyId { get; set; }
12 | public Guid? ChannelId { get; set; }
13 | public Guid? TagId { get; set; }
14 | public string Title { get; set; }
15 | public Guid? ArticleId { get; set; }
16 | public long? UserId { get; set; }
17 |
18 | ///
19 | /// 收藏集合Id
20 | ///
21 | public Guid? CollectionId { get; set; }
22 |
23 | public ArticleSearchTypeEnum? ArticleSearchType { get; set; }
24 | public override string ToString()
25 | {
26 | return $"{ClassifyId}:{ChannelId}:{TagId}:{Title}:{UserId}:{Count}:{Page}:{Sort}";
27 | }
28 |
29 | }
30 |
31 |
32 | public enum ArticleSearchTypeEnum
33 | {
34 | ///
35 | /// 点赞
36 | ///
37 | Like,
38 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Articles/CreateUpdateArticleDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using LinCms.Entities.Blog;
5 |
6 | namespace LinCms.Blog.Articles;
7 |
8 | public class CreateUpdateArticleDto
9 | {
10 | public Guid? ClassifyId { get; set; }
11 | public Guid? ChannelId { get; set; }
12 | [MaxLength(200)]
13 | public string Title { get; set; }
14 | [MaxLength(400)]
15 | public string Keywords { get; set; }
16 | [MaxLength(400)]
17 | public string Source { get; set; }
18 | [MaxLength(400)]
19 | public string Excerpt { get; set; }
20 | [Required(ErrorMessage = "随笔内容不能为空")]
21 | public string Content { get; set; }
22 | [MaxLength(400)]
23 | public string Thumbnail { get; set; }
24 | public bool IsAudit { get; set; }
25 | public bool Recommend { get; set; }
26 | public bool IsStickie { get; set; }
27 | [MaxLength(50)]
28 | public string Archive { get; set; }
29 |
30 | public ArticleType ArticleType { get; set; }
31 |
32 | public int Editor { get; set; } = 1;
33 |
34 | public List TagIds { get; set; }
35 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Articles/IArticleService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 | using LinCms.Data;
5 |
6 | namespace LinCms.Blog.Articles;
7 |
8 | public interface IArticleService
9 | {
10 | #region CRUD
11 | Task CreateAsync(CreateUpdateArticleDto createArticle);
12 |
13 | Task UpdateAsync(Guid id, CreateUpdateArticleDto updateArticleDto);
14 |
15 | Task> GetArticleAsync(ArticleSearchDto searchDto);
16 |
17 | Task DeleteAsync(Guid id);
18 |
19 | Task GetAsync(Guid id);
20 | #endregion
21 |
22 |
23 | Task> GetAllArticleAsync(ArticleSearchDto searchDto);
24 |
25 | ///
26 | /// 得到我关注的人发布的随笔
27 | ///
28 | ///
29 | ///
30 | Task> GetSubscribeArticleAsync(PageDto pageDto);
31 |
32 | ///
33 | /// 更新随笔点赞量
34 | ///
35 | ///
36 | ///
37 | ///
38 | Task UpdateLikeQuantityAysnc(Guid subjectId, int likesQuantity);
39 |
40 | Task UpdateCollectQuantityAysnc(Guid articleId, int collectQuantity);
41 |
42 | ///
43 | /// 修改随笔是否允许其他人评论
44 | ///
45 | ///
46 | ///
47 | ///
48 | Task UpdateCommentable(Guid id, bool commentable);
49 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/AuthorCenter/ArticleCardDto.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Blog.AuthorCenter;
2 |
3 | ///
4 | /// 文章统计Card
5 | ///
6 | public class ArticleCardDto
7 | {
8 | ///
9 | /// 总文章数
10 | ///
11 | public long AllArticle { get; set; }
12 |
13 | ///
14 | /// 文章收藏数
15 | ///
16 | public long AllArticleCollect { get; set; }
17 |
18 | ///
19 | /// 文章评论数
20 | ///
21 | public long AllArticleComment { get; set; }
22 |
23 | ///
24 | /// 文章点赞数
25 | ///
26 | public long AllArticleStar { get; set; }
27 |
28 | ///
29 | /// 文章阅读数
30 | ///
31 | public long AllArticleView { get; set; }
32 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/AuthorCenter/IAuthorCenterService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace LinCms.Blog.AuthorCenter;
4 |
5 | ///
6 | /// 创建者中心
7 | ///
8 | public interface IAuthorCenterService : IApplicationService
9 | {
10 | ///
11 | /// 获取文章统计
12 | ///
13 | ///
14 | Task GetArtcileCardAsync();
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Channels/ChannelDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Blog.Tags;
5 |
6 | namespace LinCms.Blog.Channels;
7 |
8 | public class ChannelDto : Entity
9 | {
10 | ///
11 | /// 封面图
12 | ///
13 | public string Thumbnail { get; set; }
14 |
15 | public string ThumbnailDisplay { get; set; }
16 | ///
17 | /// 排序
18 | ///
19 | public int SortCode { get; set; }
20 | ///
21 | /// 技术频道名称
22 | ///
23 |
24 | public string ChannelName { get; set; }
25 |
26 | ///
27 | /// 编码
28 | ///
29 | public string ChannelCode { get; set; }
30 |
31 | ///
32 | /// 备注描述
33 | ///
34 | public string Remark { get; set; }
35 |
36 | public bool Status { get; set; }
37 |
38 |
39 | public List Tags { get; set; }
40 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Channels/ChannelSearchDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Data;
2 |
3 | namespace LinCms.Blog.Channels;
4 |
5 | public class ChannelSearchDto : PageDto
6 | {
7 | public string ChannelName { get; set; }
8 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Channels/CreateUpdateChannelDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace LinCms.Blog.Channels;
5 |
6 | public class CreateUpdateChannelDto
7 | {
8 | ///
9 | /// 封面图
10 | ///
11 | public string Thumbnail { get; set; }
12 | ///
13 | /// 排序
14 | ///
15 | public int SortCode { get; set; }
16 | ///
17 | /// 技术频道名称
18 | ///
19 |
20 | public string ChannelName { get; set; }
21 |
22 | ///
23 | /// 编码
24 | ///
25 | public string ChannelCode { get; set; }
26 |
27 | ///
28 | /// 备注描述
29 | ///
30 | public string Remark { get; set; }
31 | ///
32 | /// 是否有效
33 | ///
34 | public bool Status { get; set; }
35 |
36 | public List TagIds { get; set; }
37 |
38 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Channels/IChannelService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 | using LinCms.Data;
5 |
6 | namespace LinCms.Blog.Channels;
7 |
8 | ///
9 | /// 技术频道
10 | ///
11 | public interface IChannelService
12 | {
13 | #region CRUD
14 | Task> GetListAsync(ChannelSearchDto searchDto);
15 |
16 | Task GetAsync(Guid id);
17 |
18 | Task CreateAsync(CreateUpdateChannelDto createChannel);
19 |
20 | Task UpdateAsync(Guid id, CreateUpdateChannelDto updateChannel);
21 | Task DeleteAsync(Guid id);
22 | #endregion
23 |
24 | ///
25 | /// 首页减少不必要的字段后,流量字节更少
26 | ///
27 | ///
28 | ///
29 | Task> GetNavListAsync(PageDto pageDto);
30 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Channels/NavChannelListDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Blog.Tags;
5 |
6 | namespace LinCms.Blog.Channels;
7 |
8 | public class NavChannelListDto : Entity
9 | {
10 | ///
11 | /// 技术频道名称
12 | ///
13 |
14 | public string ChannelName { get; set; }
15 |
16 | ///
17 | /// 编码
18 | ///
19 | public string ChannelCode { get; set; }
20 |
21 |
22 | public List Tags { get; set; }
23 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Classifys/ClassifyDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Blog.Classifys;
5 |
6 | public class ClassifyDto : EntityDto, ICreateAuditEntity
7 | {
8 | public string Thumbnail { get; set; }
9 | public string ThumbnailDisplay { get; set; }
10 | public int SortCode { get; set; }
11 | public string ClassifyName { get; set; }
12 | public int ArticleCount { get; set; } = 0;
13 | public long? CreateUserId { get; set; }
14 | public string CreateUserName { get; set; }
15 | public DateTime CreateTime { get; set; }
16 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Classifys/ClassifySearchDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Data;
2 |
3 | namespace LinCms.Blog.Classifys;
4 |
5 | public class ClassifySearchDto : PageDto
6 | {
7 | public long? UserId { get; set; }
8 | public string ClassifyName { get; set; }
9 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Classifys/CreateUpdateClassifyDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Blog.Classifys;
4 |
5 | public class CreateUpdateClassifyDto
6 | {
7 | [Required(ErrorMessage = "请上传专栏图")]
8 | public string Thumbnail { get; set; }
9 | public int SortCode { get; set; }
10 | [Required(ErrorMessage = "分类专栏为必填项")]
11 | public string ClassifyName { get; set; }
12 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Classifys/IClassifyService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace LinCms.Blog.Classifys;
6 |
7 | ///
8 | /// 用户自己的分类
9 | ///
10 | public interface IClassifyService : ICrudAppService
11 | {
12 | Task UpdateArticleCountAsync(Guid? id, int inCreaseCount);
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Collections/CollectionDto.cs:
--------------------------------------------------------------------------------
1 | using IGeekFan.FreeKit.Extras.AuditEntity;
2 | using LinCms.Entities.Blog;
3 | using System;
4 |
5 | namespace LinCms.Blog.Collections;
6 |
7 | public class CollectionDto : EntityDto, ICreateAuditEntity
8 | {
9 | ///
10 | /// 名称
11 | ///
12 | public string Name { get; set; }
13 |
14 | ///
15 | /// 描述
16 | ///
17 | public string Remark { get; set; }
18 |
19 | ///
20 | /// 公开 当其他人关注此收藏集后不可再更改为隐私
21 | /// 隐私 仅自己可见此收藏集
22 | ///
23 | public PrivacyType PrivacyType { get; set; }
24 |
25 | public long? CreateUserId { get; set; }
26 | public string CreateUserName { get; set; }
27 | public DateTime CreateTime { get; set; }
28 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Collections/CollectionSearchDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Data;
2 | using System;
3 |
4 | namespace LinCms.Blog.Collections;
5 |
6 | public class CollectionSearchDto : PageDto
7 | {
8 | public string Name { get; set; }
9 |
10 | public long? UserId { get; set; }
11 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Collections/CreateCancelArticleCollectionDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Blog.Collections;
4 |
5 | public class CreateCancelArticleCollectionDto
6 | {
7 | public Guid ArticleId { get; set; }
8 | public Guid? CollectionId { get; set; }
9 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Collections/CreateUpdateCollectionDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 | using JetBrains.Annotations;
3 | using LinCms.Entities.Blog;
4 |
5 | namespace LinCms.Blog.Collections;
6 |
7 | public class CreateUpdateCollectionDto
8 | {
9 | public string Name { get; set; }
10 |
11 | ///
12 | /// 描述
13 | ///
14 | [CanBeNull]
15 | [StringLength(200,ErrorMessage = "描述最长为200")]
16 | public string Remark { get; set; }
17 |
18 | ///
19 | /// 公开 当其他人关注此收藏集后不可再更改为隐私
20 | /// 隐私 仅自己可见此收藏集
21 | ///
22 | public PrivacyType PrivacyType { get; set; }
23 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Collections/IArticleCollectionService.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luoyunchong/lin-cms-dotnetcore/e00f7c6e7a0a6c187a10d5ecda90ed9c911a55ff/src/LinCms.Application.Contracts/Blog/Collections/IArticleCollectionService.cs
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Collections/ICollectionService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 | using LinCms.Blog.Collections;
5 | using LinCms.Entities.Blog;
6 |
7 | namespace LinCms.Blog.Collections;
8 |
9 | ///
10 | /// 收藏夹服务
11 | ///
12 | public interface ICollectionService : ICrudAppService
13 | {
14 |
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Comments/CommentDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Cms.Users;
5 |
6 | namespace LinCms.Blog.Comments;
7 |
8 | public class CommentDto : EntityDto, ICreateAuditEntity
9 | {
10 | ///
11 | /// 回复评论Id
12 | ///
13 | public Guid? RespId { get; set; }
14 | ///
15 | /// 回复的文本内容
16 | ///
17 | public string Text { get; set; }
18 |
19 | ///
20 | /// 关联随笔id
21 | ///
22 | public Guid? SubjectId { get; set; }
23 |
24 | public long? CreateUserId { get; set; }
25 | public string CreateUserName { get; set; }
26 | public DateTime CreateTime { get; set; }
27 |
28 | ///
29 | /// 评论的用户
30 | ///
31 | public OpenUserDto UserInfo { get; set; }
32 |
33 | ///
34 | /// 回复的用户
35 | ///
36 | public OpenUserDto RespUserInfo { get; set; }
37 |
38 | public bool IsLiked { get; set; }
39 |
40 | public bool? IsAudit { get; set; }
41 |
42 | public int LikesQuantity { get; set; }
43 |
44 | public Guid? RootCommentId { get; set; }
45 | ///
46 | /// 最新的二条回复
47 | ///
48 | public List TopComment { get; set; }
49 |
50 |
51 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Comments/CommentSearchDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Data;
3 |
4 | namespace LinCms.Blog.Comments;
5 |
6 | public class CommentSearchDto : PageDto
7 | {
8 | public Guid? RootCommentId { get; set; }
9 | public Guid? SubjectId { get; set; }
10 |
11 | public String Text { get; set; }
12 |
13 | public bool? IsAudit { get; set; }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Comments/CreateCommentDto.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 |
4 | namespace LinCms.Blog.Comments;
5 |
6 | public class CreateCommentDto
7 | {
8 | ///
9 | /// 回复评论Id
10 | ///
11 | public Guid? RespId { get; set; }
12 | ///
13 | /// 根回复id
14 | ///
15 | public Guid? RootCommentId { get; set; }
16 | ///
17 | /// 回复的文本内容
18 | ///
19 | public string Text { get; set; }
20 | ///
21 | /// 关联随笔id
22 | ///
23 | public Guid? SubjectId { get; set; }
24 | ///
25 | /// 被回复的用户Id
26 | ///
27 | public long RespUserId { get; set; }
28 |
29 | public int SubjectType { get; set; }
30 | }
31 |
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Comments/ICommentService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 | using LinCms.Entities.Blog;
5 |
6 | namespace LinCms.Blog.Comments;
7 |
8 | ///
9 | /// 评论
10 | ///
11 | public interface ICommentService
12 | {
13 | ///
14 | /// 随笔下的评论列表
15 | ///
16 | ///
17 | ///
18 | Task> GetListByArticleAsync(CommentSearchDto commentSearchDto);
19 |
20 | ///
21 | /// 评论分页项
22 | ///
23 | ///
24 | ///
25 | Task> GetListAsync(CommentSearchDto commentSearchDto);
26 |
27 | ///
28 | /// 发表评论
29 | ///
30 | ///
31 | ///
32 | Task CreateAsync(CreateCommentDto createCommentDto);
33 |
34 | ///
35 | /// 删除评论并同步随笔数量
36 | ///
37 | ///
38 | Task DeleteAsync(Comment comment);
39 |
40 | ///
41 | /// 删除评论,先查一次
42 | ///
43 | /// 评论表Id
44 | Task DeleteAsync(Guid id);
45 |
46 | ///
47 | /// 只删除自己的评论
48 | ///
49 | ///
50 | ///
51 | Task DeleteMyComment(Guid id);
52 |
53 | ///
54 | /// 修改评论的点赞的数量
55 | ///
56 | ///
57 | ///
58 | ///
59 | Task UpdateLikeQuantityAysnc(Guid subjectId, int likesQuantity);
60 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/ArticleEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Blog.Notifications;
5 |
6 | public class ArticleEntry : EntityDto
7 | {
8 | public string Title { get; set; }
9 |
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/CommentEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Blog.Notifications;
5 |
6 | public class CommentEntry : EntityDto
7 | {
8 | public Guid? RespId { get; set; }
9 | public string Text { get; set; }
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/CreateNotificationDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.Notifications;
5 |
6 | public class CreateNotificationDto
7 | {
8 | public const string CreateOrCancelAsync = "CreateNotificationDto.CreateOrCancelAsync";
9 | public NotificationType NotificationType { get; set; }
10 | public Guid? ArticleId { get; set; }
11 | public Guid? CommentId { get; set; }
12 | public long NotificationRespUserId { get; set; }
13 | public long UserInfoId { get; set; }
14 |
15 | public bool IsCancel { get; set; }
16 | public DateTime CreateTime { get; set; }
17 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/IEventService.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Blog.Notifications;
2 |
3 | public interface IEventService
4 | {
5 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/INotificationService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 |
5 | namespace LinCms.Blog.Notifications;
6 |
7 | ///
8 | /// 消息通知
9 | ///
10 | public interface INotificationService
11 | {
12 | Task> GetListAsync(NotificationSearchDto pageDto);
13 |
14 | ///
15 | /// 新增一个消息通知,或取消消息通知
16 | ///
17 | ///
18 | Task CreateOrCancelAsync(CreateNotificationDto createNotificationDto);
19 |
20 | ///
21 | /// 设置消息通知为已读状态
22 | ///
23 | ///
24 | Task SetNotificationReadAsync(Guid id);
25 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/NotificationDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 | using LinCms.Cms.Users;
4 | using LinCms.Entities.Blog;
5 |
6 | namespace LinCms.Blog.Notifications;
7 |
8 | public class NotificationDto : EntityDto
9 | {
10 | public NotificationType NotificationType { get; set; }
11 | public OpenUserDto UserInfo { get; set; }
12 | public bool IsRead { get; set; }
13 | public long UserInfoId { get; set; }
14 | public long MessageRespUserId { get; set; }
15 | public DateTime CreateTime { get; set; }
16 | public ArticleEntry ArticleEntry { get; set; }
17 | public CommentEntry CommentEntry { get; set; }
18 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Notifications/NotificationSearchDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Data;
2 |
3 | namespace LinCms.Blog.Notifications;
4 |
5 | public class NotificationSearchDto : PageDto
6 | {
7 | public NotificationSearchType? NotificationSearchType { get; set; }
8 | }
9 |
10 | public enum NotificationSearchType
11 | {
12 | ///
13 | /// 用户点赞随笔、点赞评论
14 | ///
15 | UserLike = 0,
16 | ///
17 | /// 用户评论随笔、回复别人的评论
18 | ///
19 | UserComment = 1,
20 | ///
21 | /// 用户关注用户
22 | ///
23 | UserLikeUser = 2
24 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Tags/CreateUpdateTagDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Blog.Tags;
4 |
5 | public class CreateUpdateTagDto
6 | {
7 | [Required(ErrorMessage = "请上传标签封面")]
8 | public string Thumbnail { get; set; }
9 | [Required(ErrorMessage = "标签为必填项")]
10 | public string TagName { get; set; }
11 |
12 | public string Remark { get; set; }
13 |
14 | ///
15 | /// 别名
16 | ///
17 | [MaxLength(300, ErrorMessage = "请少于300个字符")]
18 | public string Alias { get; set; }
19 |
20 | public bool Status { get; set; }
21 |
22 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Tags/IUserTagService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace LinCms.Blog.Tags;
5 |
6 | public interface IUserTagService
7 | {
8 | ///
9 | /// 用户关注标签
10 | ///
11 | ///
12 | Task CreateUserTagAsync(Guid tagId);
13 |
14 | ///
15 | /// 当前用户取消关注标签
16 | ///
17 | ///
18 | ///
19 | Task DeleteUserTagAsync(Guid tagId);
20 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Tags/TagDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Blog.Tags;
5 |
6 | public class TagDto : EntityDto
7 | {
8 | public TagDto(Guid id, string tagName)
9 | {
10 | Id = id;
11 | TagName = tagName;
12 | }
13 |
14 | public string TagName { get; set; }
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Tags/TagListDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Blog.Tags;
5 |
6 | ///
7 | /// 后台列表List
8 | ///
9 | public class TagListDto : EntityDto
10 | {
11 | public string Thumbnail { get; set; }
12 | public string ThumbnailDisplay { get; set; }
13 | public string TagName { get; set; }
14 | public long CreateUserId { get; set; }
15 | public DateTime? CreateTime { get; set; }
16 | public string Alias { get; set; }
17 | public int ArticleCount { get; set; }
18 | public int SubscribersCount { get; set; }
19 | public int ViewHits { get; set; }
20 | public bool Status { get; set; }
21 | public bool IsSubscribe { get; set; }
22 | public string Remark { get; set; }
23 |
24 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Tags/TagSearchDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using LinCms.Data;
4 |
5 | namespace LinCms.Blog.Tags;
6 |
7 | public class TagSearchDto : PageDto
8 | {
9 | public List TagIds { get; set; }
10 | public string TagName { get; set; }
11 |
12 | public bool? Status { get; set; }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/Tags/UserTagDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Blog.Tags;
4 |
5 | public class UserTagDto
6 | {
7 | public Guid TagId { get; set; }
8 | public long CreateUserId { get; set; }
9 | public bool IsSubscribeed { get; set; }
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/UserLikes/CreateUpdateUserLikeDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.UserLikes;
5 |
6 | public class CreateUpdateUserLikeDto
7 | {
8 | public Guid SubjectId { get; set; }
9 | ///
10 | /// 1.随笔 2 评论
11 | ///
12 | public UserLikeSubjectType SubjectType { get; set; }
13 | }
14 |
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/UserLikes/IUserLikeService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace LinCms.Blog.UserLikes;
4 |
5 | ///
6 | /// 用户点赞
7 | ///
8 | public interface IUserLikeService
9 | {
10 | ///
11 | /// 点赞/取消点赞随笔、评论
12 | ///
13 | ///
14 | ///
15 | Task CreateOrCancelAsync(CreateUpdateUserLikeDto createUpdateUserLike);
16 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/UserSubscribes/IUserSubscribeService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 |
5 | namespace LinCms.Blog.UserSubscribes;
6 |
7 | ///
8 | /// 用户关注(订阅)服务接口
9 | ///
10 | public interface IUserSubscribeService
11 | {
12 | ///
13 | /// 得到某用户的关注的用户Id
14 | ///
15 | ///
16 | ///
17 | Task> GetSubscribeUserIdAsync(long userId);
18 |
19 | ///
20 | /// 得到某个用户的关注
21 | ///
22 | ///
23 | ///
24 | PagedResultDto GetUserSubscribeeeList(UserSubscribeSearchDto searchDto);
25 |
26 | ///
27 | /// 获取某个用户的粉丝
28 | ///
29 | ///
30 | ///
31 | PagedResultDto GetUserFansList(UserSubscribeSearchDto searchDto);
32 |
33 | ///
34 | /// 关注用户
35 | ///
36 | ///
37 | ///
38 | Task CreateAsync(long subscribeUserId);
39 |
40 | ///
41 | /// 取消关注
42 | ///
43 | ///
44 | ///
45 | Task DeleteAsync(long subscribeUserId);
46 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/UserSubscribes/SubscribeCountDto.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Blog.UserSubscribes;
2 |
3 | public class SubscribeCountDto
4 | {
5 | public long SubscribeCount { get; set; }
6 | public long FansCount { get; set; }
7 |
8 | public long TagCount { get; set; }
9 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/UserSubscribes/UserSubscribeDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Cms.Users;
2 |
3 | namespace LinCms.Blog.UserSubscribes;
4 |
5 | public class UserSubscribeDto
6 | {
7 | ///
8 | /// 被关注的用户Id
9 | ///
10 | public long SubscribeUserId { get; set; }
11 | ///
12 | /// 关注的用户Id
13 | ///
14 | public long CreateUserId { get; set; }
15 |
16 | ///
17 | /// 关注者
18 | ///
19 | public OpenUserDto Subscribeer { get; set; }
20 |
21 | public bool IsSubscribeed { get; set; }
22 |
23 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Blog/UserSubscribes/UserSubscribeSearchDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Data;
2 |
3 | namespace LinCms.Blog.UserSubscribes;
4 |
5 | public class UserSubscribeSearchDto : PageDto
6 | {
7 | public long UserId { get; set; }
8 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Account/IAccountService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using LinCms.Cms.Users;
4 |
5 | namespace LinCms.Cms.Account;
6 |
7 | ///
8 | /// 账号服务
9 | ///
10 | public interface IAccountService
11 | {
12 |
13 | ///
14 | /// 生成无状态的登录验证码
15 | ///
16 | ///
17 | LoginCaptchaDto GenerateCaptcha();
18 |
19 | ///
20 | /// 校验登录验证码
21 | ///
22 | ///
23 | ///
24 | ///
25 | bool VerifyCaptcha(String captcha, String tag);
26 |
27 | ///
28 | /// 注册前先发送邮件才能正常注册
29 | ///
30 | ///
31 | ///
32 | Task SendEmailCodeAsync(RegisterEmailCodeInput registerDto);
33 |
34 | ///
35 | /// 发送邮件:重置密码的验证码
36 | ///
37 | ///
38 | ///
39 | Task SendPasswordResetCodeAsync(SendEmailCodeInput sendEmailCode);
40 |
41 | ///
42 | /// 重置密码:根据邮件验证码
43 | ///
44 | ///
45 | ///
46 |
47 | Task ResetPasswordAsync(ResetEmailPasswordDto resetPassword);
48 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Account/ITokenService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IGeekFan.FreeKit.Extras.Security;
3 |
4 | namespace LinCms.Cms.Account;
5 |
6 | ///
7 | /// Token维护
8 | ///
9 | public interface ITokenService
10 | {
11 | ///
12 | /// 登录
13 | ///
14 | ///
15 | ///
16 | Task LoginAsync(LoginInputDto loginInputDto);
17 |
18 | ///
19 | /// 刷新token
20 | ///
21 | ///
22 | ///
23 | Task GetRefreshTokenAsync(string refreshToken);
24 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Account/LoginCaptchaDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Cms.Account
4 | {
5 | public class LoginCaptchaDto
6 | {
7 | public LoginCaptchaDto()
8 | {
9 | }
10 |
11 | public LoginCaptchaDto(string tag, string image)
12 | {
13 | Tag = tag ?? throw new ArgumentNullException(nameof(tag));
14 | Image = image ?? throw new ArgumentNullException(nameof(image));
15 | }
16 |
17 | ///
18 | /// 验证码图片地址,可使用base64
19 | ///
20 | public string Tag { get; set; }
21 | ///
22 | /// 加密后的验证码
23 | ///
24 | public string Image { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Account/LoginInputDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.ComponentModel.DataAnnotations;
3 | using JetBrains.Annotations;
4 |
5 | namespace LinCms.Cms.Account;
6 |
7 | public class LoginInputDto
8 | {
9 | ///
10 | /// 登录名:admin
11 | ///
12 | [Required(ErrorMessage = "登录名为必填项")]
13 | [DefaultValue("admin")]
14 | public string Username { get; set; }
15 | ///
16 | /// 密码:123qwe
17 | ///
18 | [Required(ErrorMessage = "密码为必填项")]
19 | [DefaultValue("123qwe")]
20 | public string Password { get; set; }
21 |
22 | ///
23 | /// 验证码
24 | ///
25 | [CanBeNull]
26 | public string Captcha { get; set; }
27 |
28 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Account/ResetEmailPasswordDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Account;
4 |
5 | public class ResetEmailPasswordDto
6 | {
7 | [Required(ErrorMessage = "非法请求")]
8 | public string Email { get; set; }
9 | [Required(ErrorMessage = "非法请求")]
10 | public string PasswordResetCode { get; set; }
11 |
12 | [Required(ErrorMessage = "请输入验证码")]
13 | public string ResetCode { get; set; }
14 | [Required(ErrorMessage = "请输入你的新密码")]
15 | [RegularExpression(AccountContract.PasswordRegex, ErrorMessage = AccountContract.PasswordErrorMessage)]
16 | public string Password { get; set; }
17 | }
18 |
19 | public class AccountContract
20 | {
21 | public const string PasswordRegex = "^(?![a-zA-Z]+$)(?!\\d+$)(?![^\\da-zA-Z\\s]+$).{6,20}$";
22 | public const string PasswordErrorMessage = "密码由字母、数字、特殊字符,任意2种组成,长度在6-20个字符之间";
23 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Account/SendEmailCodeInput.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.DataAnnotations;
3 | using System.Net.Mail;
4 |
5 | namespace LinCms.Cms.Account;
6 |
7 | public class SendEmailCodeInput : IValidatableObject
8 | {
9 | [Required(ErrorMessage = "请输入邮件")]
10 | public string Email { get; set; }
11 |
12 | public IEnumerable Validate(ValidationContext validationContext)
13 | {
14 | if (!Email.IsNullOrEmpty())
15 | {
16 |
17 | string address = null;
18 | try
19 | {
20 | address = new MailAddress(Email).Address;
21 | }
22 | catch
23 | {
24 | // ignored
25 | }
26 |
27 | if (address.IsNullOrEmpty())
28 | {
29 | yield return new ValidationResult("电子邮箱不符合规范,请输入正确的邮箱", new[] { "Email" });
30 | }
31 |
32 | }
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Admins/ResetPasswordDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Admins;
4 |
5 | public class ResetPasswordDto
6 | {
7 | [Required(ErrorMessage = "新密码不可为空")]
8 | [Compare("ConfirmPassword", ErrorMessage = "两次输入的密码不一致,请输入相同的密码")]
9 | //密码规则太麻烦, 记不住
10 | //[RegularExpression(@"^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,24}", ErrorMessage = "密码长度必须在8~24位之间,包含字母、数字、特殊字符")]
11 | [RegularExpression(@"^(?![a-zA-Z]+$)(?!\d+$)(?![^\da-zA-Z\s]+$).{6,16}$", ErrorMessage = "密码长度必须在6~16位之间,包含字母、数字、特殊字符中的二种")]
12 | public string NewPassword { get; set; }
13 | [Required(ErrorMessage = "请确认密码")]
14 | public string ConfirmPassword { get; set; }
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Admins/UpdateUserDto.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using LinCms.Data.Enums;
3 |
4 | namespace LinCms.Cms.Admins;
5 |
6 | public class UpdateUserDto
7 | {
8 | public string Email { get; set; }
9 | public string Nickname { get; set; }
10 | public string Username { get; set; }
11 | public UserStatus Active { get; set; }
12 | public List GroupIds { get; set; }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Admins/UserSearchDto.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 | using LinCms.Data;
3 |
4 | namespace LinCms.Cms.Admins;
5 |
6 | public class UserSearchDto : PageDto
7 | {
8 | public int? GroupId { get; set; }
9 |
10 | [CanBeNull] public string Email { get; set; }
11 | [CanBeNull] public string Nickname { get; set; }
12 | [CanBeNull] public string Username { get; set; }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Files/FileDto.cs:
--------------------------------------------------------------------------------
1 | using IGeekFan.FreeKit.Extras.AuditEntity;
2 |
3 | namespace LinCms.Cms.Files;
4 |
5 | public class FileDto : Entity
6 | {
7 | public string Key { get; set; }
8 | public string Path { get; set; }
9 | public string Url { get; set; }
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Files/IFileService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using Microsoft.AspNetCore.Http;
3 |
4 | namespace LinCms.Cms.Files;
5 |
6 | ///
7 | /// 文件服务
8 | ///
9 | public interface IFileService
10 | {
11 | ///
12 | /// 单文件上传,键为file
13 | ///
14 | ///
15 | ///
16 | ///
17 | Task UploadAsync(IFormFile file, int key = 0);
18 |
19 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Groups/CreateGroupDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Data;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 |
5 | namespace LinCms.Cms.Groups;
6 |
7 | public class CreateGroupDto : UpdateGroupDto, IValidatableObject
8 | {
9 | public List PermissionIds { get; set; }
10 |
11 | public IEnumerable Validate(ValidationContext validationContext)
12 | {
13 | if (PermissionIds.Count == 0)
14 | {
15 | yield return new ValidationResult("请选择权限", new List { "PermissionIds" });
16 | }
17 | }
18 | }
19 |
20 | public class GroupQuery:PageDto
21 | {
22 | public string Name { get; set; }
23 |
24 | ///
25 | /// 权限组描述
26 | ///
27 | public string Info { get; set; }
28 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Groups/GroupDto.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 | using LinCms.Entities;
4 |
5 | namespace LinCms.Cms.Groups;
6 |
7 | public class GroupDto : Entity
8 | {
9 | public List Permissions { get; set; }
10 | public string Name { get; set; }
11 | public string Info { get; set; }
12 | public bool IsStatic { get; set; }
13 |
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Groups/IGroupService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 | using LinCms.Entities;
5 |
6 | namespace LinCms.Cms.Groups;
7 |
8 | public interface IGroupService
9 | {
10 | Task> GetListAsync(GroupQuery query);
11 |
12 | Task GetAsync(long id);
13 |
14 | Task CreateAsync(CreateGroupDto inputDto);
15 |
16 | Task UpdateAsync(long id, UpdateGroupDto inputDto);
17 |
18 | ///
19 | /// 管理员删除一个权限分组
20 | ///
21 | ///
22 | ///
23 | Task DeleteAsync(long id);
24 |
25 | ///
26 | /// 根据用户Id删除用户分组
27 | ///
28 | ///
29 | ///
30 | Task DeleteUserGroupAsync(long userId);
31 |
32 | ///
33 | /// 检查该用户是否在root分组中
34 | ///
35 | ///
36 | ///
37 | bool CheckIsRootByUserId(long userId);
38 |
39 | ///
40 | /// 根据用户Id得到获得用户的所有分组id
41 | ///
42 | ///
43 | ///
44 | Task> GetGroupIdsByUserIdAsync(long userId);
45 |
46 | ///
47 | /// 删除用户与分组直接的关联
48 | ///
49 | /// 用户Id
50 | /// 删除的分组Id
51 | ///
52 | Task DeleteUserGroupAsync(long userId, List deleteGroupIds);
53 |
54 | ///
55 | /// 添加用户与分组直接的关联
56 | ///
57 | /// 用户Id
58 | /// 要新增的分组Id
59 | ///
60 | Task AddUserGroupAsync(long userId, List addGroupIds);
61 |
62 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Groups/UpdateGroupDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Groups;
4 |
5 | public class UpdateGroupDto
6 | {
7 | [Required(ErrorMessage = "请输入分组名称")]
8 | public string Name { get; set; }
9 | public string Info { get; set; }
10 | public int SortCode { get; set; }
11 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/ILogService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.Dto;
4 | using LinCms.Data;
5 | using LinCms.Entities;
6 |
7 | namespace LinCms.Cms.Logs;
8 |
9 | public interface ILogService
10 | {
11 | Task CreateAsync(LinLog linlog);
12 | PagedResultDto GetUserLogs(LogSearchDto searchDto);
13 |
14 | List GetLoggedUsers(PageDto searchDto);
15 |
16 | ///
17 | /// 管理端访问与用户统计
18 | ///
19 | ///
20 | VisitLogUserDto GetUserAndVisits();
21 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/ISerilogService.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IGeekFan.FreeKit.Extras.Dto;
3 | using LinCms.Entities;
4 |
5 | namespace LinCms.Cms.Logs;
6 |
7 | public interface ISerilogService
8 | {
9 | Task GetLogDashboard();
10 | Task> GetListAsync(SerilogSearchDto searchDto);
11 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/LogDashboard.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Cms.Logs;
2 |
3 | public class LogDashboard
4 | {
5 | public long TodayCount { get; set; }
6 | public long HourCount { get; set; }
7 | public long AllCount { get; set; }
8 | public long UniqueCount { get; set; }
9 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/LogDto.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Cms.Logs;
2 |
3 | public class LogDto
4 | {
5 | ///
6 | /// 访问哪个权限
7 | ///
8 | public string Authority { get; set; }
9 |
10 | ///
11 | /// 日志信息
12 | ///
13 | public string Message { get; set; }
14 |
15 | ///
16 | /// 请求方法
17 | ///
18 | public string Method { get; set; }
19 |
20 | ///
21 | /// 请求路径
22 | ///
23 | public string Path { get; set; }
24 |
25 | ///
26 | /// 请求的http返回码
27 | ///
28 | public int? StatusCode { get; set; }
29 |
30 | ///
31 | /// 用户id
32 | ///
33 | public long UserId { get; set; }
34 |
35 | ///
36 | /// 用户当时的昵称
37 | ///
38 | public string Username { get; set; }
39 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/LogSearchDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Data;
3 |
4 | namespace LinCms.Cms.Logs;
5 |
6 | public class LogSearchDto : PageDto
7 | {
8 | public string Keyword { get; set; }
9 | ///
10 | /// 用户昵称
11 | ///
12 | public string Name { get; set; }
13 | ///
14 | /// 起始时间
15 | ///
16 | public DateTime? Start { get; set; }
17 | ///
18 | /// 结束时间
19 | ///
20 | public DateTime? End { get; set; }
21 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/SerilogSearchDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Data;
3 |
4 | namespace LinCms.Cms.Logs;
5 |
6 | public class SerilogSearchDto : PageDto
7 | {
8 | public string Keyword { get; set; }
9 | public int? LogLevel { get; set; }
10 | ///
11 | /// 起始时间
12 | ///
13 | public DateTime? Start { get; set; }
14 | ///
15 | /// 结束时间
16 | ///
17 | public DateTime? End { get; set; }
18 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Logs/VisitLogUserDto.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Cms.Logs;
2 |
3 | public class VisitLogUserDto
4 | {
5 | ///
6 | /// 总访问量
7 | ///
8 | public long TotalVisitsCount { get; set; }
9 | ///
10 | /// 总用户数
11 | ///
12 | public long TotalUserCount { get; set; }
13 | ///
14 | /// 新增访问量 (月)
15 | ///
16 | public long MonthVisitsCount { get; set; }
17 |
18 | ///
19 | /// 新增用户数(月)
20 | ///
21 | public long MonthUserCount { get; set; }
22 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Permissions/DispatchPermissionsDto.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.DataAnnotations;
3 |
4 | namespace LinCms.Cms.Permissions;
5 |
6 | public class DispatchPermissionsDto : IValidatableObject
7 | {
8 | public long GroupId { get; set; }
9 | public List PermissionIds { get; set; }
10 | public IEnumerable Validate(ValidationContext validationContext)
11 | {
12 | if (GroupId <= 0)
13 | {
14 | yield return new ValidationResult("分组id必须大于0", new List() { "GroupId" });
15 | }
16 | if (PermissionIds.Count == 0)
17 | {
18 | yield return new ValidationResult("请输入PermissionIds字段", new List() { "Permission" });
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Permissions/IPermissionService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using LinCms.Data;
4 | using LinCms.Entities;
5 |
6 | namespace LinCms.Cms.Permissions;
7 |
8 | public interface IPermissionService
9 | {
10 | Task> GetPermissionTreeNodes();
11 | Task CheckPermissionAsync(string permission);
12 | Task DeletePermissionsAsync(RemovePermissionDto permissionDto);
13 |
14 | Task DispatchPermissions(DispatchPermissionsDto permissionDto, List permissionDefinition);
15 |
16 | Task> GetPermissionByGroupIds(List groupIds);
17 |
18 | List> StructuringPermissions(List permissions);
19 |
20 | Task UpdateAsync(int id,PermissioCreateUpdateDto createUpdateDto);
21 | Task CreateAsync(PermissioCreateUpdateDto createUpdateDto);
22 |
23 | Task DeleteAsync(int id);
24 |
25 | Task GetAsync(string permissionName);
26 |
27 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Permissions/PermissioCreateUpdateDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Entities;
2 |
3 | namespace LinCms.Cms.Permissions;
4 |
5 | public class PermissioCreateUpdateDto
6 | {
7 |
8 | public PermissionType PermissionType { get; set; }
9 |
10 | ///
11 | /// 父级Id
12 | ///
13 | public long ParentId { get; set; }
14 |
15 | ///
16 | /// 所属权限、权限名称,例如:访问首页
17 | ///
18 | public string Name { get; set; }
19 |
20 | ///
21 | /// 后台路由
22 | ///
23 | public string Router { get; set; }
24 |
25 | ///
26 | /// 排序
27 | ///
28 | public int SortCode { get; set; }
29 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Permissions/PermissionDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Entities;
5 |
6 | namespace LinCms.Cms.Permissions;
7 |
8 | public class PermissionDto : EntityDto
9 | {
10 | ///
11 | /// 父级Id
12 | ///
13 | public long ParentId { get; set; }
14 | public string Name { get; set; }
15 |
16 | public PermissionType PermissionType { get; set; }
17 |
18 | public string Router { get; set; }
19 |
20 | }
21 |
22 | public class PermissionTreeNode : TreeNode
23 | {
24 | public int SortCode { get; set; }
25 | public string Router { get; set; }
26 | public PermissionType PermissionType { get; set; }
27 | public DateTime? CreateTime { get; set; }
28 | public List Children { get; set; }
29 |
30 | public PermissionTreeNode()
31 | {
32 | Children = new List();
33 | }
34 |
35 | }
36 |
37 | public class TreeNode
38 | {
39 | public long Id { get; set; }
40 | public long ParentId { get; set; }
41 | public string Name { get; set; }
42 | public List Children { get; set; }
43 |
44 | public TreeNode()
45 | {
46 | Children = new List();
47 | }
48 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Permissions/RemovePermissionDto.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.DataAnnotations;
3 |
4 | namespace LinCms.Cms.Permissions;
5 |
6 | public class RemovePermissionDto : IValidatableObject
7 | {
8 | public long GroupId { get; set; }
9 | public List PermissionIds { get; set; }
10 | public IEnumerable Validate(ValidationContext validationContext)
11 | {
12 | if (GroupId <= 0)
13 | {
14 | yield return new ValidationResult("分组id必须大于0", new List() { "GroupId" });
15 | }
16 | if (PermissionIds.Count == 0)
17 | {
18 | yield return new ValidationResult("请输入Permission字段", new List() { "Permission" });
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Settings/CreateUpdateSettingDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Settings;
4 |
5 | public class CreateUpdateSettingDto
6 | {
7 | ///
8 | /// 键
9 | ///
10 | [StringLength(128)]
11 | public string Name { get; set; }
12 |
13 | ///
14 | /// 值
15 | ///
16 | [StringLength(2048)]
17 | public string Value { get; set; }
18 |
19 | ///
20 | /// 提供者键
21 | ///
22 | [StringLength(64)]
23 | public string ProviderName { get; set; }
24 |
25 | ///
26 | /// 提供者值
27 | ///
28 | [StringLength(64)]
29 | public string ProviderKey { get; set; }
30 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Settings/ISettingService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using IGeekFan.FreeKit.Extras.Dto;
5 | using LinCms.Data;
6 |
7 | namespace LinCms.Cms.Settings;
8 |
9 | ///
10 | /// 通用配置项
11 | ///
12 | public interface ISettingService
13 | {
14 | Task> GetPagedListAsync(PageDto pageDto);
15 |
16 | Task GetAsync(Guid id);
17 |
18 | Task Delete(string name, string providerName, string providerKey);
19 |
20 | Task> GetListAsync(string providerName, string providerKey);
21 |
22 | Task GetOrNullAsync(string name, string providerName, string providerKey);
23 |
24 | ///
25 | /// 用户设置自己的一些配置
26 | ///
27 | ///
28 | ///
29 | Task SetAsync(CreateUpdateSettingDto createSetting);
30 |
31 | Task CreateAsync(CreateUpdateSettingDto createSettingDto);
32 |
33 | Task UpdateAsync(Guid id, CreateUpdateSettingDto updateSettingDto);
34 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Settings/SettingDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Cms.Settings;
5 |
6 | public class SettingDto : EntityDto
7 | {
8 | ///
9 | /// 键
10 | ///
11 | public string Name { get; set; }
12 | ///
13 | /// 值
14 | ///
15 | public string Value { get; set; }
16 | ///
17 | /// 提供者键
18 | ///
19 | public string ProviderName { get; set; }
20 | ///
21 | /// 提供者值
22 | ///
23 | public string ProviderKey { get; set; }
24 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/ChangePasswordDto.cs:
--------------------------------------------------------------------------------
1 | using LinCms.Cms.Admins;
2 |
3 | namespace LinCms.Cms.Users;
4 |
5 | public class ChangePasswordDto : ResetPasswordDto
6 | {
7 |
8 | // [Required(ErrorMessage = "原密码不可为空")]
9 | public string OldPassword { get; set; }
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/IOAuth2Service.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Claims;
2 | using System.Threading.Tasks;
3 | using LinCms.Data;
4 |
5 | namespace LinCms.Cms.Users;
6 |
7 | ///
8 | /// OAuath2.0登录绑定授权
9 | ///
10 | public interface IOAuth2Service
11 | {
12 | ///
13 | /// 第三方登录后,自动注册用户信息
14 | ///
15 | ///
16 | ///
17 | ///
18 | Task SaveUserAsync(ClaimsPrincipal principal, string openId);
19 |
20 | ///
21 | /// 用户账号绑定第三方账号
22 | ///
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | Task BindAsync(ClaimsPrincipal principal, string identityType, string openId, long userId);
29 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/OAuthService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Claims;
3 | using System.Threading.Tasks;
4 | using IGeekFan.FreeKit.Extras.FreeSql;
5 | using LinCms.Data;
6 | using LinCms.Entities;
7 |
8 | namespace LinCms.Cms.Users;
9 |
10 | public abstract class OAuthService : IOAuth2Service
11 | {
12 | private readonly IAuditBaseRepository _userIdentityRepository;
13 |
14 | public OAuthService(IAuditBaseRepository userIdentityRepository)
15 | {
16 | _userIdentityRepository = userIdentityRepository;
17 | }
18 | private async Task BindAsync(string identityType, string name, string openId, long userId)
19 | {
20 | LinUserIdentity linUserIdentity = await _userIdentityRepository.Where(r => r.IdentityType == identityType && r.Credential == openId).FirstAsync();
21 | if (linUserIdentity == null)
22 | {
23 | var userIdentity = new LinUserIdentity(identityType, name, openId, DateTime.Now)
24 | {
25 | CreateUserId = userId
26 | };
27 | await _userIdentityRepository.InsertAsync(userIdentity);
28 | return UnifyResponseDto.Success("绑定成功");
29 | }
30 | else
31 | {
32 | return UnifyResponseDto.Error("绑定失败,该用户已绑定其他账号");
33 | }
34 | }
35 |
36 | public abstract Task SaveUserAsync(ClaimsPrincipal principal, string openId);
37 |
38 | public virtual async Task BindAsync(ClaimsPrincipal principal, string identityType, string openId, long userId)
39 | {
40 | string nickname = principal.FindFirst(ClaimTypes.Name)?.Value;
41 | return await BindAsync(identityType, nickname, openId, userId);
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/OpenUserDto.cs:
--------------------------------------------------------------------------------
1 | using IGeekFan.FreeKit.Extras.AuditEntity;
2 |
3 | namespace LinCms.Cms.Users;
4 |
5 | public class OpenUserDto : EntityDto
6 | {
7 | public OpenUserDto(string nickname)
8 | {
9 | Nickname = nickname;
10 | }
11 |
12 | public OpenUserDto()
13 | {
14 | }
15 |
16 | public string Introduction { get; set; }
17 | public string Username { get; set; }
18 | public string Nickname { get; set; }
19 | public string Avatar { get; set; }
20 | public string BlogAddress { get; set; }
21 | public string JobTitle { get; set; }
22 | public string Company { get; set; }
23 |
24 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UpdateAvatarDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Users;
4 |
5 | public class UpdateAvatarDto
6 | {
7 | [Required(ErrorMessage = "请输入头像url")]
8 | public string Avatar { get; set; }
9 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UpdateNickNameDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Users;
4 |
5 | public class UpdateNicknameDto
6 | {
7 | [Required(ErrorMessage = "请输入昵称")]
8 | [StringLength(24, ErrorMessage = "昵称应在24个字符内")]
9 | public string Nickname { get; set; }
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UpdateProfileDto.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.DataAnnotations;
2 |
3 | namespace LinCms.Cms.Users;
4 |
5 | public class UpdateProfileDto
6 | {
7 | [Required(ErrorMessage = "请输入昵称")]
8 | [StringLength(24, ErrorMessage = "昵称应在24个字符内")]
9 |
10 | public string Nickname { get; set; }
11 | [StringLength(100, ErrorMessage = "个人介绍应在100个字符内")]
12 |
13 | public string Introduction { get; set; }
14 |
15 | [StringLength(100, ErrorMessage = "博客应在100个字符内")]
16 | public string BlogAddress { get; set; }
17 |
18 | ///
19 | /// 职位
20 | ///
21 | [StringLength(50, ErrorMessage = "职位应在50个字符内")]
22 | public string JobTitle { get; set; }
23 |
24 | ///
25 | /// 公司
26 | ///
27 | [StringLength(50, ErrorMessage = "公司应在50个字符内")]
28 | public string Company { get; set; }
29 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UserDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Cms.Groups;
5 |
6 | namespace LinCms.Cms.Users;
7 |
8 | public class UserDto : EntityDto
9 | {
10 | public string Username { get; set; }
11 | public string Nickname { get; set; }
12 | public string Avatar { get; set; }
13 | public string Email { get; set; }
14 | public int Admin { get; set; } = 1;
15 | public int Active { get; set; }
16 | public List Groups { get; set; }
17 | public DateTime CreateTime { get; set; }
18 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UserIdentityDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Cms.Users;
5 |
6 | public class UserIdentityDto : EntityDto
7 | {
8 | public string IdentityType { get; set; }
9 |
10 | public string Identifier { get; set; }
11 |
12 | public string ExtraProperties { get; set; }
13 |
14 | public DateTime CreateTime { get; set; }
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UserInformation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using LinCms.Cms.Groups;
5 | using LinCms.Data.Enums;
6 |
7 | namespace LinCms.Cms.Users;
8 |
9 | public class UserInformation : EntityDto
10 | {
11 | ///
12 | /// 昵称
13 | ///
14 | public string Nickname { get; set; }
15 | ///
16 | /// 用户默认生成图像,为null、头像url
17 | ///
18 | public string Avatar { get; set; }
19 | ///
20 | /// 电子邮箱
21 | ///
22 | public string Email { get; set; }
23 | ///
24 | /// 是否为超级管理员
25 | ///
26 | public bool Admin { get; set; } = false;
27 | ///
28 | /// 当前用户是否为激活状态,非激活状态默认失去用户权限 ; 1 -> 激活 | 2 -> 非激活
29 | ///
30 | public UserStatus Active { get; set; }
31 | ///
32 | /// 用户所属的权限组id
33 | ///
34 | public List Groups { get; set; }
35 |
36 | public string Introduction { get; set; }
37 | public string BlogAddress { get; set; }
38 | public string Username { get; set; }
39 | public DateTime UpdateTime { get; set; }
40 | public DateTime CreateTime { get; set; }
41 |
42 | public List> Permissions { get; set; }
43 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/Cms/Users/UserNoviceDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Cms.Users;
5 |
6 | public class UserNoviceDto : EntityDto
7 | {
8 | public string Introduction { get; set; }
9 | public string Username { get; set; }
10 | public string Nickname { get; set; }
11 | public string Avatar { get; set; }
12 | public DateTime CreateTime { get; set; }
13 | public DateTime LastLoginTime { get; set; }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/IApplicationService.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms;
2 |
3 | public interface IApplicationService
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/ICrudAppService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using IGeekFan.FreeKit.Extras.Dto;
5 |
6 | namespace LinCms;
7 |
8 | public interface ICrudAppService
9 | where TGetOutputDto : IEntityDto
10 | where TKey : IEquatable
11 | where TGetListOutputDto : class, IEntityDto
12 | {
13 | Task> GetListAsync(TGetListInput input);
14 |
15 | Task GetAsync(TKey id);
16 |
17 | Task CreateAsync(TCreateInput createInput);
18 |
19 | Task UpdateAsync(TKey id, TUpdateInput updateInput);
20 |
21 | Task DeleteAsync(TKey id);
22 | }
--------------------------------------------------------------------------------
/src/LinCms.Application.Contracts/LinCms.Application.Contracts.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | LinCms.Application.Contracts
6 | LinCms
7 |
8 |
9 |
10 | LinCms.Application.Contracts.xml
11 | bin\Debug
12 | 1701;1702;1591
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Never
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/LinCms.Application/Base/BaseItems/BaseItemProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Base;
3 |
4 | namespace LinCms.Base.BaseItems;
5 |
6 | public class BaseItemProfile : Profile
7 | {
8 | public BaseItemProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Base/BaseTypes/BaseTypeProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Base;
3 |
4 | namespace LinCms.Base.BaseTypes;
5 |
6 | public class BaseTypeProfile : Profile
7 | {
8 | public BaseTypeProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Articles/ArticleDraftService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.FreeSql;
4 | using LinCms.Blog.ArticleDrafts;
5 | using LinCms.Entities.Blog;
6 | using LinCms.Exceptions;
7 | using LinCms.Security;
8 |
9 | namespace LinCms.Blog.Articles;
10 | ///
11 | /// 文章草稿箱
12 | ///
13 | public class ArticleDraftService : ApplicationService, IArticleDraftService
14 | {
15 | private readonly IAuditBaseRepository _articleDraftRepository;
16 | public ArticleDraftService(IAuditBaseRepository articleDraftRepository)
17 | {
18 | _articleDraftRepository = articleDraftRepository;
19 | }
20 |
21 | public async Task GetAsync(Guid id)
22 | {
23 | ArticleDraft articleDraft = await _articleDraftRepository.Where(r => r.Id == id && r.CreateUserId == CurrentUser.FindUserId()).ToOneAsync();
24 | return Mapper.Map(articleDraft);
25 | }
26 |
27 | public async Task UpdateAsync(Guid id, UpdateArticleDraftDto updateArticleDto)
28 | {
29 | ArticleDraft articleDraft = await _articleDraftRepository.Select.Where(r => r.Id == id).ToOneAsync();
30 | if (articleDraft != null && articleDraft.CreateUserId != CurrentUser.FindUserId())
31 | {
32 | throw new LinCmsException("您无权修改他人的随笔");
33 | }
34 | if (articleDraft == null)
35 | {
36 | articleDraft = new ArticleDraft { Id = id, CreateUserId = CurrentUser.FindUserId() ?? 0, CreateTime = DateTime.Now };
37 | }
38 | Mapper.Map(updateArticleDto, articleDraft);
39 | await _articleDraftRepository.InsertOrUpdateAsync(articleDraft);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Articles/ArticleProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Blog.ArticleDrafts;
3 | using LinCms.Entities.Blog;
4 |
5 | namespace LinCms.Blog.Articles;
6 |
7 | public class ArticleProfile : Profile
8 | {
9 | public ArticleProfile()
10 | {
11 | CreateMap();
12 | CreateMap();
13 | CreateMap();
14 |
15 | CreateMap();
16 | CreateMap();
17 |
18 | CreateMap();
19 | }
20 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/AuthorCenter/AuthorCenterService.cs:
--------------------------------------------------------------------------------
1 | using IGeekFan.FreeKit.Extras.FreeSql;
2 | using LinCms.Entities.Blog;
3 | using LinCms.Security;
4 | using System.Threading.Tasks;
5 |
6 | namespace LinCms.Blog.AuthorCenter
7 | {
8 | ///
9 | /// 创建者中心统计
10 | ///
11 | public class AuthorCenterService(IAuditBaseRepository articleRepository,
12 | IAuditBaseRepository userLikeRepository)
13 | : ApplicationService, IAuthorCenterService
14 | {
15 | public async Task GetArtcileCardAsync()
16 | {
17 | long? userid = CurrentUser.FindUserId();
18 | var allArticle = await articleRepository.Select.Where(r => r.CreateUserId == userid.Value).CountAsync();
19 | var allArticleView = (long) await articleRepository.Select.Where(r => r.CreateUserId == userid.Value)
20 | .SumAsync(r => r.ViewHits);
21 | var allArticleStar = await userLikeRepository.Select.Where(r =>
22 | r.CreateUserId == userid.Value && r.SubjectType == UserLikeSubjectType.UserLikeArticle).CountAsync();
23 | var allArticleComment = (long) await articleRepository.Select.Where(r => r.CreateUserId == userid.Value)
24 | .SumAsync(r => r.CommentQuantity);
25 | var allArticleCollect = (long) await articleRepository.Select.Where(r => r.CreateUserId == userid.Value)
26 | .SumAsync(r => r.CollectQuantity);
27 |
28 | return new ArticleCardDto()
29 | {
30 | AllArticle = allArticle,
31 | AllArticleView = allArticleView,
32 | AllArticleStar = allArticleStar,
33 | AllArticleComment = allArticleComment,
34 | AllArticleCollect = allArticleCollect
35 | };
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Channels/ChannelProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.Channels;
5 |
6 | public class ChannelProfile : Profile
7 | {
8 | public ChannelProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | CreateMap();
13 | }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Classifies/ClassifyProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Blog.Classifys;
3 | using LinCms.Entities.Blog;
4 |
5 | namespace LinCms.Blog.Classifies;
6 |
7 | public class ClassifyProfile : Profile
8 | {
9 | public ClassifyProfile()
10 | {
11 | CreateMap();
12 | CreateMap();
13 | }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Collections/CollectionProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Blog.Collections;
3 | using LinCms.Entities.Blog;
4 |
5 | namespace LinCms.Blog.Comments;
6 |
7 | public class CollectionProfile:Profile
8 | {
9 | public CollectionProfile()
10 | {
11 | CreateMap();
12 | CreateMap();
13 | CreateMap();
14 | }
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Comments/CommentProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.Comments;
5 |
6 | public class CommentProfile : Profile
7 | {
8 | public CommentProfile()
9 | {
10 | CreateMap();
11 | CreateMap().ForMember(d => d.TopComment, opts => opts.Ignore());
12 | }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Notifications/EventService.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Blog.Notifications;
2 |
3 | public class EventService
4 | {
5 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Notifications/NotificationProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.Notifications;
5 |
6 | public class NotificationProfile : Profile
7 | {
8 | public NotificationProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | CreateMap();
13 | CreateMap();
14 | }
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Tags/TagProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.Tags;
5 |
6 | public class TagProfile : Profile
7 | {
8 | public TagProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | CreateMap();
13 | }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/Tags/UserTagService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.FreeSql;
4 | using LinCms.Entities.Blog;
5 | using LinCms.Exceptions;
6 | using LinCms.Security;
7 |
8 | namespace LinCms.Blog.Tags;
9 |
10 | public class UserTagService(ITagService tagService, IAuditBaseRepository tagRepository,
11 | IAuditBaseRepository userTagRepository)
12 | : ApplicationService, IUserTagService
13 | {
14 | [Transactional]
15 | public async Task CreateUserTagAsync(Guid tagId)
16 | {
17 | Tag tag = await tagRepository.Select.Where(r => r.Id == tagId).ToOneAsync();
18 | if (tag == null)
19 | {
20 | throw new LinCmsException("该标签不存在");
21 | }
22 |
23 | if (!tag.Status)
24 | {
25 | throw new LinCmsException("该标签已被拉黑");
26 | }
27 |
28 | bool any = await userTagRepository.Select.AnyAsync(r => r.CreateUserId == CurrentUser.FindUserId() && r.TagId == tagId);
29 | if (any)
30 | {
31 | throw new LinCmsException("您已关注该标签");
32 | }
33 |
34 | UserTag userTag = new() { TagId = tagId };
35 | await userTagRepository.InsertAsync(userTag);
36 | await tagService.UpdateSubscribersCountAsync(tagId, 1);
37 | }
38 |
39 | [Transactional]
40 | public async Task DeleteUserTagAsync(Guid tagId)
41 | {
42 | bool any = await userTagRepository.Select.AnyAsync(r => r.CreateUserId == CurrentUser.FindUserId() && r.TagId == tagId);
43 | if (!any)
44 | {
45 | throw new LinCmsException("已取消关注");
46 | }
47 | await userTagRepository.DeleteAsync(r => r.TagId == tagId && r.CreateUserId == CurrentUser.FindUserId());
48 | await tagService.UpdateSubscribersCountAsync(tagId, -1);
49 | }
50 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/UserLikes/UserLikeProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.UserLikes;
5 |
6 | public class UserLikeProfile : Profile
7 | {
8 | public UserLikeProfile()
9 | {
10 | CreateMap();
11 | }
12 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Blog/UserSubscribes/UserSubscribeProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Blog;
3 |
4 | namespace LinCms.Blog.UserSubscribes;
5 |
6 | public class UserSubscribeProfile : Profile
7 | {
8 | public UserSubscribeProfile()
9 | {
10 | CreateMap();
11 | }
12 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Account/AccountContracts.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Cms.Account;
2 |
3 | public class AccountContracts
4 | {
5 | ///
6 | /// 注册返回的uuid值
7 | ///
8 | public static string SendEmailCode_EmailCode = "AccountService.SendEmailCode.EmailCode.{0}";
9 |
10 | ///
11 | /// 注册时缓存的邮件验证码
12 | ///
13 | public static string SendEmailCode_VerificationCode = "AccountService.SendEmailCode.VerificationCode.{0}";
14 |
15 | ///
16 | /// 重置密码时邮件验证码
17 | ///
18 | public static string SendPasswordResetCode_VerificationCode =
19 | "AccountService.SendPasswordResetCode.VerificationCode.{0}";
20 |
21 | ///
22 | /// 重置密码验证码可使用次数
23 | ///
24 | public static string SendPasswordResetCode_VerificationCode_Count =
25 | "AccountService.SendPasswordResetCode.VerificationCode.{0}.Count";
26 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Groups/GroupProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities;
3 |
4 | namespace LinCms.Cms.Groups;
5 |
6 | public class GroupProfile : Profile
7 | {
8 | public GroupProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | CreateMap();
13 | }
14 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Permissions/PermissionProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities;
3 |
4 | namespace LinCms.Cms.Permissions;
5 |
6 | public class PermissionProfile : Profile
7 | {
8 | public PermissionProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | CreateMap();
13 | CreateMap();
14 | }
15 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Permissions/TreeBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace LinCms.Cms.Permissions;
5 |
6 | public record TreeBuilder
7 | {
8 | public List BuildPermissionTree(List nodes)
9 | {
10 | var nodeDict = nodes.ToDictionary(n => n.Id);
11 | List roots = new List();
12 |
13 | foreach (var node in nodes)
14 | {
15 | if (node.ParentId == 0) // 假定ParentId为0表示根节点
16 | {
17 | roots.Add(node);
18 | }
19 | else
20 | {
21 | if (nodeDict.TryGetValue(node.ParentId, out PermissionTreeNode parentNode))
22 | {
23 | parentNode.Children.Add(node);
24 | }
25 | }
26 | }
27 | return roots; // 返回森林中所有根节点的列表
28 | }
29 |
30 | public List BuildTree(List nodes)
31 | {
32 | var nodeDict = nodes.ToDictionary(n => n.Id);
33 | List roots = new List();
34 |
35 | foreach (var node in nodes)
36 | {
37 | if (node.ParentId == 0) // 假定ParentId为0表示根节点
38 | {
39 | roots.Add(node);
40 | }
41 | else
42 | {
43 | if (nodeDict.TryGetValue(node.ParentId, out TreeNode parentNode))
44 | {
45 | parentNode.Children.Add(node);
46 | }
47 | }
48 | }
49 | return roots; // 返回森林中所有根节点的列表
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Settings/SettingProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities.Settings;
3 |
4 | namespace LinCms.Cms.Settings;
5 |
6 | public class SettingProfile : Profile
7 | {
8 | public SettingProfile()
9 | {
10 | CreateMap();
11 | CreateMap();
12 | }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Users/UserIdentityProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Entities;
3 |
4 | namespace LinCms.Cms.Users;
5 |
6 | public class UserIdentityProfile : Profile
7 | {
8 | public UserIdentityProfile()
9 | {
10 | CreateMap();
11 |
12 | }
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/Cms/Users/UserProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using LinCms.Cms.Account;
3 | using LinCms.Cms.Admins;
4 | using LinCms.Entities;
5 |
6 | namespace LinCms.Cms.Users;
7 |
8 | public class UserProfile : Profile
9 | {
10 | public UserProfile()
11 | {
12 | CreateMap();
13 | CreateMap();
14 | CreateMap();
15 | CreateMap();
16 | CreateMap();
17 | CreateMap();
18 | CreateMap();
19 | }
20 | }
--------------------------------------------------------------------------------
/src/LinCms.Application/LinCms.Application.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | LinCms.Application
6 | LinCms
7 | True
8 | True
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Aop/Attributes/CacheableAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Aop.Attributes;
4 |
5 | [AttributeUsage(AttributeTargets.Method)]
6 | public class CacheableAttribute : Attribute
7 | {
8 | public CacheableAttribute()
9 | {
10 | }
11 |
12 | public CacheableAttribute(string cacheKey)
13 | {
14 | CacheKey = cacheKey;
15 | }
16 |
17 | public string CacheKey { get; set; }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Aop/Attributes/DisableAuditingAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Aop.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)]
6 | public class DisableAuditingAttribute : Attribute
7 | {
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Aop/Attributes/IgnoreMemberAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Aop.Attributes
4 | {
5 | // source: https://github.com/jhewlett/ValueObject
6 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
7 | public class IgnoreMemberAttribute : Attribute
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Aop/Attributes/LoggerAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Aop.Attributes
4 | {
5 | [AttributeUsage(AttributeTargets.Method)]
6 | public class LoggerAttribute(string template) : Attribute
7 | {
8 | public string Template { get; } = template ?? throw new ArgumentNullException(nameof(template));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Common/EncryptUtil.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using System.Text;
3 |
4 | namespace LinCms.Common
5 | {
6 | public class EncryptUtil
7 | {
8 | ///
9 | /// 通过创建哈希字符串适用于任何 MD5 哈希函数 (在任何平台) 上创建 32 个字符的十六进制格式哈希字符串
10 | ///
11 | ///
12 | ///
13 | public static string Encrypt(string source)
14 | {
15 | using MD5 md5Hash = MD5.Create();
16 | byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source));
17 | StringBuilder sBuilder = new StringBuilder();
18 | foreach (byte t in data)
19 | {
20 | sBuilder.Append(t.ToString("x2"));
21 | }
22 |
23 | string hash = sBuilder.ToString();
24 | return hash.ToUpper();
25 | }
26 |
27 | ///
28 | /// 验证source加密码后是否生成mdPwd
29 | ///
30 | /// Md5生成的代码
31 | ///
32 | ///
33 | public static bool Verify(string mdPwd, string source)
34 | {
35 | return mdPwd == Encrypt(source).ToUpper();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Common/LinConsts.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Common
2 | {
3 | public static class LinConsts
4 | {
5 | public static class Group
6 | {
7 | public const int Admin = 1;
8 | public const int CmsAdmin = 2;
9 | public const int User = 3;
10 | }
11 |
12 | public static class Claims
13 | {
14 | public const string Bio = "urn:github:bio";
15 | public const string AvatarUrl = "urn:github:avatar_url";
16 | public const string HtmlUrl = "urn:github:html_url";
17 | public const string BlogAddress = "urn:github:blog";
18 | }
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Authorization/PermissionAuthorizationRequirement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Authorization.Infrastructure;
3 |
4 | namespace LinCms.Data.Authorization
5 | {
6 | public class ModuleAuthorizationRequirement : OperationAuthorizationRequirement
7 | {
8 | public ModuleAuthorizationRequirement(string module, string permission)
9 | {
10 | Module = module ?? throw new ArgumentNullException(nameof(module));
11 | Name = permission ?? throw new ArgumentNullException(nameof(permission));
12 | }
13 |
14 | public string Module { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Authorization/ValidJtiRequirement.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 |
3 | namespace LinCms.Data.Authorization
4 | {
5 | public class ValidJtiRequirement : IAuthorizationRequirement
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Enums/CapMessageQueueType.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Enums
2 | {
3 | public enum CapMessageQueueType
4 | {
5 | InMemoryQueue = 0,
6 | RabbitMQ = 1,
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Enums/CapStorageType.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Enums
2 | {
3 | public enum CapStorageType
4 | {
5 | ///
6 | /// 引用包 DotNetCore.CAP.InMemoryStorage
7 | ///
8 | InMemoryStorage = 0,
9 | ///
10 | /// 引用包 DotNetCore.CAP.MySql
11 | ///
12 | Mysql = 1,
13 | ///
14 | /// 引用包 DotNetCore.CAP.SqlServer
15 | ///
16 | SqlServer = 2
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Enums/Status.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Enums
2 | {
3 | public enum Status
4 | {
5 | ///
6 | /// 启用
7 | ///
8 | Enable = 1,
9 | ///
10 | /// 禁用
11 | ///
12 | Forbidden = 2
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Enums/TokenType.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Enums
2 | {
3 | /*
4 | * 令牌类型静态类
5 | */
6 | public class TokenType
7 | {
8 | ///
9 | /// access token
10 | ///
11 | public static string Access = "access";
12 | ///
13 | /// refresh token
14 | ///
15 | public static string Refresh = "refresh";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Enums/UserStatus.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Enums
2 | {
3 | /**
4 | * 当前用户是否为激活状态的枚举
5 | * ACTIVE 代表 激活状态
6 | * NOT_ACTIVE 代表 非激活状态
7 | */
8 | public enum UserStatus
9 | {
10 | ///
11 | /// 激活状态
12 | ///
13 | Active = 1,
14 | ///
15 | /// 非激活状态
16 | ///
17 | NotActive = 2
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Options/FileStorageOption.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Options
2 | {
3 | public class FileStorageOption
4 | {
5 | ///
6 | /// 上传文件总大小
7 | ///
8 | public long MaxFileSize { get; set; }
9 | ///
10 | /// 多文件上传时,支持的最大文件数量
11 | ///
12 | public int NumLimit { get; set; }
13 | ///
14 | /// 允许某些类型文件上传,文件格式以,隔开
15 | ///
16 | public string Include { get; set; }
17 | ///
18 | /// 禁止某些类型文件上传,文件格式以,隔开
19 | ///
20 | public string Exclude { get; set; }
21 |
22 | public string ServiceName { get; set; }
23 | public LocalFileOption LocalFile { get; set; }
24 | public QiniuOptions Qiniu { get; set; }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Options/LocalFileOption.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace LinCms.Data.Options
3 | {
4 | public class LocalFileOption
5 | {
6 | public string PrefixPath { get; set; }
7 | public string Host { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Options/QiniuOption.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Options
2 | {
3 | public class QiniuOptions
4 | {
5 | public string AK { get; set; }
6 | public string SK { get; set; }
7 | public string Bucket { get; set; }
8 | public string PrefixPath { get; set; }
9 | public string Host { get; set; }
10 | public bool UseHttps { get; set; }
11 | }
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/Options/SiteOption.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Data.Options
2 | {
3 | public class SiteOption
4 | {
5 | public string Domain { get; set; }
6 | public string VVLogDomain { get; set; }
7 | public string CMSDomain { get; set; }
8 | public string ApiDomain { get; set; }
9 | public string IdentityServer4Domain { get; set; }
10 | public string Email { get; set; }
11 | public string BlogUrl { get; set; }
12 | public string DocUrl { get; set; }
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/PagedAndSortedRequestDto.cs:
--------------------------------------------------------------------------------
1 |
2 |
3 | using System.ComponentModel.DataAnnotations;
4 |
5 | namespace LinCms.Data
6 | {
7 | public class PagedAndSortedRequestDto : PageDto, ISortedResultRequest
8 | {
9 | public string Sorting { get; set; }
10 | }
11 |
12 |
13 | ///
14 | /// 分页
15 | ///
16 | public class PageDto : IPageDto
17 | {
18 | ///
19 | /// 每页个数
20 | ///
21 | [Range(1, int.MaxValue, ErrorMessage = "每页个数最小为1")]
22 | public int Count { get; set; } = 15;
23 |
24 | ///
25 | /// 从0开始,0时取第1页,1时取第二页
26 | ///
27 | public int Page { get; set; }
28 |
29 | public string Sort { get; set; }
30 | }
31 |
32 | public interface IPageDto : ILimitedResultRequest
33 | {
34 | int Page { get; set; }
35 | }
36 |
37 | public interface ILimitedResultRequest
38 | {
39 | ///
40 | /// Maximum result count should be returned.
41 | /// This is generally used to limit result count on paging.
42 | ///
43 | int Count { get; set; }
44 | }
45 |
46 | ///
47 | /// This interface is defined to standardize to request a sorted result.
48 | ///
49 | public interface ISortedResultRequest
50 | {
51 | ///
52 | /// Sorting information.
53 | /// Should include sorting field and optionally a direction (ASC or DESC)
54 | /// Can contain more than one field separated by comma (,).
55 | ///
56 | ///
57 | /// Examples:
58 | /// "Name"
59 | /// "Name DESC"
60 | /// "Name ASC, Age DESC"
61 | ///
62 | string Sorting { get; set; }
63 | }
64 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Data/PermissionDefinition.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Data
4 | {
5 | public class PermissionDefinition(string permission, string module, string router)
6 | {
7 | public string Permission { get; set; } = permission ?? throw new ArgumentNullException(nameof(permission));
8 | public string Module { get; set; } = module ?? throw new ArgumentNullException(nameof(module));
9 | public string Router { get; set; } = router ?? throw new ArgumentNullException(nameof(router));
10 |
11 | public override string ToString()
12 | {
13 | return base.ToString() + $" Permission:{Permission}、Module:{Module}、Router:{Router}";
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Domain/Captcha/CaptchaBO.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LinCms.Domain.Captcha;
4 |
5 | public class CaptchaBO
6 | {
7 | public CaptchaBO()
8 | {
9 | }
10 |
11 | public CaptchaBO(string captcha, long expired)
12 | {
13 | Captcha = captcha ?? throw new ArgumentNullException(nameof(captcha));
14 | Expired = expired;
15 | }
16 |
17 | public string Captcha { get; set; }
18 | public long Expired { get; set; }
19 | }
20 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Domain/Captcha/CaptchaOption.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Domain.Captcha
2 | {
3 | ///
4 | /// 验证码配置
5 | ///
6 | public class CaptchaOption
7 | {
8 | ///
9 | /// 是否启用验证码
10 | ///
11 | public bool Enabled { get; set; }
12 |
13 | ///
14 | /// 盐值
15 | ///
16 | public string Salt { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Domain/Captcha/ICaptchaManager.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Domain.Captcha;
2 |
3 | public interface ICaptchaManager
4 | {
5 |
6 | ///
7 | /// 获取加密后验证码
8 | ///
9 | /// 原验证码
10 | /// 盐值
11 | /// 过期时间(单位秒)
12 | ///
13 | string GetTag(string captcha, string salt = "cryptography_salt", int seconds = 300);
14 |
15 | ///
16 | /// 获取时间戳(13位)
17 | ///
18 | ///
19 | ///
20 | long GetTimeStamp(int seconds=0);
21 | ///
22 | /// 随机字符的获取
23 | ///
24 | ///
25 | ///
26 | string GetRandomString(int num);
27 |
28 | ///
29 | /// 生成随机图片的base64编码字符串
30 | ///
31 | ///
32 | ///
33 | string GetRandomCaptchaBase64(string captcha);
34 |
35 | ///
36 | /// 解密出验证码
37 | ///
38 | ///
39 | ///
40 | ///
41 | CaptchaBO DecodeTag(string tag, string salt = "cryptography_salt");
42 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Domain/ITokenManager.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IGeekFan.FreeKit.Extras.Security;
3 | using LinCms.Entities;
4 |
5 | namespace LinCms.Domain;
6 |
7 | ///
8 | /// Token 处理类
9 | ///
10 | public interface ITokenManager
11 | {
12 | Task CreateTokenAsync(LinUser user);
13 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Domain/TokenManager.cs:
--------------------------------------------------------------------------------
1 | using DotNetCore.Security;
2 | using IGeekFan.FreeKit.Extras.Dependency;
3 | using IGeekFan.FreeKit.Extras.Security;
4 | using LinCms.Entities;
5 | using LinCms.IRepositories;
6 | using LinCms.Security;
7 | using Microsoft.Extensions.Logging;
8 | using System.Collections.Generic;
9 | using System.Security.Claims;
10 | using System.Threading.Tasks;
11 |
12 | namespace LinCms.Domain;
13 |
14 | public class TokenManager(IJwtService jsonWebTokenService, ILogger logger, IUserRepository userRepository)
15 | : ITokenManager, ITransientDependency
16 | {
17 | public async Task CreateTokenAsync(LinUser user)
18 | {
19 | List claims = new()
20 | {
21 | new Claim(FreeKitClaimTypes.NameIdentifier, user.Id.ToString()),
22 | new Claim(FreeKitClaimTypes.Email, user.Email ?? ""),
23 | new Claim(FreeKitClaimTypes.Name, user.Nickname ?? ""),
24 | new Claim(FreeKitClaimTypes.UserName, user.Username ?? ""),
25 | };
26 | user.LinGroups?.ForEach(r =>
27 | {
28 | claims.Add(new Claim(FreeKitClaimTypes.Role, r.Name));
29 | claims.Add(new Claim(LinCmsClaimTypes.GroupIds, r.Id.ToString()));
30 | });
31 |
32 | string token = jsonWebTokenService.Encode(claims);
33 |
34 | user.AddRefreshToken();
35 | await userRepository.UpdateAsync(user);
36 |
37 | return new UserAccessToken(token, user.RefreshToken, 24 * 60 * 60, "Bearer", 24 * 60 * 60 * 30);
38 | }
39 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Base/BaseItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Base
6 | {
7 | ///
8 | /// 数据字典-详情项
9 | ///
10 | [Table(Name = "base_item")]
11 | public class BaseItem : FullAuditEntity
12 | {
13 | public BaseItem()
14 | {
15 | }
16 |
17 | public BaseItem(string itemCode, string itemName, int? sortCode, bool status)
18 | {
19 | ItemCode = itemCode ?? throw new ArgumentNullException(nameof(itemCode));
20 | ItemName = itemName ?? throw new ArgumentNullException(nameof(itemName));
21 | SortCode = sortCode;
22 | Status = status;
23 | }
24 |
25 | public BaseItem(string itemCode, string itemName, int? sortCode, int baseTypeId, bool status) : this(itemCode, itemName, sortCode, status)
26 | {
27 | BaseTypeId = baseTypeId;
28 | }
29 |
30 | ///
31 | /// 数据字典-分类Id
32 | ///
33 | public long BaseTypeId { get; set; }
34 |
35 | ///
36 | /// 数据字典-编码
37 | ///
38 |
39 | [Column(StringLength = 50)]
40 | public string ItemCode { get; set; }
41 |
42 | ///
43 | /// 数据字典-名称
44 | ///
45 |
46 | [Column(StringLength = 50)]
47 | public string ItemName { get; set; }
48 |
49 | ///
50 | /// 排序码
51 | ///
52 |
53 | public int? SortCode { get; set; }
54 |
55 | ///
56 | /// 状态
57 | ///
58 | public bool Status { get; set; }
59 |
60 | public virtual BaseType BaseType { get; set; }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Base/BaseType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FreeSql.DataAnnotations;
4 | using IGeekFan.FreeKit.Extras.AuditEntity;
5 |
6 | namespace LinCms.Entities.Base
7 | {
8 | ///
9 | /// 数据字典-分类
10 | ///
11 | [Table(Name = "base_type")]
12 | public class BaseType : FullAuditEntity
13 | {
14 | public BaseType()
15 | {
16 | }
17 |
18 | public BaseType(string typeCode, string fullName, int? sortCode)
19 | {
20 | TypeCode = typeCode ?? throw new ArgumentNullException(nameof(typeCode));
21 | FullName = fullName ?? throw new ArgumentNullException(nameof(fullName));
22 | SortCode = sortCode;
23 | }
24 |
25 | ///
26 | /// 分类编码
27 | ///
28 | [Column(StringLength = 50)]
29 | public string TypeCode { get; set; }
30 |
31 | ///
32 | /// 分类名称
33 | ///
34 | [Column(StringLength = 50)]
35 | public string FullName { get; set; }
36 |
37 | ///
38 | /// 排序码
39 | ///
40 | public int? SortCode { get; set; }
41 |
42 | public virtual ICollection BaseItems { get; set; }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/BlackRecord.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities
6 | {
7 | ///
8 | /// 黑名单,实现登录Token的过期
9 | ///
10 | public class BlackRecord : Entity, ICreateAuditEntity
11 | {
12 | ///
13 | /// 用户Token
14 | ///
15 | [StringLength(-2)]
16 | public string Jti { get; set; }
17 |
18 | ///
19 | /// 登录名
20 | ///
21 | [StringLength(50)]
22 | public string UserName { get; set; }
23 |
24 | ///
25 | public long? CreateUserId { get; set; }
26 |
27 | ///
28 | public string CreateUserName { get; set; }
29 |
30 | ///
31 | public DateTime CreateTime { get; set; }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/ArticleCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog;
6 |
7 | ///
8 | /// 用户文章收藏
9 | ///
10 | [Table(Name = "blog_article_collection")]
11 | public class ArticleCollection : Entity, ICreateAuditEntity
12 | {
13 | public Guid ArticleId { get; set; }
14 | public Guid CollectionId { get; set; }
15 | public long? CreateUserId { get; set; }
16 | public string CreateUserName { get; set; }
17 | public DateTime CreateTime { get; set; }
18 |
19 | public Article Article { get; set; }
20 | public Collection Collection { get; set; }
21 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/ArticleDraft.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog
6 | {
7 | ///
8 | /// 随笔草稿箱
9 | ///
10 | [Table(Name = "blog_article_draft")]
11 | public class ArticleDraft : FullAuditEntity
12 | {
13 | public ArticleDraft()
14 | {
15 | }
16 |
17 | public ArticleDraft(Guid id, string content, string title, int editor)
18 | {
19 | Id = id;
20 | Content = content ?? throw new ArgumentNullException(nameof(content));
21 | Title = title ?? throw new ArgumentNullException(nameof(title));
22 | Editor = editor;
23 | }
24 |
25 | ///
26 | /// 正文
27 | ///
28 | [Column(StringLength = -2)]
29 | public string Content { get; set; }
30 |
31 | [Column(StringLength = 200)]
32 | public string Title { get; set; }
33 |
34 | ///
35 | ///1:MarkDown编辑器 2:富文本编辑器,
36 | ///
37 | public int Editor { get; set; } = 1;
38 |
39 | public virtual Article Article { get; set; }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/Channel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FreeSql.DataAnnotations;
4 | using IGeekFan.FreeKit.Extras.AuditEntity;
5 |
6 | namespace LinCms.Entities.Blog
7 | {
8 | ///
9 | /// 技术频道,官方分类。标签的分类。
10 | ///
11 | [Table(Name = "blog_channel")]
12 | public class Channel : FullAuditEntity
13 | {
14 | ///
15 | /// 封面图
16 | ///
17 | [Column(StringLength = 100)]
18 | public string Thumbnail { get; set; }
19 |
20 | ///
21 | /// 排序
22 | ///
23 | public int SortCode { get; set; }
24 |
25 | ///
26 | /// 技术频道名称
27 | ///
28 | [Column(StringLength = 50)]
29 | public string ChannelName { get; set; }
30 |
31 | ///
32 | /// 编码
33 | ///
34 | [Column(StringLength = 50)]
35 | public string ChannelCode { get; set; }
36 |
37 | ///
38 | /// 备注描述
39 | ///
40 | [Column(StringLength = 500)]
41 | public string Remark { get; set; }
42 |
43 | ///
44 | /// 是否有效
45 | ///
46 | public bool Status { get; set; }
47 |
48 | public virtual ICollection Tags { get; set; }
49 | public virtual List Articles { get; set; }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/ChannelTag.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog
6 | {
7 | ///
8 | /// 频道标签
9 | ///
10 | [Table(Name = "blog_channel_tag")]
11 | public class ChannelTag : FullAuditEntity
12 | {
13 |
14 | public ChannelTag()
15 | {
16 | }
17 |
18 | public ChannelTag(Guid tagId)
19 | {
20 | TagId = tagId;
21 | }
22 |
23 | public ChannelTag(Guid channelId, Guid tagId)
24 | {
25 | ChannelId = channelId;
26 | TagId = tagId;
27 | }
28 |
29 | ///
30 | /// 频道Id
31 | ///
32 | public Guid ChannelId { get; set; }
33 |
34 | ///
35 | /// 标签Id
36 | ///
37 | public Guid TagId { get; set; }
38 |
39 | [Navigate("ChannelId")]
40 | public virtual Channel Channel { get; set; }
41 | [Navigate("TagId")]
42 | public virtual Tag Tag { get; set; }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/Collection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 | using JetBrains.Annotations;
5 |
6 | namespace LinCms.Entities.Blog;
7 |
8 | ///
9 | /// 收藏集
10 | ///
11 | [Table(Name = "blog_collection")]
12 | public class Collection : FullAuditEntity
13 | {
14 | ///
15 | /// 名称
16 | ///
17 | [Column(StringLength = 50)]
18 | public string Name { get; set; }
19 |
20 | ///
21 | /// 描述
22 | ///
23 | [Column(StringLength = 200)]
24 | [CanBeNull]
25 | public string Remark { get; set; }
26 |
27 | ///
28 | /// 收藏数量
29 | ///
30 | public int Quantity { get; set; }
31 |
32 | ///
33 | /// 公开 当其他人关注此收藏集后不可再更改为隐私
34 | /// 隐私 仅自己可见此收藏集
35 | ///
36 | public PrivacyType PrivacyType { get; set; }
37 |
38 | public void UpdateQuantity(int quantity)
39 | {
40 | if (quantity < 0 && Quantity < -quantity) return;
41 | Quantity += quantity;
42 | }
43 | }
44 |
45 | public enum PrivacyType
46 | {
47 | ///
48 | /// 公开可见
49 | ///
50 | Public = 0,
51 |
52 | ///
53 | /// 仅自己可见
54 | ///
55 | VisibleOnlyMySelf = 1
56 | }
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/TagArticle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog
6 | {
7 | ///
8 | /// 随笔标签
9 | ///
10 | [Table(Name = "blog_tag_article")]
11 | public class TagArticle : Entity
12 | {
13 | public Guid TagId { get; set; }
14 |
15 | public Guid ArticleId { get; set; }
16 |
17 | public virtual Tag Tag { get; set; }
18 |
19 | public virtual Article Article { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/UserLike.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog
6 | {
7 | ///
8 | /// 用户点赞:点赞随笔、评论内容
9 | ///
10 | [Table(Name = "blog_user_like")]
11 | public class UserLike : Entity, ICreateAuditEntity
12 | {
13 | ///
14 | /// 点赞对象
15 | ///
16 | public Guid SubjectId { get; set; }
17 |
18 | ///
19 | /// 点赞类型 1 是随笔,2 是评论
20 | ///
21 | [Column(MapType = typeof(int))]
22 | public UserLikeSubjectType SubjectType { get; set; }
23 |
24 | public long? CreateUserId { get; set; }
25 |
26 | public DateTime CreateTime { get; set; }
27 |
28 | [Navigate("CreateUserId")]
29 | public virtual LinUser LinUser { get; set; }
30 |
31 | [Navigate("SubjectId")]
32 | public virtual Comment Comment { get; set; }
33 |
34 | [Navigate("SubjectId")]
35 | public virtual Article Article { get; set; }
36 | public string CreateUserName { get; set; }
37 | }
38 |
39 | public enum UserLikeSubjectType
40 | {
41 | ///
42 | /// 点赞随笔
43 | ///
44 | UserLikeArticle = 1,
45 | ///
46 | /// 点赞评论
47 | ///
48 | UserLikeComment = 2
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/UserSubscribe.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog
6 | {
7 | ///
8 | /// 用户关注用户
9 | ///
10 | [Table(Name = "blog_user_subscribe")]
11 | public class UserSubscribe : Entity, ICreateAuditEntity
12 | {
13 | ///
14 | /// 被关注的用户Id
15 | ///
16 | public long SubscribeUserId { get; set; }
17 |
18 | ///
19 | /// 关注的用户Id
20 | ///
21 | public long? CreateUserId { get; set; }
22 | public string CreateUserName { get; set; }
23 |
24 | public DateTime CreateTime { get; set; }
25 |
26 | [Navigate("CreateUserId")]
27 | public virtual LinUser LinUser { get; set; }
28 |
29 | [Navigate("SubscribeUserId")]
30 | public virtual LinUser SubscribeUser { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Blog/UserTag.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities.Blog
6 | {
7 | ///
8 | /// 用户关注的标签
9 | ///
10 | [Table(Name = "blog_user_tag")]
11 | public class UserTag : Entity, ICreateAuditEntity
12 | {
13 | public Guid TagId { get; set; }
14 |
15 | public long? CreateUserId { get; set; }
16 | public string CreateUserName { get; set; }
17 |
18 |
19 | public DateTime CreateTime { get; set; }
20 |
21 | [Navigate("CreateUserId")]
22 | public virtual LinUser LinUser { get; set; }
23 |
24 | [Navigate("TagId")]
25 | public virtual Tag Tag { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/LinFile.cs:
--------------------------------------------------------------------------------
1 | using FreeSql.DataAnnotations;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Entities
5 | {
6 | ///
7 | /// 文件
8 | ///
9 | [Table(Name = "lin_file")]
10 | public class LinFile : FullAuditEntity
11 | {
12 | ///
13 | /// 文件后缀
14 | ///
15 | [Column(StringLength = 50)]
16 | public string Extension { get; set; } = string.Empty;
17 |
18 | ///
19 | /// 图片md5值,防止上传重复图片
20 | ///
21 | [Column(StringLength = 40)]
22 | public string Md5 { get; set; } = string.Empty;
23 |
24 | ///
25 | /// 名称
26 | ///
27 | [Column(StringLength = 300)]
28 | public string Name { get; set; } = string.Empty;
29 |
30 | ///
31 | /// 路径
32 | ///
33 | [Column(StringLength = 500)]
34 | public string Path { get; set; } = string.Empty;
35 |
36 | ///
37 | /// 大小
38 | ///
39 | public long? Size { get; set; }
40 |
41 | ///
42 | /// 1 local,2 代表七牛云 3 其他表示其他地方
43 | ///
44 | public short? Type { get; set; }
45 |
46 | public const string LocalFileService = "LocalFileService";
47 | public const string QiniuService = "QiniuService";
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/LinGroup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FreeSql.DataAnnotations;
4 | using IGeekFan.FreeKit.Extras.AuditEntity;
5 |
6 | namespace LinCms.Entities
7 | {
8 | ///
9 | /// 分组
10 | ///
11 | [Table(Name = "lin_group")]
12 | public class LinGroup : FullAuditEntity
13 | {
14 | public LinGroup()
15 | {
16 | }
17 |
18 | public LinGroup(string name, string info, bool isStatic)
19 | {
20 | Name = name ?? throw new ArgumentNullException(nameof(name));
21 | Info = info ?? throw new ArgumentNullException(nameof(info));
22 | IsStatic = isStatic;
23 | }
24 |
25 | ///
26 | /// 权限组唯一标识字符
27 | ///
28 | [Column(StringLength = 60)]
29 | public string Name { get; set; }
30 |
31 | ///
32 | /// 权限组描述
33 | ///
34 | [Column(StringLength = 100)]
35 | public string Info { get; set; }
36 |
37 | ///
38 | /// 是否是静态分组,是静态时无法删除此分组
39 | ///
40 | public bool IsStatic { get; set; } = false;
41 |
42 | ///
43 | /// 排序码,升序
44 | ///
45 | public int SortCode { get; set; }
46 |
47 | [Navigate(ManyToMany = typeof(LinUserGroup))]
48 | public virtual ICollection LinUsers { get; set; }
49 |
50 | ///
51 | /// 超级管理员
52 | ///
53 | public const string Admin = "Admin";
54 | ///
55 | /// Cms管理员
56 | ///
57 | public const string CmsAdmin = "CmsAdmin";
58 |
59 | ///
60 | /// 普通用户
61 | ///
62 | public const string User = "User";
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/LinGroupPermission.cs:
--------------------------------------------------------------------------------
1 | using FreeSql.DataAnnotations;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Entities
5 | {
6 | ///
7 | /// 分组权限中间表
8 | ///
9 | [Table(Name = "lin_group_permission")]
10 | public class LinGroupPermission : Entity
11 | {
12 | public LinGroupPermission()
13 | {
14 | }
15 |
16 | public LinGroupPermission(long groupId, long permissionId)
17 | {
18 | GroupId = groupId;
19 | PermissionId = permissionId;
20 | }
21 |
22 | public LinGroupPermission(long permissionId)
23 | {
24 | PermissionId = permissionId;
25 | }
26 |
27 | ///
28 | /// 分组id
29 | ///
30 | public long GroupId { get; set; }
31 |
32 | ///
33 | /// 权限Id
34 | ///
35 | public long PermissionId { get; set; }
36 |
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/LinLog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities
6 | {
7 | ///
8 | /// 日志表
9 | ///
10 | [Table(Name = "lin_log")]
11 | public class LinLog : Entity
12 | {
13 | ///
14 | /// 访问哪个权限
15 | ///
16 | [Column(StringLength = 100)]
17 | public string Authority { get; set; }
18 |
19 | ///
20 | /// 日志信息
21 | ///
22 | [Column(StringLength = 500)]
23 | public string Message { get; set; }
24 |
25 | ///
26 | /// 请求方法
27 | ///
28 | [Column(StringLength = 20)]
29 | public string Method { get; set; }
30 |
31 | ///
32 | /// 请求路径
33 | ///
34 | [Column(StringLength = 100)]
35 | public string Path { get; set; }
36 |
37 | ///
38 | /// 请求的http返回码
39 | ///
40 | public int? StatusCode { get; set; }
41 |
42 | ///
43 | /// 用户id
44 | ///
45 | public long? UserId { get; set; }
46 |
47 | ///
48 | /// 用户当时的昵称
49 | ///
50 | [Column(StringLength = 24)]
51 | public string Username { get; set; }
52 |
53 | public DateTime CreateTime { get; set; }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/LinPermission.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Entities
6 | {
7 | ///
8 | /// 权限表
9 | ///
10 | [Table(Name = "lin_permission")]
11 | public class LinPermission : FullAuditEntity
12 | {
13 | public LinPermission()
14 | {
15 | }
16 |
17 | public LinPermission(string name, PermissionType permissionType, string router)
18 | {
19 | Name = name;
20 | PermissionType = permissionType;
21 | Router = router;
22 | }
23 |
24 | public PermissionType PermissionType { get; set; }
25 |
26 | ///
27 | /// 父级Id
28 | ///
29 | public long ParentId { get; set; }
30 |
31 | ///
32 | /// 所属权限、权限名称,例如:访问首页
33 | ///
34 | [Column(StringLength = 60)]
35 | public string Name { get; set; }
36 |
37 | ///
38 | /// 后台路由
39 | ///
40 | [Column(StringLength = 200)]
41 | public string Router { get; set; }
42 |
43 | ///
44 | /// 排序
45 | ///
46 | public int SortCode { get; set; }
47 |
48 | }
49 |
50 | public enum PermissionType
51 | {
52 | Folder = 0,
53 | Permission = 1
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/LinUserGroup.cs:
--------------------------------------------------------------------------------
1 | using FreeSql.DataAnnotations;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Entities
5 | {
6 | ///
7 | /// 用户分组中间表
8 | ///
9 | [Table(Name = "lin_user_group")]
10 | public class LinUserGroup : Entity
11 | {
12 | public LinUserGroup()
13 | {
14 | }
15 | public LinUserGroup(long userId, long groupId)
16 | {
17 | UserId = userId;
18 | GroupId = groupId;
19 | }
20 |
21 | public long UserId { get; set; }
22 |
23 | public long GroupId { get; set; }
24 |
25 | [Navigate("UserId")]
26 | public LinUser LinUser { get; set; }
27 |
28 | [Navigate("GroupId")]
29 | public LinGroup LinGroup { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/SerilogDO.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql.DataAnnotations;
3 |
4 | namespace LinCms.Entities
5 | {
6 | ///
7 | /// Serilog数据库存储
8 | ///
9 | [Table(DisableSyncStructure = true, Name = "app_serilog")]
10 | public class SerilogDO
11 | {
12 | public long Id { get; set; }
13 | public string Exception { get; set; }
14 | public int Level { get; set; }
15 | public string Message { get; set; }
16 | public string MessageTemplate { get; set; }
17 | public string Properties { get; set; }
18 | public DateTime Timestamp { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Entities/Settings/LinSetting.cs:
--------------------------------------------------------------------------------
1 | using FreeSql.DataAnnotations;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Entities.Settings
5 | {
6 | ///
7 | /// 配置项
8 | ///
9 | [Table(Name = "lin_settings")]
10 | public class LinSetting : FullAuditEntity
11 | {
12 | ///
13 | /// 键
14 | ///
15 | [Column(StringLength = 128)]
16 | public string Name { get; set; }
17 |
18 | ///
19 | /// 值
20 | ///
21 | [Column(StringLength = 2048)]
22 | public string Value { get; set; }
23 |
24 | ///
25 | /// 提供者
26 | ///
27 |
28 | [Column(StringLength = 64)]
29 | public string ProviderName { get; set; }
30 |
31 | ///
32 | /// 提供者值
33 | ///
34 | [Column(StringLength = 64)]
35 | public string ProviderKey { get; set; }
36 |
37 | public override string ToString()
38 | {
39 | return $"{base.ToString()}, Name = {Name}, Value = {Value}, ProviderName = {ProviderName}, ProviderKey = {ProviderKey}";
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Exceptions/LinCmsException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using LinCms.Data.Enums;
3 |
4 | namespace LinCms.Exceptions
5 | {
6 | [Serializable]
7 | public class LinCmsException(string message = "服务器繁忙,请稍后再试!", ErrorCode errorCode = ErrorCode.Fail, int code = 400)
8 | : ApplicationException(message)
9 | {
10 | ///
11 | /// 状态码
12 | ///
13 | private readonly int _code = code;
14 | ///
15 | /// 错误码,当为0时,代表正常
16 | ///
17 |
18 | private readonly ErrorCode _errorCode = errorCode;
19 | ///
20 | ///
21 | ///
22 | public LinCmsException() : this("服务器繁忙,请稍后再试!", ErrorCode.Fail, 400)
23 | {
24 | }
25 |
26 | ///
27 | ///
28 | ///
29 | ///
30 | public int GetCode()
31 | {
32 | return _code;
33 | }
34 |
35 | public ErrorCode GetErrorCode()
36 | {
37 | return _errorCode;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Extensions/HttpContextExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using Microsoft.AspNetCore.Authentication;
5 | using Microsoft.AspNetCore.Http;
6 | using Microsoft.Extensions.DependencyInjection;
7 |
8 | namespace LinCms.Extensions
9 | {
10 | public static class HttpContextExtensions
11 | {
12 | public static async Task GetExternalProvidersAsync(this HttpContext context)
13 | {
14 | if (context == null)
15 | {
16 | throw new ArgumentNullException(nameof(context));
17 | }
18 |
19 | var schemes = context.RequestServices.GetRequiredService();
20 |
21 | return (from scheme in await schemes.GetAllSchemesAsync()
22 | where !string.IsNullOrEmpty(scheme.DisplayName)
23 | select scheme).ToArray();
24 | }
25 |
26 | public static async Task IsProviderSupportedAsync(this HttpContext context, string provider)
27 | {
28 | if (context == null)
29 | {
30 | throw new ArgumentNullException(nameof(context));
31 | }
32 |
33 | return (from scheme in await context.GetExternalProvidersAsync()
34 | where string.Equals(scheme.Name, provider, StringComparison.OrdinalIgnoreCase)
35 | select scheme).Any();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/LinCms.Core/IRepositories/IFileRepository.cs:
--------------------------------------------------------------------------------
1 | using IGeekFan.FreeKit.Extras.FreeSql;
2 | using LinCms.Entities;
3 |
4 | namespace LinCms.IRepositories
5 | {
6 | public interface IFileRepository : IAuditBaseRepository
7 | {
8 | string GetFileUrl(string path);
9 |
10 | }
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/LinCms.Core/IRepositories/ILogRepository.cs:
--------------------------------------------------------------------------------
1 | using IGeekFan.FreeKit.Extras.FreeSql;
2 | using LinCms.Entities;
3 |
4 | namespace LinCms.IRepositories
5 | {
6 | public interface ILogRepository : IAuditBaseRepository
7 | {
8 | void Create(LinLog linlog);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/LinCms.Core/IRepositories/ISettingRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using IGeekFan.FreeKit.Extras.FreeSql;
4 | using LinCms.Entities.Settings;
5 |
6 | namespace LinCms.IRepositories
7 | {
8 | public interface ISettingRepository : IAuditBaseRepository
9 | {
10 | Task FindAsync(string name, string providerName, string providerKey);
11 |
12 | Task> GetListAsync(string providerName, string providerKey);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/LinCms.Core/IRepositories/IUserRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using System.Threading.Tasks;
4 | using IGeekFan.FreeKit.Extras.FreeSql;
5 | using LinCms.Entities;
6 |
7 | namespace LinCms.IRepositories
8 | {
9 | public interface IUserRepository : IAuditBaseRepository
10 | {
11 | ///
12 | /// 根据条件得到用户信息
13 | ///
14 | ///
15 | ///
16 | Task GetUserAsync(Expression> expression);
17 |
18 | ///
19 | /// 根据用户Id更新用户的最后登录时间
20 | ///
21 | ///
22 | ///
23 | Task UpdateLastLoginTimeAsync(long userId);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/LinCms.Core/LinCms.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | LinCms
6 | True
7 |
8 |
9 |
10 | LinCms.Core.xml
11 | bin\Debug\
12 | 4
13 | 1701;1702;1705;1591
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/LinCms.Core/Security/LinCmsClaimTypes.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Security
2 | {
3 | public class LinCmsClaimTypes
4 | {
5 | public const string GroupIds = "groupids";
6 | public const string IsActive = "isactve";
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/LinCms.Infrastructure/FreeSql/IDataSeedContributor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using IGeekFan.FreeKit.Extras.Dependency;
5 | using LinCms.Data;
6 |
7 | namespace LinCms.FreeSql;
8 |
9 | public interface IDataSeedContributor: ISingletonDependency
10 | {
11 |
12 | Task InitAdminPermission();
13 |
14 | Task SeedPermissionAsync(List linCmsAttributes, CancellationToken cancellationToken);
15 |
16 | }
--------------------------------------------------------------------------------
/src/LinCms.Infrastructure/LinCms.Infrastructure.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | LinCms
6 | True
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/LinCms.Infrastructure/Repositories/FileRepository.cs:
--------------------------------------------------------------------------------
1 | using FreeSql;
2 | using IGeekFan.FreeKit.Extras.FreeSql;
3 | using IGeekFan.FreeKit.Extras.Security;
4 | using LinCms.Data.Options;
5 | using LinCms.Entities;
6 | using LinCms.IRepositories;
7 | using Microsoft.Extensions.Options;
8 |
9 | namespace LinCms.Repositories;
10 |
11 | public class FileRepository(UnitOfWorkManager unitOfWorkManager,
12 | ICurrentUser currentUser,
13 | IOptionsMonitor fileStorageOption)
14 | : AuditDefaultRepository(unitOfWorkManager, currentUser), IFileRepository
15 | {
16 | private readonly FileStorageOption _fileStorageOption = fileStorageOption.CurrentValue;
17 |
18 | public string GetFileUrl(string path)
19 | {
20 | if (string.IsNullOrEmpty(path)) return "";
21 | if (path.StartsWith("http") || path.StartsWith("https"))
22 | {
23 | return path;
24 | }
25 | return _fileStorageOption.LocalFile.Host + path;
26 |
27 | //string redisKey = "filerepository:getfileurl:" +path;
28 |
29 | //return RedisHelper.CacheShell(
30 | // redisKey, 5*60, () =>
31 | // {
32 | // LinFile linFile = Where(r => r.Path == path).First();
33 | // if (linFile == null) return path;
34 | // return linFile.Type switch
35 | // {
36 | // 1 => _fileStorageOption.LocalFile.Host + path,
37 | // 2 => _fileStorageOption.Qiniu.Host + path,
38 | // _ => path,
39 | // };
40 | // }
41 | // );
42 | }
43 | }
--------------------------------------------------------------------------------
/src/LinCms.Infrastructure/Repositories/LogRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FreeSql;
3 | using IGeekFan.FreeKit.Extras.FreeSql;
4 | using IGeekFan.FreeKit.Extras.Security;
5 | using LinCms.Entities;
6 | using LinCms.IRepositories;
7 | using LinCms.Security;
8 |
9 | namespace LinCms.Repositories;
10 |
11 | public class LogRepository : AuditDefaultRepository, ILogRepository
12 | {
13 | public LogRepository(UnitOfWorkManager unitOfWorkManager, ICurrentUser currentUser)
14 | : base(unitOfWorkManager, currentUser)
15 | {
16 |
17 | }
18 |
19 | public void Create(LinLog linlog)
20 | {
21 | linlog.CreateTime = DateTime.Now;
22 | linlog.Username = CurrentUser.UserName;
23 | linlog.UserId = CurrentUser.FindUserId();
24 |
25 | base.Insert(linlog);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/LinCms.Infrastructure/Repositories/SettingRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using FreeSql;
5 | using IGeekFan.FreeKit.Extras.FreeSql;
6 | using IGeekFan.FreeKit.Extras.Security;
7 | using LinCms.Entities.Settings;
8 | using LinCms.IRepositories;
9 |
10 | namespace LinCms.Repositories;
11 |
12 | public class SettingRepository : AuditDefaultRepository, ISettingRepository
13 | {
14 | public SettingRepository(UnitOfWorkManager unitOfWorkManager, ICurrentUser currentUser) : base(unitOfWorkManager,
15 | currentUser)
16 | {
17 | }
18 |
19 | public async Task FindAsync(string name, string providerName, string providerKey)
20 | {
21 | return await Select.Where(s => s.Name == name && s.ProviderName == providerName && s.ProviderKey == providerKey)
22 | .FirstAsync();
23 | }
24 |
25 | public async Task> GetListAsync(string providerName, string providerKey)
26 | {
27 | return await Select
28 | .Where(
29 | s => s.ProviderName == providerName && s.ProviderKey == providerKey
30 | )
31 | .OrderByDescending(r => r.CreateTime)
32 | .ToListAsync();
33 | }
34 | }
--------------------------------------------------------------------------------
/src/LinCms.Infrastructure/Repositories/UserRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 | using System.Threading.Tasks;
4 |
5 | using FreeSql;
6 | using IGeekFan.FreeKit.Extras.FreeSql;
7 | using IGeekFan.FreeKit.Extras.Security;
8 | using LinCms.Entities;
9 | using LinCms.IRepositories;
10 |
11 | namespace LinCms.Repositories;
12 |
13 | public class UserRepository : AuditDefaultRepository, IUserRepository
14 | {
15 | public UserRepository(UnitOfWorkManager unitOfWorkManager, ICurrentUser currentUser) : base(unitOfWorkManager, currentUser)
16 | {
17 | }
18 |
19 | ///
20 | /// 根据条件得到用户信息
21 | ///
22 | ///
23 | ///
24 | public Task GetUserAsync(Expression> expression)
25 | {
26 | return Select.Where(expression).IncludeMany(r => r.LinGroups).ToOneAsync();
27 | }
28 |
29 | ///
30 | /// 根据用户Id更新用户的最后登录时间
31 | ///
32 | ///
33 | ///
34 | public Task UpdateLastLoginTimeAsync(long userId)
35 | {
36 | return UpdateDiy.Set(r => new LinUser()
37 | {
38 | LastLoginTime = DateTime.Now
39 | }).Where(r => r.Id == userId).ExecuteAffrowsAsync();
40 | }
41 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/LinCms.Plugins.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/Domain/LinPoem.cs:
--------------------------------------------------------------------------------
1 | using FreeSql.DataAnnotations;
2 | using IGeekFan.FreeKit.Extras.AuditEntity;
3 |
4 | namespace LinCms.Plugins.Poem.Domain;
5 |
6 | [Table(Name = "lin_poem")]
7 | public class LinPoem : FullAuditEntity
8 | {
9 |
10 | ///
11 | /// 作者
12 | ///
13 | [Column(StringLength = 50)]
14 | public string Author { get; set; } = string.Empty;
15 |
16 | ///
17 | /// 内容,以/来分割每一句,以|来分割宋词的上下片
18 | ///
19 | [Column(DbType = "text")]
20 | public string Content { get; set; } = string.Empty;
21 |
22 | ///
23 | /// 朝代
24 | ///
25 | [Column(StringLength = 50)]
26 | public string Dynasty { get; set; } = string.Empty;
27 |
28 | ///
29 | /// 配图
30 | ///
31 | public string Image { get; set; } = string.Empty;
32 |
33 | ///
34 | /// 标题
35 | ///
36 | [Column(StringLength = 50)]
37 | public string Title { get; set; } = string.Empty;
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/Models/CreateUpdatePoemDto.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Plugins.Poem.Models;
2 |
3 | public class CreateUpdatePoemDto
4 | {
5 | public string Author { get; set; }
6 | public string Content { get; set; }
7 | public string Dynasty { get; set; }
8 | public string Image { get; set; }
9 | public string Title { get; set; }
10 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/Models/PoemDto.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using IGeekFan.FreeKit.Extras.AuditEntity;
4 |
5 | namespace LinCms.Plugins.Poem.Models;
6 |
7 | public class PoemDto : EntityDto
8 | {
9 | public string Author { get; set; }
10 | public List> Content { get; set; }
11 | public string Dynasty { get; set; }
12 | public string Image { get; set; }
13 | public string Title { get; set; }
14 | public DateTime CreateTime { get; set; }
15 | public DateTime UpdateTime { get; set; }
16 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/PoemModule.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Plugins.Poem;
2 |
3 | class PoemModule
4 | {
5 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/Services/IPoemService.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Plugins.Poem.Services;
2 |
3 | public interface IPoemService
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/Services/PoemProfile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using AutoMapper;
4 | using LinCms.Plugins.Poem.Domain;
5 | using LinCms.Plugins.Poem.Models;
6 |
7 | namespace LinCms.Plugins.Poem.Services;
8 |
9 | public class PoemProfile : Profile
10 | {
11 | public PoemProfile()
12 | {
13 | CreateMap()
14 | .ForMember(r => r.Content, opts => opts.MapFrom(r => r
15 | .Content
16 | .Split('|', StringSplitOptions.None)
17 | .ToList()
18 | .ConvertAll(u => u.Split('/', StringSplitOptions.None).ToList())
19 | ));
20 |
21 | CreateMap();
22 |
23 | }
24 |
25 |
26 | }
--------------------------------------------------------------------------------
/src/LinCms.Plugins/Poem/Services/PoemService.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Plugins.Poem.Services;
2 |
3 | public class PoemService : IPoemService
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Entities/CommandOption.cs:
--------------------------------------------------------------------------------
1 | namespace LinCms.Scaffolding.Entities
2 | {
3 | public class CommandOption
4 | {
5 | public string Directory { get; set; } = null!;
6 | public string Entity { get; set; } = null!;
7 | ///
8 | /// 是否拆分DTO
9 | ///
10 | public bool SeparateDto { get; set; }
11 | public bool CustomRepository { get; set; }
12 | public bool NoOverwrite { get; set; }
13 | public bool SkipEntityConstructors { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Entities/ProjectInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace LinCms.Scaffolding.Entities
4 | {
5 | public class ProjectInfo
6 | {
7 | public ProjectInfo(string baseDirectory, string fullName)
8 | {
9 | BaseDirectory = baseDirectory;
10 | FullName = fullName;
11 | }
12 |
13 | public string BaseDirectory { get; }
14 | public string FullName { get; }
15 | public string Name => FullName.Split('.').Last();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Entities/PropertyInfo.cs:
--------------------------------------------------------------------------------
1 | using Humanizer;
2 | using System;
3 |
4 | namespace LinCms.Scaffolding.Entities
5 | {
6 | ///
7 | /// 属性
8 | ///
9 | public class PropertyInfo
10 | {
11 | public PropertyInfo(string type, string name)
12 | {
13 | Type = type;
14 | Name = name;
15 | }
16 |
17 | public PropertyInfo(string type, string name, string remarks) : this(type, name)
18 | {
19 | Remarks = remarks ?? throw new ArgumentNullException(nameof(remarks));
20 | }
21 |
22 | ///
23 | /// 属性类型
24 | ///
25 | public string Type { get; }
26 |
27 | ///
28 | /// 属性名
29 | ///
30 | public string Name { get; }
31 |
32 | ///
33 | /// 备注
34 | ///
35 | public string Remarks { get; set; }
36 |
37 |
38 | ///
39 | /// 属性名转下划线
40 | ///
41 | public string NameUnderscore => Name.Underscore();
42 |
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Entities/SettingOptions.cs:
--------------------------------------------------------------------------------
1 | using Humanizer;
2 |
3 | namespace LinCms.Scaffolding.Entities
4 | {
5 | public class SettingOptions
6 | {
7 | public static string Name = "SettingOptions";
8 | public string BaseDirectory { get; set; }
9 | public string ProjectName { get; set; }
10 | public string Areas { get; set; }
11 | public string EntityFilePath { get; set; }
12 | public string TemplatePath { get; set; }
13 | public string OutputDirectory { get; set; }
14 | //区域小写
15 | public string AreasCamelize => Areas.Camelize();
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/LinCms.Scaffolding.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 |
7 |
8 |
9 |
10 |
11 | PreserveNewest
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | PreserveNewest
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/lin-cms-vue/model/{{EntityInfo.NameCamelize}}.js.txt:
--------------------------------------------------------------------------------
1 | import { post, get, put, _delete } from "@/lin/plugin/axios";
2 |
3 | class {{EntityInfo.Name}} {
4 |
5 | async get{{EntityInfo.NamePluralized}}(params) {
6 | const res = await get("api/{{SettingOptions.AreasCamelize}}/{{EntityInfo.NameCamelizePluralized}}", params);
7 | return res;
8 | }
9 |
10 | async get{{EntityInfo.Name}}(id) {
11 | const res = await get(`api/{{SettingOptions.AreasCamelize}}/{{EntityInfo.NameCamelizePluralized}}/${id}`);
12 | return res;
13 | }
14 |
15 | async add{{EntityInfo.Name}}(params) {
16 | const res = await post("api/{{SettingOptions.AreasCamelize}}/{{EntityInfo.NameCamelizePluralized}}", params);
17 | return res;
18 | }
19 |
20 | async edit{{EntityInfo.Name}}(id, data) {
21 | const res = await put(`api/{{SettingOptions.AreasCamelize}}/{{EntityInfo.NameCamelizePluralized}}/${id}`, data);
22 | return res;
23 | }
24 |
25 | async delete{{EntityInfo.Name}}(id) {
26 | const res = await _delete(`api/{{SettingOptions.AreasCamelize}}/{{EntityInfo.NameCamelizePluralized}}/${id}`);
27 | return res;
28 | }
29 |
30 | }
31 |
32 | export default new {{EntityInfo.Name}}();
33 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/lin-cms-vue/stage-config.js.txt:
--------------------------------------------------------------------------------
1 | const {{SettingOptions.AreasCamelize}}Router = {
2 | route: null,
3 | name: null,
4 | title: "工作台",
5 | type: "folder", // 类型: folder, tab, view
6 | icon: "iconfont icon-tushuguanli",
7 | filePath: "view/{{SettingOptions.AreasCamelize}}/",
8 | order: null,
9 | inNav: true,
10 | children: [
11 | {
12 | name: null,
13 | title: "{{EntityInfo.EntityRemark}}管理",
14 | type: "view",
15 | name: "{{EntityInfo.Name}}List",
16 | route: "/{{SettingOptions.AreasCamelize}}/{{EntityInfo.NameCamelize}}/list",
17 | filePath: "plugin/{{SettingOptions.AreasCamelize}}/view/{{EntityInfo.NameCamelize}}/{{EntityInfo.NameCamelize}}-list.vue",
18 | inNav: true,
19 | permission: ["所有{{EntityInfo.EntityRemark}}"]
20 | }
21 | ]
22 | };
23 |
24 | export default {{SettingOptions.AreasCamelize}}Router;
25 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/{{ProjectInfo.FullName}}.Application.Contracts/{{SettingOptions.Areas}}/{{EntityInfo.NamePluralized}}/CreateUpdate{{EntityInfo.Name}}Dto.cs.txt:
--------------------------------------------------------------------------------
1 |
2 | namespace {{ EntityInfo.Namespace }}
3 | {
4 | public class CreateUpdate{{EntityInfo.Name }}Dto
5 | {
6 | {{~ for prop in EntityInfo.Properties ~}}
7 | public {{ prop.Type}} {{ prop.Name }} { get; set; }
8 | {{~ if !for.last ~}}
9 |
10 | {{~ end ~}}
11 | {{~ end ~}}
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/{{ProjectInfo.FullName}}.Application.Contracts/{{SettingOptions.Areas}}/{{EntityInfo.NamePluralized}}/I{{EntityInfo.Name}}Service.cs.txt:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using LinCms.Data;
3 |
4 | namespace {{ EntityInfo.Namespace }}
5 | {
6 | public interface I{{ EntityInfo.Name }}Service
7 | {
8 | Task DeleteAsync({{EntityInfo.PrimaryKey}} id);
9 |
10 | Task> GetListAsync(PageDto pageDto);
11 |
12 | Task<{{ EntityInfo.Name }}Dto> GetAsync({{EntityInfo.PrimaryKey}} id);
13 |
14 | Task CreateAsync(CreateUpdate{{ EntityInfo.Name }}Dto create{{ EntityInfo.Name }});
15 |
16 | Task UpdateAsync({{EntityInfo.PrimaryKey}} id, CreateUpdate{{ EntityInfo.Name }}Dto update{{ EntityInfo.Name }});
17 | }
18 | }
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/{{ProjectInfo.FullName}}.Application.Contracts/{{SettingOptions.Areas}}/{{EntityInfo.NamePluralized}}/{{EntityInfo.Name}}Dto.cs.txt:
--------------------------------------------------------------------------------
1 | using LinCms.Entities;
2 | namespace {{ EntityInfo.Namespace }}
3 | {
4 | public class {{EntityInfo.Name }}Dto:EntityDto<{{ EntityInfo.PrimaryKey }}>
5 | {
6 | {{~ for prop in EntityInfo.Properties ~}}
7 | public {{ prop.Type}} {{ prop.Name }} { get; set; }
8 | {{~ if !for.last ~}}
9 |
10 | {{~ end ~}}
11 | {{~ end ~}}
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/{{ProjectInfo.FullName}}.Application/{{SettingOptions.Areas}}/{{EntityInfo.NamePluralized}}/{{EntityInfo.Name}}Profile.cs.txt:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using {{ProjectInfo.FullName}}.Entities.{{SettingOptions.Areas}};
3 |
4 | namespace {{ EntityInfo.Namespace }}
5 | {
6 | public class {{ EntityInfo.Name }}Profile : Profile
7 | {
8 | public {{ EntityInfo.Name }}Profile()
9 | {
10 | CreateMap<{{ EntityInfo.Name }}, {{ EntityInfo.Name }}Dto>();
11 | CreateMap();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/{{ProjectInfo.FullName}}.Core/IRepositories/I{{EntityInfo.Name}}Repository.cs.txt:
--------------------------------------------------------------------------------
1 | using {{ProjectInfo.FullName}}.Entities.{{SettingOptions.Areas}};
2 | namespace {{ProjectInfo.FullName}}.IRepositories
3 | {
4 | public interface I{{ EntityInfo.Name }}Repository : IAuditBaseRepository<{{ EntityInfo.Name }},{{EntityInfo.PrimaryKey}}>
5 | {
6 |
7 | }
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/Templates/{{ProjectInfo.FullName}}.Infrastructure/Repositories/{{EntityInfo.Name}}Repository.cs.txt:
--------------------------------------------------------------------------------
1 | using FreeSql;
2 | using {{ProjectInfo.FullName}}.Entities.{{SettingOptions.Areas}};
3 | using {{ProjectInfo.FullName}}.IRepositories;
4 | using {{ProjectInfo.FullName}}.Security;
5 | namespace {{ProjectInfo.FullName}}.Repositories
6 | {
7 | public class {{ EntityInfo.Name }}Repository : AuditBaseRepository<{{ EntityInfo.Name }},{{EntityInfo.PrimaryKey}}>, I{{ EntityInfo.Name }}Repository
8 | {
9 | private readonly ICurrentUser _currentUser;
10 | public {{ EntityInfo.Name }}Repository(UnitOfWorkManager unitOfWork, ICurrentUser currentUser): base(unitOfWork, currentUser)
11 | {
12 | _currentUser = currentUser;
13 | }
14 | }
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/src/LinCms.Scaffolding/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Serilog": {
3 | "Using": [
4 | "Serilog.Sinks.Console",
5 | "Serilog.Sinks.File"
6 | ],
7 | "MinimalLevel": {
8 | "Default": "Information",
9 | "Override": {
10 | "Microsoft": "Information",
11 | "System": "Information"
12 | }
13 | },
14 | "WriteTo": [
15 | {
16 | "Name": "File",
17 | "Args": {
18 | "path": "Logs/log.txt",
19 | "rollingInterval": "Day"
20 | }
21 | },
22 | {
23 | "Name": "Console",
24 | "Args": {
25 | "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
26 | "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {NewLine}{Exception}"
27 | }
28 | }
29 | ]
30 | },
31 | "SettingOptions": {
32 | "ProjectName": "LinCms", //无用
33 | "BaseDirectory": "../../../../LinCms.Core/", // LinCms.Core所在目录。
34 | "EntityFilePath": "Entities/Book.cs", //实体类所在文件位置
35 | "Areas": "Base", //区域模块名
36 | "TemplatePath": "./Templates", //相对路径,当前项目下的Templates目录
37 | "OutputDirectory": "./code-scaffolding" //可以是相对路径,也可以是绝对路径
38 | }
39 | }
--------------------------------------------------------------------------------
/src/LinCms.Web/Controllers/ApiControllerBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace LinCms.Controllers;
5 |
6 | [ApiController]
7 | public abstract class ApiControllerBase : ControllerBase
8 | {
9 | public IServiceProvider? ServiceProvider { get; set; }
10 |
11 | }
--------------------------------------------------------------------------------
/src/LinCms.Web/Controllers/Base/BaseItemController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using LinCms.Aop.Filter;
4 | using LinCms.Base.BaseItems;
5 | using LinCms.Data;
6 | using Microsoft.AspNetCore.Mvc;
7 |
8 | namespace LinCms.Controllers.Base;
9 |
10 | ///
11 | /// 数据字典-详情项
12 | ///
13 | [ApiExplorerSettings(GroupName = "base")]
14 | [Area("base")]
15 | [Route("api/base/item")]
16 | [ApiController]
17 | public class BaseItemController(IBaseItemService baseItemService) : ControllerBase
18 | {
19 | [HttpDelete("{id}")]
20 | [LinCmsAuthorize("删除字典", "字典管理")]
21 | public async Task DeleteAsync(int id)
22 | {
23 | await baseItemService.DeleteAsync(id);
24 | return UnifyResponseDto.Success();
25 | }
26 |
27 | [HttpGet]
28 | public Task> GetListAsync([FromQuery] string typeCode)
29 | {
30 | return baseItemService.GetListAsync(typeCode); ;
31 | }
32 |
33 | [HttpGet("{id}")]
34 | public Task GetAsync(int id)
35 | {
36 | return baseItemService.GetAsync(id);
37 | }
38 |
39 | [HttpPost]
40 | [LinCmsAuthorize("新增字典", "字典管理")]
41 | public async Task CreateAsync([FromBody] CreateUpdateBaseItemDto createBaseItem)
42 | {
43 | await baseItemService.CreateAsync(createBaseItem);
44 | return UnifyResponseDto.Success("新建字典成功");
45 | }
46 |
47 | [HttpPut("{id}")]
48 | [LinCmsAuthorize("编辑字典", "字典管理")]
49 | public async Task UpdateAsync(int id, [FromBody] CreateUpdateBaseItemDto updateBaseItem)
50 | {
51 | await baseItemService.UpdateAsync(id, updateBaseItem);
52 | return UnifyResponseDto.Success("更新字典成功");
53 | }
54 | }
--------------------------------------------------------------------------------
/src/LinCms.Web/Controllers/Base/BaseTypeController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using LinCms.Aop.Filter;
4 | using LinCms.Base.BaseTypes;
5 | using LinCms.Data;
6 | using Microsoft.AspNetCore.Mvc;
7 |
8 | namespace LinCms.Controllers.Base;
9 |
10 | ///
11 | /// 数据字典-分类
12 | ///
13 | [ApiExplorerSettings(GroupName = "base")]
14 | [Area("base")]
15 | [Route("api/base/type")]
16 | [ApiController]
17 | public class BaseTypeController(IBaseTypeService baseTypeService) : ControllerBase
18 | {
19 | [HttpDelete("{id}")]
20 | [LinCmsAuthorize("删除字典类别", "字典类别")]
21 | public async Task DeleteAsync(int id)
22 | {
23 | await baseTypeService.DeleteAsync(id);
24 | return UnifyResponseDto.Success();
25 | }
26 |
27 | [HttpGet]
28 | public Task> GetListAsync()
29 | {
30 | return baseTypeService.GetListAsync();
31 | }
32 |
33 | [HttpGet("{id}")]
34 | public Task GetAsync(int id)
35 | {
36 | return baseTypeService.GetAsync(id);
37 | }
38 |
39 | [HttpPost]
40 | [LinCmsAuthorize("新增字典类别", "字典类别")]
41 | public async Task CreateAsync([FromBody] CreateUpdateBaseTypeDto createBaseType)
42 | {
43 | await baseTypeService.CreateAsync(createBaseType);
44 | return UnifyResponseDto.Success("新建类别成功");
45 | }
46 |
47 | [HttpPut("{id}")]
48 | [LinCmsAuthorize("编辑字典类别", "字典类别")]
49 | public async Task UpdateAsync(int id, [FromBody] CreateUpdateBaseTypeDto updateBaseType)
50 | {
51 | await baseTypeService.UpdateAsync(id, updateBaseType);
52 | return UnifyResponseDto.Success("更新类别成功");
53 | }
54 | }
--------------------------------------------------------------------------------
/src/LinCms.Web/Controllers/Blog/ArticleDraftController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | using LinCms.Blog.ArticleDrafts;
5 |
6 | using Microsoft.AspNetCore.Authorization;
7 | using Microsoft.AspNetCore.Mvc;
8 |
9 | namespace LinCms.Controllers.Blog;
10 |
11 | ///
12 | /// 随笔草稿箱,自动保存随笔
13 | ///
14 | [Area("blog")]
15 | [ApiExplorerSettings(GroupName = "blog")]
16 | [Route("api/blog/articles/draft")]
17 | [ApiController]
18 | [Authorize]
19 | public class ArticleDraftController(IArticleDraftService articleDraftService) : ControllerBase
20 | {
21 | [HttpPut("{id}")]
22 | public Task UpdateAsync(Guid id, [FromBody] UpdateArticleDraftDto updateArticleDto)
23 | {
24 | return articleDraftService.UpdateAsync(id, updateArticleDto);
25 | }
26 |
27 | ///
28 | /// 用户的随笔草稿详情
29 | ///
30 | ///
31 | ///
32 | [HttpGet("{id}")]
33 | public Task GetAsync(Guid id)
34 | {
35 | return articleDraftService.GetAsync(id);
36 | }
37 | }
--------------------------------------------------------------------------------
/src/LinCms.Web/Controllers/Blog/AuthorCenterController.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using LinCms.Blog.AuthorCenter;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Microsoft.AspNetCore.Mvc;
5 |
6 | namespace LinCms.Controllers.Blog;
7 |
8 | ///