├── .dockerignore ├── .gitattributes ├── .github └── workflows │ ├── build.yml │ ├── docker.yml │ └── nuget.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── SECURITY.md ├── deploy └── docker-compose │ ├── docker-compose.yml │ └── nginx.conf ├── publish.sh ├── src ├── .editorconfig ├── Directory.Build.props ├── OpenTask.Application.Tests │ ├── DiscoveryFromDb_Test.cs │ ├── LockerService_Test.cs │ └── OpenTask.Application.Tests.csproj ├── OpenTask.Application │ ├── Base │ │ ├── BaseResponse.cs │ │ ├── Commands │ │ │ ├── CommandBase.cs │ │ │ ├── ICommand.cs │ │ │ ├── ICommandHandler.cs │ │ │ └── InternalCommandBase.cs │ │ ├── JwtOptions.cs │ │ ├── PageQuery.cs │ │ ├── PageResponse.cs │ │ └── Queries │ │ │ ├── IQuery.cs │ │ │ └── IQueryHandler.cs │ ├── Clients │ │ ├── ListClientsHandler.cs │ │ ├── ListClientsRequest.cs │ │ └── ListClientsResponse.cs │ ├── Core │ │ ├── ClusterSubscriber.cs │ │ ├── DiscoveryFromDb.cs │ │ ├── Interface │ │ │ ├── IClusterMessage.cs │ │ │ ├── IDiscovery.cs │ │ │ ├── ITaskDispatcher.cs │ │ │ ├── ITaskSchedulingHandler.cs │ │ │ └── ITaskServer.cs │ │ ├── Models │ │ │ ├── ClusterMessage.cs │ │ │ ├── MqttNetConsoleLogger.cs │ │ │ ├── Server.cs │ │ │ └── TaskServerOptions.cs │ │ ├── MyLog.cs │ │ ├── OpenTaskServer.cs │ │ ├── SchedulingHandler.cs │ │ ├── SelfSubscriber.cs │ │ └── TaskDispatcher.cs │ ├── Dashboard │ │ ├── DashboardHandler.cs │ │ ├── StatisticsRequest.cs │ │ └── StatisticsResponse.cs │ ├── ExecutorClient.cs │ ├── Extensions │ │ └── OpentaskExtensions.cs │ ├── Issue │ │ ├── MyIssueCommand.cs │ │ ├── MyIssueHandler.cs │ │ └── MyIssueResponse.cs │ ├── Lockers │ │ └── LockerService.cs │ ├── MediatRProfile.cs │ ├── Members │ │ ├── GetMember │ │ │ ├── MemberHandler.cs │ │ │ ├── MemberRequest.cs │ │ │ └── MemberResponse.cs │ │ └── ListMembers │ │ │ ├── ListMembersHandler.cs │ │ │ ├── ListMembersRequest.cs │ │ │ └── ListMembersResponse.cs │ ├── OpenTask.Application.csproj │ ├── Orgs │ │ ├── CreateOrganization │ │ │ ├── CreateOrganizationHandler.cs │ │ │ ├── CreateOrganizationRequest.cs │ │ │ └── CreateOrganizationResponse.cs │ │ └── ListOrg │ │ │ ├── ListOrgCommand.cs │ │ │ ├── ListOrgCommandHandler.cs │ │ │ └── ListOrgResponse.cs │ ├── Projects │ │ ├── CreateProject │ │ │ ├── CreateProjectHandler.cs │ │ │ ├── CreateProjectRequest.cs │ │ │ └── CreateProjectResponse.cs │ │ └── ListProject │ │ │ ├── ListProjectHandler.cs │ │ │ ├── ListProjectRequest.cs │ │ │ └── ListProjectResponse.cs │ ├── ProxyModel.cs │ ├── Services │ │ ├── CleanerBackgroundService.cs │ │ └── OpenTaskServerBackgroundService.cs │ ├── TaskInfos │ │ ├── AddTaskRequest.cs │ │ ├── AddTaskResponse.cs │ │ ├── DeleteTaskRequest.cs │ │ ├── DeleteTaskResponse.cs │ │ ├── ExcuteOnceRequest.cs │ │ ├── ExcuteOnceResponse.cs │ │ ├── GetNext5TriggertimesRequest.cs │ │ ├── GetNext5TriggertimesResponse.cs │ │ ├── ListTaskInfosRequest.cs │ │ ├── ListTaskInfosResponse.cs │ │ ├── SwitchTaskStatusRequest.cs │ │ ├── SwitchTaskStatusResponse.cs │ │ ├── TaskInfoRequest.cs │ │ ├── TaskInfoResponse.cs │ │ └── TaskInfosHandler.cs │ ├── TaskLogs │ │ ├── LisTaskLogsRequest.cs │ │ ├── LisTaskLogsRequestHandler.cs │ │ ├── LisTaskLogsResponse.cs │ │ ├── ListTopTaskLogRequest.cs │ │ ├── ListTopTaskLogResponse.cs │ │ ├── TaskLogsDayTrendRequest.cs │ │ └── TaskLogsDayTrendResponse.cs │ ├── Todos │ │ └── GetTodoItems │ │ │ ├── GetTodoItemsQuery.cs │ │ │ ├── GetTodoItemsQueryHandler.cs │ │ │ ├── TodoDto.cs │ │ │ └── TodoItemResponse.cs │ └── User │ │ └── Login │ │ ├── LoginCommand.cs │ │ ├── LoginCommandHandler.cs │ │ └── LoginResponse.cs ├── OpenTask.Client │ ├── Handlers │ │ ├── DemoJobHandler.cs │ │ └── JobHandler.cs │ ├── OpenTask.Client.Sample.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ └── appsettings.json ├── OpenTask.Core │ ├── Base │ │ ├── IOpenTaskWorker.cs │ │ ├── ITaskHandler.cs │ │ └── TaskWorker.cs │ ├── ConstString.cs │ ├── Extensions │ │ └── IServiceCollectionExtensions.cs │ ├── Models │ │ ├── BaseMassageAgrs.cs │ │ ├── HandlerRegister.cs │ │ ├── MqttConsleLogger.cs │ │ ├── OnTaskRequest.cs │ │ ├── OpenWorkerOptions.cs │ │ ├── TaskContext.cs │ │ └── TodoTask.cs │ ├── OpenTask.Core.csproj │ ├── Properties │ │ └── launchSettings.json │ └── Services │ │ └── OpenTaskWorkerBackgroundService.cs ├── OpenTask.Domain.Tests │ └── OpenTask.Domain.Tests.csproj ├── OpenTask.Domain │ ├── Base │ │ ├── Repositorys │ │ │ └── IRepository.cs │ │ └── Types │ │ │ ├── Identifier.cs │ │ │ ├── TeamId.cs │ │ │ ├── TeamName.cs │ │ │ └── UserName.cs │ ├── Lockers │ │ ├── ILockerRepository.cs │ │ └── Locker.cs │ ├── OpenTask.Domain.csproj │ ├── Servers │ │ ├── IServerRepository.cs │ │ └── OpenTaskServer.cs │ ├── TaskInfos │ │ ├── ITaskInfoRepository.cs │ │ ├── TaskInfo.cs │ │ ├── TaskInfoBaseStatistics.cs │ │ └── TaskLogStatus.cs │ ├── TaskLogs │ │ ├── ITaskLogRepository.cs │ │ ├── TaskLog.cs │ │ ├── TaskLogBaseStatistics.cs │ │ ├── TaskLogDayTrend.cs │ │ └── TopTaskLog.cs │ └── Users │ │ ├── CurrentUser.cs │ │ ├── IUserRepository.cs │ │ ├── User.cs │ │ └── UserService.cs ├── OpenTask.Persistence │ ├── AutoMapperProfile.cs │ ├── Base │ │ ├── CustomColumnNameResolver.cs │ │ ├── CustomKeyPropertyResolver.cs │ │ └── CustomTableNameResolver.cs │ ├── Contexts │ │ ├── MyOpenTaskContext.cs │ │ └── OpenTaskContext.cs │ ├── DesignTimeDbContextFactory.cs │ ├── Entitys │ │ ├── OtLocker.cs │ │ ├── OtServer.cs │ │ ├── OtTaskInfo.cs │ │ ├── OtTaskLog.cs │ │ └── OtUser.cs │ ├── Extensions │ │ ├── DapperDBContextOptions.cs │ │ ├── DapperDBContextServiceCollectionExtensions.cs │ │ ├── DapperDbContext.cs │ │ └── PersistenceCollectionExtensions.cs │ ├── Migrations │ │ ├── 20240626091456_InitialCreate.Designer.cs │ │ ├── 20240626091456_InitialCreate.cs │ │ └── OpenTaskContextModelSnapshot.cs │ ├── Models │ │ ├── InjectAttribute.cs │ │ ├── TaskInfoBaseStatisticsDbModel.cs │ │ ├── TaskLogBaseStatisticsDbModel.cs │ │ ├── TaskLogDayTrendDbModel.cs │ │ └── TopTaskLogDbModel.cs │ ├── OpenTask.Persistence.csproj │ ├── Readme.md │ └── Repositorys │ │ ├── LockerRepository.cs │ │ ├── ServerRepository.cs │ │ ├── TaskInfoRepository.cs │ │ ├── TaskLogRepository.cs │ │ └── UserRepository.cs ├── OpenTask.Publisher │ ├── Class1.cs │ └── OpenTask.Publisher.csproj ├── OpenTask.Utility │ ├── Converters │ │ ├── DateTimeConverter.cs │ │ └── JsonLongConverter.cs │ ├── Extensions │ │ ├── DateTimeExtensions.cs │ │ └── LongExtensions.cs │ ├── Helpers │ │ ├── CrontabUtility.cs │ │ └── Md5Helper.cs │ └── OpenTask.Utility.csproj ├── OpenTask.WebApi.Tests │ ├── CustomWebApplicationFactory.cs │ ├── FakeUserStartupFilter.cs │ ├── IntegrationTests │ │ ├── ClientTests.cs │ │ └── DashboardTest.cs │ ├── OpenTask.WebApi.Tests.csproj │ ├── Properties │ │ └── launchSettings.json │ └── UnitTest │ │ └── UnitTest1.cs ├── OpenTask.WebApi │ ├── Controllers │ │ ├── BaseController.cs │ │ ├── ClientController.cs │ │ ├── DashboardController.cs │ │ ├── MembersController.cs │ │ ├── OrganizationController.cs │ │ ├── ProjectsController.cs │ │ ├── TaskInfoController.cs │ │ ├── TaskLogController.cs │ │ ├── TodoItemController.cs │ │ ├── UserController.cs │ │ └── WorkitemsController.cs │ ├── Extensions │ │ ├── IServiceCollectionExtensions.cs │ │ └── MySchemaProcessor.cs │ ├── Filters │ │ ├── CustomExceptionFilterAttribute.cs │ │ └── LongToStringSchemaFilter.cs │ ├── Models │ │ ├── DeleteJobRequest.cs │ │ ├── GetJobListRequest.cs │ │ ├── GetTokenRequest.cs │ │ └── ResultData.cs │ ├── OpenTask.WebApi.csproj │ ├── OpenTask.WebApi.csproj.user │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ └── appsettings.json └── OpenTask.sln └── ui └── vite-opentask ├── .env.development ├── .eslintrc.cjs ├── .gitignore ├── .npmrc ├── README.md ├── app └── globals.css ├── components.json ├── index.html ├── openapitools.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── mockServiceWorker.js └── vite.svg ├── src ├── App.css ├── App.tsx ├── apis-gen │ ├── .openapi-generator-ignore │ ├── .openapi-generator │ │ ├── FILES │ │ └── VERSION │ ├── apis │ │ ├── ClientApi.ts │ │ ├── DashboardApi.ts │ │ ├── TaskInfoApi.ts │ │ ├── TaskLogApi.ts │ │ ├── UserApi.ts │ │ └── index.ts │ ├── index.ts │ ├── models │ │ ├── AddTaskRequest.ts │ │ ├── AddTaskResponseBaseResponse.ts │ │ ├── DeleteTaskRequest.ts │ │ ├── DeleteTaskResponseBaseResponse.ts │ │ ├── ExcuteOnceRequest.ts │ │ ├── ExcuteOnceResponseBaseResponse.ts │ │ ├── ExecutorClient.ts │ │ ├── GetNext5TriggertimesResponse.ts │ │ ├── GetNext5TriggertimesResponseBaseResponse.ts │ │ ├── LisTaskLogsResponse.ts │ │ ├── LisTaskLogsResponseBaseResponse.ts │ │ ├── ListClientsResponse.ts │ │ ├── ListClientsResponseBaseResponse.ts │ │ ├── ListTaskInfosResponse.ts │ │ ├── ListTaskInfosResponseBaseResponse.ts │ │ ├── ListTopTaskLogResponse.ts │ │ ├── ListTopTaskLogResponseBaseResponse.ts │ │ ├── LoginCommand.ts │ │ ├── LoginResponse.ts │ │ ├── LoginResponseBaseResponse.ts │ │ ├── StatisticInfos.ts │ │ ├── StatisticsResponse.ts │ │ ├── StatisticsResponseBaseResponse.ts │ │ ├── SwitchTaskStatusRequest.ts │ │ ├── SwitchTaskStatusResponseBaseResponse.ts │ │ ├── TaskInfo.ts │ │ ├── TaskLog.ts │ │ ├── TaskLogDayTrend.ts │ │ ├── TaskLogsDayTrendResponse.ts │ │ ├── TaskLogsDayTrendResponseBaseResponse.ts │ │ ├── TopTaskLog.ts │ │ └── index.ts │ └── runtime.ts ├── apis │ ├── config.ts │ ├── index.tsx │ └── types │ │ └── index.tsx ├── assets │ └── react.svg ├── common │ └── types.tsx ├── components │ ├── dashboard-nav.tsx │ ├── date-table │ │ ├── data-table-column-header.tsx │ │ ├── data-table-faceted-filter.tsx │ │ ├── data-table-pagination.tsx │ │ ├── data-table-toolbar.tsx │ │ ├── data-table-view-options.tsx │ │ └── data-table.tsx │ ├── drawer │ │ ├── index.css │ │ └── index.tsx │ ├── icons copy.tsx │ ├── icons.tsx │ ├── logo.tsx │ ├── mode-toggle.tsx │ ├── nav │ │ └── nav.tsx │ ├── page.tsx │ ├── pages │ │ └── subpage-back.tsx │ ├── sidebar │ │ └── sidebar.tsx │ └── ui │ │ ├── alert.tsx │ │ ├── avatar.tsx │ │ ├── badge.tsx │ │ ├── breadcrumb.tsx │ │ ├── button.tsx │ │ ├── calendar.tsx │ │ ├── card.tsx │ │ ├── checkbox.tsx │ │ ├── collapsible.tsx │ │ ├── command.tsx │ │ ├── dialog.tsx │ │ ├── dropdown-menu.tsx │ │ ├── form.tsx │ │ ├── hover-card.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── pagination.tsx │ │ ├── popover.tsx │ │ ├── radio-group.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── sheet.mine.tsx │ │ ├── sheet.tsx │ │ ├── skeleton.tsx │ │ ├── slider.tsx │ │ ├── sonner.tsx │ │ ├── stepper.tsx │ │ ├── switch.tsx │ │ ├── table.tsx │ │ ├── tabs.tsx │ │ ├── textarea.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ ├── toggle-group.tsx │ │ ├── toggle.tsx │ │ ├── tooltip.tsx │ │ └── use-toast.ts ├── layout │ ├── app-content.tsx │ ├── app-footer.tsx │ ├── app-header.tsx │ ├── app-layout.tsx │ ├── app-sidebar.tsx │ ├── mobile-sidebar.tsx │ ├── page-with-nav.tsx │ └── user-nav.tsx ├── lib │ ├── jwt-decode.ts │ └── utils.ts ├── main.tsx ├── mocks │ ├── browser.ts │ ├── handlers.ts │ └── node.ts ├── pages │ ├── about │ │ └── index.tsx │ ├── clients │ │ ├── components │ │ │ ├── columns.tsx │ │ │ └── data-table-row-actions.tsx │ │ └── index.tsx │ ├── error │ │ └── _404.tsx │ ├── home │ │ ├── components │ │ │ ├── base-statistics.tsx │ │ │ ├── tasklog-daytrend.tsx │ │ │ └── tasklog-top.tsx │ │ └── index.tsx │ ├── login │ │ ├── components │ │ │ └── user-auth-form.tsx │ │ ├── forgot.tsx │ │ └── index.tsx │ ├── taskInfos │ │ ├── components │ │ │ ├── columns.tsx │ │ │ ├── data-table-row-actions.tsx │ │ │ ├── new-task-form.tsx │ │ │ ├── switch-status.tsx │ │ │ └── tool-bar.tsx │ │ └── index.tsx │ ├── taskLogs │ │ ├── components │ │ │ ├── columns.tsx │ │ │ ├── data-table-row-actions.tsx │ │ │ └── tool-bar.tsx │ │ └── index.tsx │ └── user │ │ └── index.tsx ├── routes │ ├── auth-router.tsx │ ├── error-page.tsx │ ├── index.tsx │ ├── modules │ │ ├── bottom.tsx │ │ ├── fullscreen.tsx │ │ ├── hidden.tsx │ │ └── side.tsx │ └── utils.tsx ├── store │ ├── index.tsx │ └── useSiderBar.tsx ├── theme │ └── theme-provider.tsx └── vite-env.d.ts ├── tailwind.config.js ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/dist 3 | **/.dockerignore 4 | **/.env 5 | **/.git 6 | **/.gitignore 7 | **/.project 8 | **/.settings 9 | **/.toolstarget 10 | **/.vs 11 | **/.vscode 12 | **/*.*proj.user 13 | **/*.dbmdl 14 | **/*.jfm 15 | **/azds.yaml 16 | **/bin 17 | **/charts 18 | **/docker-compose* 19 | **/Dockerfile* 20 | **/node_modules 21 | **/npm-debug.log 22 | **/obj 23 | **/secrets.dev.yaml 24 | **/values.dev.yaml 25 | LICENSE 26 | README.md 27 | !**/.gitignore 28 | !.git/HEAD 29 | !.git/config 30 | !.git/packed-refs 31 | !.git/refs/heads/** -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.dart text eol=lf 2 | *.md text eol=lf 3 | *.txt text eol=lf 4 | *.json text eol=lf 5 | *.cc text eol=lf 6 | *.cmake text eol=lf 7 | *.swift text eol=lf -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Build the Docker image 18 | run: | 19 | docker build . --file Dockerfile 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: publish docker 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | jobs: 8 | 9 | publish: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Build the Docker image 16 | run: | 17 | docker login --username=springhgui0127 registry.cn-hangzhou.aliyuncs.com --password=${{ secrets.PASSWORD }} 18 | version=$(grep "" src/Directory.Build.props | awk -F'[<>]' '{print $3}') 19 | echo $version 20 | appName=registry.cn-hangzhou.aliyuncs.com/hgui/opentask 21 | tag=$appName:$version-$(date +%s) 22 | latestTag=$appName:latest 23 | echo $tag 24 | docker build . --file Dockerfile --tag $tag 25 | docker push $tag 26 | docker tag $tag $latestTag 27 | docker push $latestTag 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /src/.vs 2 | obj 3 | bin 4 | logs 5 | /src/OpenTask.WebApi/appsettings.Development.json 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Gui.H 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 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /deploy/docker-compose/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | opentask-mysql: 3 | restart: always 4 | image: registry.cn-hangzhou.aliyuncs.com/hgui/mysql:8.4.1 5 | container_name: opentask-mysql 6 | volumes: 7 | - /apps/mysql/mysql:/var/lib/mysql 8 | - /apps/mysql/conf.d:/etc/mysql/conf.d 9 | environment: 10 | - "MYSQL_ROOT_PASSWORD=OPEN_TASK_123" # 请修改此处的密码 11 | - "MYSQL_DATABASE=open_task" 12 | ports: 13 | - 3306:3306 14 | healthcheck: 15 | test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ] 16 | interval: 2s 17 | timeout: 2s 18 | retries: 10 19 | 20 | opentask-api: 21 | restart: always 22 | image: registry.cn-hangzhou.aliyuncs.com/hgui/opentask:latest 23 | container_name: opentask-api 24 | depends_on: 25 | opentask-mysql: 26 | condition: service_healthy 27 | volumes: 28 | - /apps/opentask/logs:/app/logs 29 | environment: 30 | - "ConnectionStrings__Core=server=opentask-mysql;Port=3306;user id=root;database=open_task;pooling=true;password=OPEN_TASK_123" # 请修改此处的密码 31 | - "TZ=Asia/Shanghai" 32 | ports: 33 | - 8080:8080 34 | - 1883:1883 35 | links: 36 | - opentask-mysql 37 | 38 | opentask-nginx: 39 | restart: always 40 | image: registry.cn-hangzhou.aliyuncs.com/hgui/nginx:1.26.1 41 | container_name: opentask-nginx 42 | volumes: 43 | - ./nginx.conf:/etc/nginx/nginx.conf 44 | ports: 45 | - 80:80 46 | links: 47 | - opentask-api 48 | -------------------------------------------------------------------------------- /deploy/docker-compose/nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes auto; 4 | 5 | error_log /var/log/nginx/error.log notice; 6 | pid /var/run/nginx.pid; 7 | 8 | 9 | events { 10 | worker_connections 1024; 11 | } 12 | 13 | 14 | http { 15 | include /etc/nginx/mime.types; 16 | default_type application/octet-stream; 17 | 18 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 19 | '$status $body_bytes_sent "$http_referer" ' 20 | '"$http_user_agent" "$http_x_forwarded_for"'; 21 | 22 | access_log /var/log/nginx/access.log main; 23 | 24 | sendfile on; 25 | #tcp_nopush on; 26 | 27 | keepalive_timeout 65; 28 | 29 | #gzip on; 30 | 31 | include /etc/nginx/conf.d/*.conf; 32 | 33 | server { 34 | listen 80; 35 | server_name opentask.run; 36 | 37 | location / { 38 | proxy_pass http://opentask-api:8080; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if command -v podman &> /dev/null; then 3 | alias docker=podman 4 | else 5 | echo "podman not installed" 6 | fi 7 | 8 | # 读取文件内容,并使用grep和awk提取Version的值 9 | version=$(grep "" src/Directory.Build.props | awk -F'[<>]' '{print $3}') 10 | appName=registry.cn-hangzhou.aliyuncs.com/hgui/opentask:$version 11 | # 输出Version的值 12 | echo "Version: $version" 13 | 14 | docker build . -t $appName 15 | if [ $? -ne 0 ]; then 16 | echo "docker image build fail 😭😭😭" 17 | else 18 | echo "docker image build success 🎉🎉🎉" 19 | fi 20 | 21 | docker push $appName 22 | read 23 | exit 1 -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0.1.0 4 | OpenTask 去中心化分布式任务调度平台 5 | preview 6 | enable 7 | https://github.com/SpringHgui/OpenTask 8 | https://github.com/SpringHgui/OpenTask 9 | 10 | -------------------------------------------------------------------------------- /src/OpenTask.Application.Tests/OpenTask.Application.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/BaseResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Base 8 | { 9 | public class BaseResponse 10 | { 11 | public required int Code { get; set; } 12 | 13 | public bool Success => Code == 200; 14 | 15 | public T? Result { get; set; } 16 | 17 | public required string Message { get; set; } 18 | 19 | public required string TraceId { get; set; } = null!; 20 | } 21 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/Commands/CommandBase.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Base.Commands 8 | { 9 | public class CommandBase : ICommand 10 | { 11 | public Guid Id { get; } 12 | 13 | public CommandBase() 14 | { 15 | Id = Guid.NewGuid(); 16 | } 17 | 18 | protected CommandBase(Guid id) 19 | { 20 | Id = id; 21 | } 22 | } 23 | 24 | public abstract class CommandBase : ICommand 25 | { 26 | public Guid Id { get; } 27 | 28 | protected CommandBase() 29 | { 30 | Id = Guid.NewGuid(); 31 | } 32 | 33 | protected CommandBase(Guid id) 34 | { 35 | Id = id; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/Commands/ICommand.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | 9 | namespace OpenTask.Application.Base.Commands 10 | { 11 | public interface ICommand : IRequest 12 | { 13 | } 14 | 15 | public interface ICommand : IRequest 16 | { 17 | } 18 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/Commands/ICommandHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | 9 | namespace OpenTask.Application.Base.Commands 10 | { 11 | public interface ICommandHandler : 12 | IRequestHandler where TCommand : ICommand 13 | { 14 | 15 | } 16 | 17 | public interface ICommandHandler : 18 | IRequestHandler where TCommand : ICommand 19 | { 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/Commands/InternalCommandBase.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Base.Commands 8 | { 9 | public abstract class InternalCommandBase : ICommand 10 | { 11 | public Guid Id { get; } 12 | 13 | protected InternalCommandBase(Guid id) 14 | { 15 | Id = id; 16 | } 17 | } 18 | 19 | public abstract class InternalCommandBase : ICommand 20 | { 21 | public Guid Id { get; } 22 | 23 | protected InternalCommandBase() 24 | { 25 | Id = Guid.NewGuid(); 26 | } 27 | 28 | protected InternalCommandBase(Guid id) 29 | { 30 | Id = id; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/JwtOptions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.ComponentModel.DataAnnotations; 8 | 9 | namespace OpenTask.Application.Base 10 | { 11 | public class JwtOptions 12 | { 13 | public const string Jwt = "Jwt"; 14 | public const string DefaultScheme = "Bearer"; 15 | 16 | [Required] 17 | public string SigningKey { get; set; } = null!; 18 | 19 | public int ClockSkew { get; set; } 20 | 21 | [Required] 22 | public string ValidAudience { get; set; } = null!; 23 | 24 | [Required] 25 | public string ValidIssuer { get; set; } = null!; 26 | 27 | [Range(1, int.MaxValue)] 28 | public int Expires { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/PageQuery.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Base 8 | { 9 | public class PageQuery 10 | { 11 | public int PageNumber { get; set; } 12 | 13 | public int PageSize { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/PageResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Base 8 | { 9 | public class PageResponse 10 | { 11 | public long Count { get; set; } 12 | 13 | public IEnumerable? Rows { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/Queries/IQuery.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | 9 | namespace OpenTask.Application.Base.Queries 10 | { 11 | public interface IQuery : IRequest 12 | { 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Base/Queries/IQueryHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | 9 | namespace OpenTask.Application.Base.Queries 10 | { 11 | public interface IQueryHandler : 12 | IRequestHandler where TQuery : IQuery 13 | { 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Clients/ListClientsHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using OpenTask.Application.Core.Interface; 9 | 10 | namespace OpenTask.Application.Clients 11 | { 12 | public class ListClientsHandler : IRequestHandler 13 | { 14 | private readonly ITaskServer serverSystem; 15 | public ListClientsHandler(ITaskServer serverSystem) 16 | { 17 | this.serverSystem = serverSystem; 18 | } 19 | 20 | Task IRequestHandler.Handle(ListClientsRequest request, CancellationToken cancellationToken) 21 | { 22 | IEnumerable list = serverSystem.GetAllClientsOnline(); 23 | return Task.FromResult(new ListClientsResponse 24 | { 25 | Count = list.Count(), 26 | Rows = list.Skip((request.PageNumber - 1) * request.PageSize).Take(request.PageSize), 27 | }); 28 | } 29 | 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Clients/ListClientsRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using OpenTask.Application.Base; 9 | 10 | namespace OpenTask.Application.Clients 11 | { 12 | public class ListClientsRequest : PageQuery, IRequest 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Clients/ListClientsResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base; 8 | 9 | namespace OpenTask.Application.Clients 10 | { 11 | public class ListClientsResponse : PageResponse 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Interface/IClusterMessage.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Core.Interface 8 | { 9 | /// 10 | /// 集群之间发布的消息内容 11 | /// 12 | public interface IClusterMessage 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Interface/IDiscovery.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Collections.Concurrent; 8 | 9 | namespace OpenTask.Application.Core.Interface 10 | { 11 | public interface IDiscovery 12 | { 13 | public Task StartAsync(ITaskServer myMqttServer, CancellationToken stoppingToken); 14 | 15 | public event OnSlotParamer OnSloting; 16 | 17 | public event OnSlotParamer OnSloted; 18 | 19 | public delegate Task OnNodeSlotsChange(int start, int end); 20 | 21 | public delegate Task OnNewNodeChange(Domain.Servers.OpenTaskServer node); 22 | 23 | public delegate Task OnSlotParamer(IDiscovery sender, IEnumerable mqttNodes); 24 | 25 | public bool IsWholeSlot(IEnumerable latestNodes); 26 | 27 | public IEnumerable CalculateSlot(IEnumerable latestNodes); 28 | 29 | public ConcurrentDictionary clusterSubscribers { get; } 30 | 31 | public IEnumerable FindAllOnlineServer(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Interface/ITaskDispatcher.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.TaskInfos; 8 | 9 | namespace OpenTask.Application.Core.Interface 10 | { 11 | public interface ITaskDispatcher 12 | { 13 | Task<(bool Success, string Message)> DispatchAsync(ITaskServer server, TaskInfo job); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Interface/ITaskSchedulingHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Core.Interface 8 | { 9 | public interface ITaskSchedulingHandler 10 | { 11 | Task Start(ITaskServer taskServer, CancellationToken stoppingToken); 12 | 13 | void StartDispatch(); 14 | 15 | void StopDispatch(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Interface/ITaskServer.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MQTTnet; 8 | using MQTTnet.Client; 9 | using System.Collections.Concurrent; 10 | 11 | namespace OpenTask.Application.Core.Interface 12 | { 13 | public interface ITaskServer 14 | { 15 | string ExternalUrl { get; } 16 | 17 | string Identifier { get; } 18 | 19 | IDiscovery Discovery { get; } 20 | 21 | ConcurrentDictionary CurrentNodeOnlineUsers { get; } 22 | 23 | ConcurrentDictionary> OtherNodeOlineUsers { get; } 24 | 25 | IEnumerable GetAllClientsOnline(); 26 | 27 | IEnumerable GetClientsByAppName(string appid); 28 | 29 | Task PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken = default); 30 | 31 | Task StartAsync(CancellationToken stoppingToken); 32 | 33 | void StartDispatch(); 34 | 35 | void StopDispatch(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Models/ClusterMessage.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Core.Models 8 | { 9 | public class ClusterMessage 10 | { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Models/Server.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Core.Models 8 | { 9 | [Obsolete("使用Server替代", true)] 10 | public class Server 11 | { 12 | public required string Endpoint { get; set; } 13 | 14 | public required string Guid { get; set; } 15 | 16 | /// 17 | /// 0~16383 18 | /// 19 | public int SlotStart { get; set; } 20 | 21 | public int SlotEnd { get; set; } 22 | 23 | public long Id { get; set; } 24 | 25 | public DateTime HeartAt { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/Models/TaskServerOptions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Core.Models 8 | { 9 | public class TaskServerOptions 10 | { 11 | /// 12 | /// MQTT server 监听IP 13 | /// 14 | public string? Ip { get; set; } 15 | 16 | /// 17 | /// MQTT server 监听端口 18 | /// 19 | public int Port { get; set; } = 1883; 20 | 21 | /// 22 | /// MQTT server 外部访问地址 23 | /// 24 | public string? ExternalUrl { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Core/MyLog.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Logging; 8 | using MQTTnet.Diagnostics; 9 | 10 | namespace OpenTask.Application.Core 11 | { 12 | public class MyLog : IMqttNetLogger 13 | { 14 | private readonly ILogger logger; 15 | 16 | public MyLog(ILogger logger) 17 | { 18 | this.logger = logger; 19 | } 20 | 21 | public bool IsEnabled => true; 22 | 23 | public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception) 24 | { 25 | switch (logLevel) 26 | { 27 | case MqttNetLogLevel.Verbose: 28 | logger.LogTrace(message); 29 | break; 30 | case MqttNetLogLevel.Info: 31 | logger.LogInformation(message); 32 | break; 33 | case MqttNetLogLevel.Warning: 34 | logger.LogWarning(message); 35 | break; 36 | case MqttNetLogLevel.Error: 37 | logger.LogError(exception, message); 38 | break; 39 | default: 40 | break; 41 | } 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Dashboard/StatisticsRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | 9 | namespace OpenTask.Application.Dashboard 10 | { 11 | public class StatisticsRequest : ICommand 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Dashboard/StatisticsResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.Dashboard 8 | { 9 | public class StatisticsResponse 10 | { 11 | public required StatisticInfos TaskInfos { get; set; } 12 | 13 | public required StatisticInfos TaskLogs { get; set; } 14 | 15 | public required StatisticInfos Servers { get; set; } 16 | 17 | public required StatisticInfos Workers { get; set; } 18 | 19 | public class StatisticInfos 20 | { 21 | public long Count { get; set; } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Application/ExecutorClient.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Text.Json.Serialization; 8 | 9 | namespace OpenTask.Application 10 | { 11 | public class ExecutorClient 12 | { 13 | [JsonIgnore] 14 | public string? ServerId { get; set; } 15 | 16 | public required string GroupName { get; set; } 17 | 18 | public string? ConnectionId { get; set; } 19 | 20 | public IEnumerable? Handelrs { get; set; } 21 | 22 | public DateTime StartTime { get; set; } 23 | 24 | public required string ClientId { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Extensions/OpentaskExtensions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.DependencyInjection; 8 | using MQTTnet.Diagnostics; 9 | using OpenTask.Application.Core; 10 | using OpenTask.Application.Core.Interface; 11 | using OpenTask.Application.Services; 12 | 13 | namespace OpenTask.Application.Extensions 14 | { 15 | public static class OpentaskExtensions 16 | { 17 | public static IServiceCollection AddOpenTaskServer(this IServiceCollection services) 18 | { 19 | _ = services.AddTransient(); 20 | _ = services.AddTransient(); 21 | _ = services.AddTransient(); 22 | _ = services.AddTransient(); 23 | 24 | // Server是单例的,方便全局调用 25 | _ = services.AddSingleton(); 26 | _ = services.AddHostedService(); 27 | 28 | return services; 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Issue/MyIssueCommand.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Issue 9 | { 10 | public class MyIssueCommand : ICommand 11 | { 12 | public long UserId { get; set; } 13 | 14 | public long OrgId { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Issue/MyIssueHandler.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using OpenTask.Application.Base; 3 | using OpenTask.Domain.Workitems; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace OpenTask.Application.Issue 11 | { 12 | public class MyIssueHandler : ICommandHandler 13 | { 14 | IWorkitemRepository issueRepository; 15 | 16 | public MyIssueHandler(IWorkitemRepository issueRepository) 17 | { 18 | this.issueRepository = issueRepository; 19 | } 20 | 21 | public Task Handle(MyIssueCommand request, CancellationToken cancellationToken) 22 | { 23 | var res = issueRepository.MyIssue(request.OrgId, request.UserId); 24 | return Task.FromResult(new MyIssueResponse 25 | { 26 | Issues = res 27 | }); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Issue/MyIssueResponse.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Domain.Workitems; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Issue 9 | { 10 | public class MyIssueResponse 11 | { 12 | public IEnumerable Issues { get; internal set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/MediatRProfile.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application 8 | { 9 | public class MediatRProfile 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Members/GetMember/MemberHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using OpenTask.Application.Base.Commands; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace OpenTask.Application.Members.GetMember 10 | { 11 | public class MemberHandler : ICommandHandler 12 | { 13 | public Task Handle(MemberRequest request, CancellationToken cancellationToken) 14 | { 15 | throw new NotImplementedException(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Members/GetMember/MemberRequest.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Members.GetMember 9 | { 10 | public class MemberRequest : ICommand 11 | { 12 | public long AccountId { get; set; } 13 | 14 | public long OrganizationId { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Members/GetMember/MemberResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenTask.Application.Members.GetMember 8 | { 9 | public class MemberResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Members/ListMembers/ListMembersHandler.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Members.ListMembers 9 | { 10 | internal class ListMembersHandler : ICommandHandler 11 | { 12 | public Task Handle(ListMembersRequest request, CancellationToken cancellationToken) 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Members/ListMembers/ListMembersRequest.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Members.ListMembers 9 | { 10 | public class ListMembersRequest : ICommand 11 | { 12 | public long OrganizationId { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Members/ListMembers/ListMembersResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenTask.Application.Members.ListMembers 8 | { 9 | public class ListMembersResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Orgs/CreateOrganization/CreateOrganizationHandler.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using OpenTask.Application.Base.Commands; 3 | using OpenTask.Application.Members.ListMembers; 4 | using OpenTask.Domain.Organization; 5 | 6 | namespace OpenTask.Application.Orgs.CreateOrganization 7 | { 8 | public class CreateOrganizationHandler : ICommandHandler 9 | { 10 | readonly IOrganizationRepository teamRepository; 11 | IMapper mapper; 12 | 13 | public CreateOrganizationHandler(IOrganizationRepository teamRepository, IMapper mapper) 14 | { 15 | this.mapper = mapper; 16 | this.teamRepository = teamRepository; 17 | } 18 | 19 | public Task Handle(CreateOrganizationRequest request, CancellationToken cancellationToken) 20 | { 21 | var team = Organization.CreateTeam(request.Name, request.Description, request.UserId.Value); 22 | 23 | var id = teamRepository.Save(team); 24 | team.Id = id; 25 | 26 | return Task.FromResult(new CreateOrganizationResponse 27 | { 28 | TeamId = id 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Orgs/CreateOrganization/CreateOrganizationRequest.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using OpenTask.Application.Base.Commands; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace OpenTask.Application.Orgs.CreateOrganization 11 | { 12 | public class CreateOrganizationRequest : ICommand 13 | { 14 | public string Name { get; set; } 15 | 16 | public string Description { get; set; } 17 | 18 | public long? UserId { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Orgs/CreateOrganization/CreateOrganizationResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenTask.Application.Orgs.CreateOrganization 8 | { 9 | public class CreateOrganizationResponse 10 | { 11 | public long TeamId { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/OpenTask.Application/Orgs/ListOrg/ListOrgCommand.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Orgs.ListOrg 9 | { 10 | public class ListOrgCommand : ICommand 11 | { 12 | public long UserId { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Orgs/ListOrg/ListOrgCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using OpenTask.Application.Base; 3 | using OpenTask.Domain.Organization; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace OpenTask.Application.Orgs.ListOrg 11 | { 12 | public class ListOrgCommandHandler : ICommandHandler 13 | { 14 | IOrganizationRepository orgRepository; 15 | 16 | public ListOrgCommandHandler(IOrganizationRepository orgRepository) 17 | { 18 | this.orgRepository = orgRepository; 19 | } 20 | 21 | public Task Handle(ListOrgCommand request, CancellationToken cancellationToken) 22 | { 23 | var orgs = orgRepository.ListOrgForCurrentUser(request.UserId) ?? Enumerable.Empty(); 24 | 25 | return Task.FromResult(new ListOrgResponse 26 | { 27 | Orgs = orgs 28 | }); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Orgs/ListOrg/ListOrgResponse.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Domain.Organization; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Orgs.ListOrg 9 | { 10 | public class ListOrgResponse 11 | { 12 | public required IEnumerable Orgs { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Projects/CreateProject/CreateProjectHandler.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using OpenTask.Domain.Projects; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace OpenTask.Application.Projects.CreateProject 10 | { 11 | public class CreateProjectHandler : ICommandHandler 12 | { 13 | readonly IProjectRepository projectRepository; 14 | 15 | public CreateProjectHandler(IProjectRepository projectRepository) 16 | { 17 | this.projectRepository = projectRepository; 18 | } 19 | 20 | public Task Handle(CreateProjectRequest request, CancellationToken cancellationToken) 21 | { 22 | var project = Project.Create(request.OrganizationId, request.ProjectName, request.Describe, request.CreatedBy); 23 | 24 | var id = projectRepository.Save(project); 25 | 26 | project.Id = id; 27 | return Task.FromResult(new CreateProjectResponse 28 | { 29 | Project = project 30 | }); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Projects/CreateProject/CreateProjectRequest.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Commands; 2 | using OpenTask.Application.Base.Queries; 3 | using OpenTask.Application.Todos.GetTodoItems; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.ComponentModel.DataAnnotations; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Text.Json.Serialization; 10 | using System.Threading.Tasks; 11 | 12 | namespace OpenTask.Application.Projects.CreateProject 13 | { 14 | public class CreateProjectRequest : ICommand 15 | { 16 | [JsonIgnore] 17 | public long OrganizationId { get; set; } 18 | 19 | [JsonIgnore] 20 | public long CreatedBy { get; set; } 21 | 22 | public string ProjectName { get; set; } = null!; 23 | 24 | public string Describe { get; set; } = null!; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Projects/CreateProject/CreateProjectResponse.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Domain.Projects; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Projects.CreateProject 9 | { 10 | public class CreateProjectResponse 11 | { 12 | public Project Project { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Projects/ListProject/ListProjectHandler.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Queries; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Projects.ListProject 9 | { 10 | public class ListProjectHandler : IQueryHandler 11 | { 12 | public Task Handle(ListProjectRequest request, CancellationToken cancellationToken) 13 | { 14 | throw new NotImplementedException(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Projects/ListProject/ListProjectRequest.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Queries; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OpenTask.Application.Projects.ListProject 9 | { 10 | public class ListProjectRequest : IQuery 11 | { 12 | public long OrganizationId { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Projects/ListProject/ListProjectResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenTask.Application.Projects.ListProject 8 | { 9 | public class ListProjectResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/ProxyModel.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application 8 | { 9 | public class ProxyModel 10 | { 11 | public required string topic { get; set; } 12 | 13 | public required string data { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Services/CleanerBackgroundService.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace OpenTask.Application.Services 11 | { 12 | public class CleanerBackgroundService : BackgroundService 13 | { 14 | private readonly ILogger logger; 15 | 16 | public CleanerBackgroundService(ILogger logger) 17 | { 18 | this.logger = logger; 19 | } 20 | 21 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 22 | { 23 | while (!stoppingToken.IsCancellationRequested) 24 | { 25 | //logger.LogInformation($"now: {DateTime.Now.ToTimestamp()}"); 26 | await Task.Delay(1000); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Services/OpenTaskServerBackgroundService.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Hosting; 8 | using OpenTask.Application.Core.Interface; 9 | 10 | namespace OpenTask.Application.Services 11 | { 12 | public class OpenTaskServerBackgroundService : BackgroundService 13 | { 14 | private readonly ITaskServer server; 15 | 16 | public OpenTaskServerBackgroundService(ITaskServer server) 17 | { 18 | this.server = server; 19 | } 20 | 21 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 22 | { 23 | await server.StartAsync(stoppingToken); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/AddTaskRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | using OpenTask.Domain.TaskInfos; 9 | 10 | namespace OpenTask.Application.TaskInfos 11 | { 12 | public class AddTaskRequest : ICommand 13 | { 14 | public required TaskInfo Task { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/AddTaskResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.TaskInfos 8 | { 9 | public class AddTaskResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/DeleteTaskRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | 9 | namespace OpenTask.Application.TaskInfos 10 | { 11 | public class DeleteTaskRequest : ICommand 12 | { 13 | public long TaskId { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/DeleteTaskResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.TaskInfos 8 | { 9 | public class DeleteTaskResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/ExcuteOnceRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | 9 | namespace OpenTask.Application.TaskInfos 10 | { 11 | public class ExcuteOnceRequest : ICommand 12 | { 13 | public long TaskId { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/ExcuteOnceResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.TaskInfos 8 | { 9 | public class ExcuteOnceResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/GetNext5TriggertimesRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | 9 | namespace OpenTask.Application.TaskInfos 10 | { 11 | public class GetNext5TriggertimesRequest : ICommand 12 | { 13 | public long TaskId { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/GetNext5TriggertimesResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.TaskInfos 8 | { 9 | public class GetNext5TriggertimesResponse 10 | { 11 | public required IEnumerable NextTriggers { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/ListTaskInfosRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using OpenTask.Application.Base; 9 | 10 | namespace OpenTask.Application.TaskInfos 11 | { 12 | public class ListTaskInfosRequest : PageQuery, IRequest 13 | { 14 | public string? Name { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/ListTaskInfosResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base; 8 | using OpenTask.Domain.TaskInfos; 9 | 10 | namespace OpenTask.Application.TaskInfos 11 | { 12 | public class ListTaskInfosResponse : PageResponse 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/SwitchTaskStatusRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | 9 | namespace OpenTask.Application.TaskInfos 10 | { 11 | public class SwitchTaskStatusRequest : ICommand 12 | { 13 | public long TaskId { get; set; } 14 | 15 | public bool Enabled { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/SwitchTaskStatusResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.TaskInfos 8 | { 9 | public class SwitchTaskStatusResponse 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/TaskInfoRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | 9 | namespace OpenTask.Application.TaskInfos 10 | { 11 | public class TaskInfoRequest : ICommand 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskInfos/TaskInfoResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.TaskInfos; 8 | 9 | namespace OpenTask.Application.TaskInfos 10 | { 11 | public class TaskInfoResponse 12 | { 13 | public required TaskInfo TaskInfo { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskLogs/LisTaskLogsRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using OpenTask.Application.Base; 9 | 10 | namespace OpenTask.Application.TaskLogs 11 | { 12 | public class LisTaskLogsRequest : PageQuery, IRequest 13 | { 14 | public long? TaskId { get; set; } 15 | 16 | public DateTime? StartTime { get; set; } 17 | 18 | public DateTime? EndTime { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskLogs/LisTaskLogsResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base; 8 | using OpenTask.Domain.TaskLogs; 9 | 10 | namespace OpenTask.Application.TaskLogs 11 | { 12 | public class LisTaskLogsResponse : PageResponse 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskLogs/ListTopTaskLogRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using System.ComponentModel.DataAnnotations; 9 | 10 | namespace OpenTask.Application.TaskLogs 11 | { 12 | public class ListTopTaskLogRequest : IRequest 13 | { 14 | [Required] 15 | public DateTime Start { get; set; } 16 | 17 | [Required] 18 | public DateTime End { get; set; } 19 | 20 | [Range(1, 30)] 21 | public int Count { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskLogs/ListTopTaskLogResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.TaskLogs; 8 | 9 | namespace OpenTask.Application.TaskLogs 10 | { 11 | public class ListTopTaskLogResponse 12 | { 13 | public required IEnumerable Data { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskLogs/TaskLogsDayTrendRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | 9 | namespace OpenTask.Application.TaskLogs 10 | { 11 | /// 12 | /// 调度日志 日走势 13 | /// 14 | public class TaskLogsDayTrendRequest : IRequest 15 | { 16 | public DateTime Start { get; set; } 17 | 18 | public DateTime End { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/OpenTask.Application/TaskLogs/TaskLogsDayTrendResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.TaskLogs; 8 | 9 | namespace OpenTask.Application.TaskLogs 10 | { 11 | public class TaskLogsDayTrendResponse 12 | { 13 | public required IEnumerable data { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Todos/GetTodoItems/GetTodoItemsQuery.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Queries; 2 | 3 | namespace OpenTask.Application.Todos.GetTodoItems 4 | { 5 | public class GetTodoItemsQuery : IQuery 6 | { 7 | public long Id { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Todos/GetTodoItems/GetTodoItemsQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using OpenTask.Application.Base.Queries; 2 | using OpenTask.Domain.TodoItems; 3 | 4 | namespace OpenTask.Application.Todos.GetTodoItems 5 | { 6 | public class GetTodoItemsQueryHandler : IQueryHandler 7 | { 8 | readonly ITodoItemRepository todoItemRepository; 9 | 10 | public GetTodoItemsQueryHandler(ITodoItemRepository todoItemRepository) 11 | { 12 | this.todoItemRepository = todoItemRepository; 13 | } 14 | 15 | public Task Handle(GetTodoItemsQuery request, CancellationToken cancellationToken) 16 | { 17 | var res = todoItemRepository.Find(request.Id); 18 | 19 | return Task.FromResult(new TodoItemResponse 20 | { 21 | TodoInfo = new TodoDto 22 | { 23 | Id = request.Id, 24 | Summary = res.Summary, 25 | Title = res.Title, 26 | }, 27 | }); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Todos/GetTodoItems/TodoDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenTask.Application.Todos.GetTodoItems 8 | { 9 | public class TodoDto 10 | { 11 | public long Id { get; set; } 12 | 13 | public string Title { get; set; } 14 | 15 | public string Summary { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Application/Todos/GetTodoItems/TodoItemResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenTask.Application.Todos.GetTodoItems 8 | { 9 | public class TodoItemResponse 10 | { 11 | public TodoDto TodoInfo { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OpenTask.Application/User/Login/LoginCommand.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base.Commands; 8 | using System.ComponentModel.DataAnnotations; 9 | 10 | 11 | namespace OpenTask.Application.User.Login 12 | { 13 | public class LoginCommand : ICommand 14 | { 15 | [Required] 16 | public string UserName { get; set; } = null!; 17 | 18 | [Required] 19 | public string Password { get; set; } = null!; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/OpenTask.Application/User/Login/LoginResponse.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Application.User.Login 8 | { 9 | public class LoginResponse 10 | { 11 | public required string Token { get; set; } 12 | 13 | //public IEnumerable Teams { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Client/Handlers/DemoJobHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Core.Base; 8 | using OpenTask.Core.Models; 9 | 10 | namespace OpenTask.Client.Handlers 11 | { 12 | internal class DemoJobHandler : ITaskHandler 13 | { 14 | public Task RunAsync(TaskContext context) 15 | { 16 | Console.WriteLine($"执行参数:{context.TaskInfo.JobParams}"); 17 | Console.WriteLine("DemoJob"); 18 | Thread.Sleep(2000); 19 | return Task.CompletedTask; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/OpenTask.Client/Handlers/JobHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Core.Base; 8 | using OpenTask.Core.Models; 9 | 10 | namespace OpenTask.Client.Handlers 11 | { 12 | internal class JobHandler : ITaskHandler 13 | { 14 | public Task RunAsync(TaskContext context) 15 | { 16 | Console.WriteLine("Job"); 17 | Thread.Sleep(20000); 18 | 19 | return Task.CompletedTask; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/OpenTask.Client/OpenTask.Client.Sample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/OpenTask.Client/Program.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Hosting; 8 | using OpenTask.Client.Handlers; 9 | using OpenTask.Core.Extensions; 10 | using Serilog; 11 | 12 | namespace OpenTask.Client 13 | { 14 | internal class Program 15 | { 16 | private const string outputTemplate = "[{Timestamp:HH:mm:ss.fff} {TraceId} {Level:u3}] {Message:lj}{NewLine}{Exception}"; 17 | public static void Main(string[] args) 18 | { 19 | IHost host = Host.CreateDefaultBuilder(args) 20 | .ConfigureServices((ctx, services) => 21 | { 22 | _ = services.AddOpenTaskWorker(ctx.Configuration.GetSection("OpenTaskWorker"), options => 23 | { 24 | options.AddHandler(); 25 | options.AddHandler(); 26 | }); 27 | }).UseSerilog((context, configuration) => 28 | { 29 | _ = configuration.WriteTo.Console(Serilog.Events.LogEventLevel.Debug, outputTemplate: outputTemplate); 30 | }) 31 | .Build(); 32 | 33 | host.Run(); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/OpenTask.Client/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Scheduler.Client": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "https://localhost:55967;http://localhost:55968" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/OpenTask.Client/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.Hosting.Lifetime": "Information" 6 | } 7 | }, 8 | "OpenTaskWorker": { 9 | //"Addr": [ "127.0.0.1:1883" ], 10 | "Addr": [ "101.37.166.120:1883" ], 11 | "AppName": "default" // 不能用汉字 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Base/IOpenTaskWorker.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Core.Models; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace OpenTask.Core.Base 12 | { 13 | public interface IOpenTaskWorker 14 | { 15 | Task DoTaskAsync(OnTaskRequest job); 16 | 17 | Task RunAsync(CancellationToken cancellationToken); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Base/ITaskHandler.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Core.Models; 8 | using System.Threading.Tasks; 9 | 10 | namespace OpenTask.Core.Base 11 | { 12 | public interface ITaskHandler 13 | { 14 | public Task RunAsync(TaskContext context); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Core/ConstString.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Core 8 | { 9 | public class ConstString 10 | { 11 | public const string LOGO = """ 12 | ____ _______ _ 13 | / __ \ |__ __| | | 14 | | | | | _ __ ___ _ __ | | __ _ ___ | | __ 15 | | | | || '_ \ / _ \| '_ \ | | / _` |/ __|| |/ / 16 | | |__| || |_) || __/| | | || || (_| |\__ \| < 17 | \____/ | .__/ \___||_| |_||_| \__,_||___/|_|\_\ 18 | | | 19 | |_| 20 | """; 21 | 22 | public static class UserProperties 23 | { 24 | public const string APP_NAME = "app-name"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Models/BaseMassageAgrs.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Core.Models 8 | { 9 | public abstract class BaseMassageAgrs 10 | { 11 | public string? MsgId { get; set; } 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Models/HandlerRegister.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.DependencyInjection; 8 | using OpenTask.Core.Base; 9 | using System; 10 | using System.Collections.Generic; 11 | 12 | namespace OpenTask.Core.Models 13 | { 14 | public class HandlerRegister 15 | { 16 | private readonly IServiceCollection services; 17 | 18 | public HandlerRegister(IServiceCollection services) 19 | { 20 | this.services = services; 21 | } 22 | 23 | internal Dictionary handlers = []; 24 | 25 | public void AddHandler() 26 | where T : class, ITaskHandler 27 | { 28 | _ = services.AddTransient(); 29 | handlers.Add(typeof(T).Name, typeof(T)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Models/MqttConsleLogger.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MQTTnet.Diagnostics; 8 | using System; 9 | 10 | namespace OpenTask.Core.Models 11 | { 12 | public class MqttConsleLogger : IMqttNetLogger 13 | { 14 | public bool IsEnabled => true; 15 | 16 | public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception) 17 | { 18 | switch (logLevel) 19 | { 20 | case MqttNetLogLevel.Verbose: 21 | break; 22 | case MqttNetLogLevel.Info: 23 | Console.WriteLine(message); 24 | break; 25 | case MqttNetLogLevel.Warning: 26 | Console.WriteLine(message); 27 | break; 28 | case MqttNetLogLevel.Error: 29 | Console.WriteLine(message); 30 | break; 31 | default: 32 | break; 33 | } 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Models/OnTaskRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | 8 | namespace OpenTask.Core.Models 9 | { 10 | public class OnTaskRequest : BaseMassageAgrs 11 | { 12 | public TodoTask? Job { get; set; } 13 | 14 | public bool Success { get; set; } 15 | 16 | public string? ErrMsg { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Models/OpenWorkerOptions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | 8 | using System; 9 | using System.ComponentModel.DataAnnotations; 10 | 11 | namespace OpenTask.Core.Models 12 | { 13 | public class OpenWorkerOptions 14 | { 15 | [Required] 16 | public string[]? Addr { get; set; } 17 | 18 | public string? ClientId { get; set; } 19 | 20 | [Required] 21 | public string? AppName { get; set; } 22 | 23 | public string? Token { get; set; } 24 | 25 | internal void Validate() 26 | { 27 | if (Addr == null) 28 | { 29 | throw new ArgumentNullException("配置 Addr 不可为空"); 30 | } 31 | 32 | if (Addr.Length > 1) 33 | { 34 | throw new ArgumentNullException("Addr 尚不支持配置多个地址,请删除多余的"); 35 | } 36 | 37 | foreach (var item in Addr) 38 | { 39 | // 检查地址格式 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Models/TaskContext.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Threading; 8 | 9 | namespace OpenTask.Core.Models 10 | { 11 | public class TaskContext 12 | { 13 | public TaskContext(TodoTask task) 14 | { 15 | TaskInfo = task; 16 | } 17 | 18 | ///// 19 | ///// 取消任务的令牌 20 | ///// 21 | //public CancellationToken CancellationToken { get; internal set; } = CancellationToken.None; 22 | 23 | /// 24 | /// 任务信息 25 | /// 26 | public TodoTask TaskInfo { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OpenTask.Core/OpenTask.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461;net5.0 5 | true 6 | true 7 | preview 8 | enable 9 | https://github.com/SpringHgui/OpenTask 10 | https://github.com/SpringHgui/OpenTask 11 | README.md 12 | 13 | 14 | 15 | 16 | True 17 | \ 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/OpenTask.Core/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Scheduler.Core": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "https://localhost:55969;http://localhost:55970" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/OpenTask.Core/Services/OpenTaskWorkerBackgroundService.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using OpenTask.Core.Base; 10 | using System.Threading; 11 | using System.Threading.Tasks; 12 | 13 | namespace OpenTask.Core.Services; 14 | 15 | public class OpenTaskWorkerBackgroundService : BackgroundService 16 | { 17 | private readonly ILogger _logger; 18 | private readonly TaskWorker taskWorker; 19 | 20 | public OpenTaskWorkerBackgroundService(ILogger logger, TaskWorker jobExecutor) 21 | { 22 | _logger = logger; 23 | taskWorker = jobExecutor; 24 | } 25 | 26 | protected override async Task ExecuteAsync(CancellationToken stoppingToken) 27 | { 28 | await taskWorker.RunAsync(stoppingToken); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenTask.Domain.Tests/OpenTask.Domain.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Base/Types/Identifier.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Base.Types 8 | { 9 | //public class Identifier : IIdentifier 10 | //{ 11 | // public Identifier(long id) 12 | // { 13 | // if (id <= 0) 14 | // { 15 | // throw new ArgumentOutOfRangeException("id"); 16 | // } 17 | 18 | // this.Value = id; 19 | // } 20 | 21 | // public long Value { get; private set; } 22 | //} 23 | } 24 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Base/Types/TeamId.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Base.Types 8 | { 9 | internal class TeamId 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Base/Types/TeamName.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Base.Types 8 | { 9 | public class TeamName 10 | { 11 | public TeamName(string name) 12 | { 13 | if (string.IsNullOrEmpty(name)) 14 | { 15 | throw new ArgumentNullException("name"); 16 | } 17 | 18 | if (name.Length >= 20) 19 | { 20 | throw new ArgumentOutOfRangeException(nameof(name), name.Length, "超长"); 21 | } 22 | 23 | Name = name; 24 | } 25 | 26 | public string Name { get; private set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Base/Types/UserName.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Base.Types 8 | { 9 | public class UserName 10 | { 11 | public UserName(string name) 12 | { 13 | 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Lockers/ILockerRepository.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.Base.Repositorys; 8 | 9 | namespace OpenTask.Domain.Lockers 10 | { 11 | public interface ILockerRepository : IRepository 12 | { 13 | Locker FindByKey(string resource); 14 | 15 | bool NewLocker(string key, string lockerby, out Locker? locker); 16 | 17 | bool UpdateLocker(string key, string lockerby, int currentVersion); 18 | 19 | bool ReEnterLocker(string key, string lockerby, int currentVersion); 20 | 21 | bool ReleaseLocker(string key, string lockerby); 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Lockers/Locker.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Lockers 8 | { 9 | public class Locker 10 | { 11 | public string Resource { get; set; } = null!; 12 | 13 | public int Version { get; set; } 14 | 15 | public bool Locked { get; set; } 16 | 17 | public DateTime LockedAt { get; set; } 18 | 19 | public string LockedBy { get; set; } = null!; 20 | 21 | /// 22 | /// 默认超过多久视为无效 23 | /// 24 | public bool IsExpired(int secd) 25 | { 26 | return (DateTime.Now - LockedAt).TotalSeconds > secd; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/OpenTask.Domain.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Servers/IServerRepository.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.Base.Repositorys; 8 | 9 | namespace OpenTask.Domain.Servers 10 | { 11 | public interface IServerRepository : IRepository 12 | { 13 | IEnumerable GetServerOnline(int v); 14 | 15 | void RegisterOrUpdate(OpenTaskServer server); 16 | 17 | void UpdateSlot(IEnumerable enumerable); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Servers/OpenTaskServer.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Servers 8 | { 9 | public class OpenTaskServer 10 | { 11 | public long Id { get; set; } 12 | 13 | public string ServerId { get; set; } = null!; 14 | 15 | public string EndPoint { get; set; } = null!; 16 | 17 | public DateTime HeartAt { get; set; } 18 | 19 | public int SlotFrom { get; set; } 20 | 21 | public int SlotEnd { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskInfos/ITaskInfoRepository.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.Base.Repositorys; 8 | 9 | namespace OpenTask.Domain.TaskInfos 10 | { 11 | public interface ITaskInfoRepository : IRepository 12 | { 13 | TaskInfo AddJob(TaskInfo model); 14 | 15 | void DelJob(long jobId); 16 | 17 | TaskInfoBaseStatistics GetBaseStatistics(); 18 | 19 | TaskInfo GetJob(long jobId); 20 | 21 | IEnumerable GetNextJob(string guid, long timeStamp); 22 | 23 | IEnumerable ListJobs(int pageNumber, int pageSize, string? name, out long count); 24 | 25 | bool SwitchEnabledStatus(long jobId, bool enbaled); 26 | 27 | bool UpdateNextTriggerTime(long id, long last, long next); 28 | 29 | void UpdateParallelCount(long jobId, int v); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskInfos/TaskInfoBaseStatistics.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.TaskInfos 8 | { 9 | public class TaskInfoBaseStatistics 10 | { 11 | public long Enabled { get; set; } 12 | 13 | public long Total { get; set; } 14 | 15 | public long Disabled => Total - Enabled; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskInfos/TaskLogStatus.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.ComponentModel; 8 | 9 | namespace OpenTask.Domain.TaskInfos 10 | { 11 | [Flags] 12 | public enum TaskLogStatus : int 13 | { 14 | [Description("初始化")] 15 | Inited = 0, 16 | 17 | [Description("执行中")] 18 | Process = 1, 19 | 20 | [Description("成功")] 21 | SUCCESS = 2, 22 | 23 | [Description("失败")] 24 | FAIL = 3, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskLogs/ITaskLogRepository.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.Base.Repositorys; 8 | 9 | namespace OpenTask.Domain.TaskLogs 10 | { 11 | public interface ITaskLogRepository : IRepository 12 | { 13 | TaskLog AddTask(TaskLog task); 14 | 15 | TaskLogBaseStatistics GetBaseStatistics(); 16 | 17 | IEnumerable GetDayTrend(DateTime start, DateTime end); 18 | 19 | TaskLog? GetTaskById(long taskId); 20 | 21 | IEnumerable LisTasks(int pageNumber, int pageSize, long? jobId, DateTime? startTime, DateTime? endTime, out long count); 22 | 23 | void Update(TaskLog task); 24 | 25 | void UpdateTaskFlag(long taskId, int process); 26 | 27 | IEnumerable GetTopTaskLog(DateTime start, DateTime end, int count); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskLogs/TaskLog.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.TaskLogs 8 | { 9 | public class TaskLog 10 | { 11 | public long Id { get; set; } 12 | 13 | public long TaskId { get; set; } 14 | 15 | public DateTime? HandleStart { get; set; } 16 | 17 | public DateTime? HandleEnd { get; set; } 18 | 19 | public string HandleResult { get; set; } = ""; 20 | 21 | public sbyte HandleStatus { get; set; } 22 | 23 | public string HandleClient { get; set; } = ""; 24 | 25 | public int AlarmStatus { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskLogs/TaskLogBaseStatistics.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.TaskLogs 8 | { 9 | public class TaskLogBaseStatistics 10 | { 11 | public long Total { get; set; } 12 | 13 | public long Success { get; set; } 14 | 15 | public long Fail { get; set; } 16 | 17 | public long Process { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskLogs/TaskLogDayTrend.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.TaskLogs 8 | { 9 | public class TaskLogDayTrend 10 | { 11 | public required string Day { get; set; } 12 | 13 | public int Total { get; set; } 14 | 15 | public int Success { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/TaskLogs/TopTaskLog.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.TaskLogs 8 | { 9 | public class TopTaskLog 10 | { 11 | public long TaskId { get; set; } 12 | 13 | public required string Name { get; set; } 14 | 15 | public string? Description { get; set; } 16 | 17 | public long Count { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Users/CurrentUser.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Domain.Users 8 | { 9 | public class CurrentUser 10 | { 11 | public required long UserId { get; set; } 12 | 13 | public required string UserName { get; set; } 14 | 15 | //public required IEnumerable Teams { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Domain/Users/IUserRepository.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Domain.Base.Repositorys; 8 | 9 | namespace OpenTask.Domain.Users 10 | { 11 | public interface IUserRepository : IRepository 12 | { 13 | User? FindByUserName(string email); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/AutoMapperProfile.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using AutoMapper; 8 | using OpenTask.Domain.Lockers; 9 | using OpenTask.Domain.Servers; 10 | using OpenTask.Domain.TaskInfos; 11 | using OpenTask.Domain.TaskLogs; 12 | using OpenTask.Domain.Users; 13 | using OpenTask.Persistence.Entitys; 14 | using OpenTask.Persistence.Models; 15 | 16 | namespace OpenTask.Persistence 17 | { 18 | public class AutoMapperProfile : Profile 19 | { 20 | public AutoMapperProfile() 21 | { 22 | _ = CreateMap().ReverseMap(); 23 | _ = CreateMap().ReverseMap(); 24 | _ = CreateMap().ReverseMap(); 25 | _ = CreateMap().ReverseMap(); 26 | _ = CreateMap().ReverseMap(); 27 | 28 | _ = CreateMap(); 29 | _ = CreateMap(); 30 | _ = CreateMap(); 31 | _ = CreateMap(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Base/CustomColumnNameResolver.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Dommel; 8 | using System.Reflection; 9 | using System.Text.Json; 10 | 11 | namespace OpenTask.Persistence.Base 12 | { 13 | public class CustomColumnNameResolver : IColumnNameResolver 14 | { 15 | public string ResolveColumnName(PropertyInfo propertyInfo) 16 | { 17 | // Every column has prefix 'fld' and is uppercase. 18 | JsonNamingPolicy namingPolicy = JsonNamingPolicy.SnakeCaseLower; 19 | string snakeCaseString = namingPolicy.ConvertName(propertyInfo.Name); 20 | 21 | return snakeCaseString; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Base/CustomKeyPropertyResolver.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Dommel; 8 | 9 | namespace OpenTask.Persistence.Base 10 | { 11 | public class CustomKeyPropertyResolver : IKeyPropertyResolver 12 | { 13 | public ColumnPropertyInfo[] ResolveKeyProperties(Type type) 14 | { 15 | return new[] { new ColumnPropertyInfo(type.GetProperties().Single(p => p.Name == $"{type.Name}Id"), isKey: true) }; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Base/CustomTableNameResolver.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Dommel; 8 | using System.Text.Json; 9 | 10 | namespace OpenTask.Persistence.Base 11 | { 12 | public class CustomTableNameResolver : ITableNameResolver 13 | { 14 | public string ResolveTableName(Type type) 15 | { 16 | string camelCaseString = type.Name; 17 | 18 | JsonNamingPolicy namingPolicy = JsonNamingPolicy.SnakeCaseLower; 19 | string snakeCaseString = namingPolicy.ConvertName(camelCaseString); 20 | 21 | return snakeCaseString; // $"{snakeCaseString.Replace("_entity", string.Empty)}"; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/DesignTimeDbContextFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.EntityFrameworkCore.Design; 8 | using Microsoft.EntityFrameworkCore; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using OpenTask.Persistence.Contexts; 15 | 16 | namespace OpenTask.Persistence 17 | { 18 | public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory 19 | { 20 | public OpenTaskContext CreateDbContext(string[] args) 21 | { 22 | var optionsBuilder = new DbContextOptionsBuilder(); 23 | optionsBuilder.UseMySQL("Data Source=opentask.db"); 24 | 25 | return new OpenTaskContext(optionsBuilder.Options); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Entitys/OtLocker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace OpenTask.Persistence.Entitys; 8 | 9 | [Table("ot_locker")] 10 | public partial class OtLocker 11 | { 12 | /// 13 | /// 资源唯唯一标识 14 | /// 15 | [Key] 16 | [Column("resource")] 17 | [StringLength(64)] 18 | public string Resource { get; set; } = null!; 19 | 20 | /// 21 | /// 资源版本号 22 | /// 23 | [Column("version")] 24 | public int Version { get; set; } 25 | 26 | /// 27 | /// 加锁者 28 | /// 29 | [Column("locked_by")] 30 | [StringLength(64)] 31 | public string LockedBy { get; set; } = null!; 32 | 33 | /// 34 | /// 获取锁的开始时间 35 | /// 36 | [Column("locked_at", TypeName = "datetime")] 37 | public DateTime LockedAt { get; set; } 38 | } 39 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Entitys/OtServer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace OpenTask.Persistence.Entitys; 8 | 9 | [Table("ot_server")] 10 | [Index("ServerId", Name = "idx_server_id", IsUnique = true)] 11 | public partial class OtServer 12 | { 13 | /// 14 | /// 自增主键 15 | /// 16 | [Key] 17 | [Column("id")] 18 | public long Id { get; set; } 19 | 20 | /// 21 | /// server唯一标识 22 | /// 23 | [Column("server_id")] 24 | [StringLength(128)] 25 | public string ServerId { get; set; } = null!; 26 | 27 | /// 28 | /// 集群内部访问地址 29 | /// 30 | [Column("end_point")] 31 | [StringLength(64)] 32 | public string EndPoint { get; set; } = null!; 33 | 34 | /// 35 | /// 最后一次心跳时间 36 | /// 37 | [Column("heart_at", TypeName = "datetime")] 38 | public DateTime HeartAt { get; set; } 39 | 40 | /// 41 | /// 0~16383 42 | /// 43 | [Column("slot_from")] 44 | public int SlotFrom { get; set; } 45 | 46 | /// 47 | /// 0~16383 48 | /// 49 | [Column("slot_end")] 50 | public int SlotEnd { get; set; } 51 | } 52 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Entitys/OtTaskLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace OpenTask.Persistence.Entitys; 8 | 9 | [Table("ot_task_log")] 10 | [Index("TaskId", Name = "idx_task_id")] 11 | public partial class OtTaskLog 12 | { 13 | /// 14 | /// 自增主键 15 | /// 16 | [Key] 17 | [Column("id")] 18 | public long Id { get; set; } 19 | 20 | /// 21 | /// 任务id(taskinfo表主键) 22 | /// 23 | [Column("task_id")] 24 | public long TaskId { get; set; } 25 | 26 | /// 27 | /// 处理开始时间 28 | /// 29 | [Column("handle_start", TypeName = "datetime")] 30 | public DateTime? HandleStart { get; set; } 31 | 32 | /// 33 | /// 处理结果 34 | /// 35 | [Column("handle_result")] 36 | [StringLength(255)] 37 | public string HandleResult { get; set; } = null!; 38 | 39 | /// 40 | /// 处理状态 41 | /// 42 | [Column("handle_status")] 43 | public sbyte HandleStatus { get; set; } 44 | 45 | /// 46 | /// 处理任务客户端id 47 | /// 48 | [Column("handle_client")] 49 | [StringLength(128)] 50 | public string HandleClient { get; set; } = null!; 51 | 52 | /// 53 | /// 报警状态 0-默认、1-无需告警、2-告警成功、3-告警失败 54 | /// 55 | [Column("alarm_status")] 56 | public sbyte AlarmStatus { get; set; } 57 | } 58 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Entitys/OtUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace OpenTask.Persistence.Entitys; 8 | 9 | [Table("ot_user")] 10 | [Index("UserName", Name = "idx_user_name", IsUnique = true)] 11 | public partial class OtUser 12 | { 13 | /// 14 | /// 用户id 15 | /// 16 | [Key] 17 | [Column("id")] 18 | public int Id { get; set; } 19 | 20 | /// 21 | /// 用户名 22 | /// 23 | [Column("user_name")] 24 | [StringLength(128)] 25 | public string UserName { get; set; } = null!; 26 | 27 | /// 28 | /// 密码 29 | /// 30 | [Column("password")] 31 | [StringLength(255)] 32 | public string Password { get; set; } = null!; 33 | 34 | /// 35 | /// 创建时间 36 | /// 37 | [Column("created_at", TypeName = "datetime")] 38 | public DateTime CreatedAt { get; set; } 39 | } 40 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Extensions/DapperDBContextOptions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Options; 8 | 9 | namespace OpenTask.Persistence.Extensions 10 | { 11 | public class DapperdbContextOptions : IOptions 12 | { 13 | public required string Configuration { get; set; } 14 | 15 | public required DapperdbContextOptions Value { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Extensions/DapperDbContext.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.Options; 8 | using MySql.Data.MySqlClient; 9 | using System.Data; 10 | 11 | namespace OpenTask.Persistence.Extensions 12 | { 13 | public class DapperdbContext 14 | { 15 | protected DapperdbContextOptions options; 16 | 17 | public DapperdbContext(IOptions optionsAccessor) 18 | { 19 | options = optionsAccessor.Value; 20 | } 21 | 22 | public IDbConnection CreateConnection() => new MySqlConnection(options.Configuration); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Models/InjectAttribute.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.Extensions.DependencyInjection; 8 | 9 | namespace OpenTask.Persistence.Models 10 | { 11 | public class InjectAttribute : Attribute 12 | { 13 | private readonly ServiceLifetime lifetime; 14 | 15 | public InjectAttribute(ServiceLifetime Lifetime = ServiceLifetime.Transient) 16 | { 17 | lifetime = Lifetime; 18 | } 19 | 20 | public ServiceLifetime GetServiceLifetime() 21 | { 22 | return lifetime; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Models/TaskInfoBaseStatisticsDbModel.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.ComponentModel.DataAnnotations.Schema; 8 | 9 | namespace OpenTask.Persistence.Models 10 | { 11 | public class TaskInfoBaseStatisticsDbModel 12 | { 13 | [Column("enabled")] 14 | public long Enabled { get; set; } 15 | 16 | [Column("total")] 17 | public long Total { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Models/TaskLogBaseStatisticsDbModel.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.ComponentModel.DataAnnotations.Schema; 8 | 9 | namespace OpenTask.Persistence.Models 10 | { 11 | public class TaskLogBaseStatisticsDbModel 12 | { 13 | [Column("total")] 14 | public long Total { get; set; } 15 | 16 | [Column("success")] 17 | public long Success { get; set; } 18 | 19 | [Column("fail")] 20 | public long Fail { get; set; } 21 | 22 | [Column("process")] 23 | public long Process { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Models/TaskLogDayTrendDbModel.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Persistence.Models 8 | { 9 | public class TaskLogDayTrendDbModel 10 | { 11 | public required string Day { get; set; } 12 | 13 | public int Total { get; set; } 14 | 15 | public int Success { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Models/TopTaskLogDbModel.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.ComponentModel.DataAnnotations.Schema; 8 | 9 | namespace OpenTask.Persistence.Models 10 | { 11 | public class TopTaskLogDbModel 12 | { 13 | [Column("task_id")] 14 | public long TaskId { get; set; } 15 | 16 | public required string Name { get; set; } 17 | 18 | public string? Description { get; set; } 19 | 20 | public long Count { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/OpenTask.Persistence/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | dotnet tool install --global dotnet-ef 3 | dotnet tool update dotnet-ef 4 | 5 | db first 6 | ``` 7 | dotnet ef dbcontext scaffold "server=127.0.0.1;Port=3306;user id=root;database=open_task;pooling=true;password=OPEN_TASK_!@#;" MySql.EntityFrameworkCore --schema open_task --context-dir Contexts --output-dir Entitys --no-onconfiguring -d --no-build --force 8 | ``` 9 | 10 | code first 11 | https://learn.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli 12 | 13 | ``` 14 | dotnet ef migrations add InitialCreate 15 | dotnet ef database update 16 | 17 | dotnet ef migrations remove 18 | ``` -------------------------------------------------------------------------------- /src/OpenTask.Publisher/Class1.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Publisher 8 | { 9 | public class Class1 10 | { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OpenTask.Publisher/OpenTask.Publisher.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/Converters/DateTimeConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Text.Json; 8 | using System.Text.Json.Serialization; 9 | 10 | namespace OpenTask.Utility.Converters 11 | { 12 | public class DateTimeConverter : JsonConverter 13 | { 14 | public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 15 | { 16 | return reader.GetDateTime(); 17 | } 18 | 19 | public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) 20 | { 21 | writer.WriteStringValue(value.ToString("yyyy-MM-dd:HH:mm:ss")); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/Converters/JsonLongConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Text.Json; 8 | using System.Text.Json.Serialization; 9 | 10 | namespace OpenTask.Utility.Converters 11 | { 12 | public class JsonLongConverter : JsonConverter 13 | { 14 | public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 15 | { 16 | return reader.TokenType == JsonTokenType.String ? long.Parse(reader.GetString()) : reader.GetInt64(); 17 | } 18 | 19 | public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) 20 | { 21 | writer.WriteStringValue(value.ToString()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/Extensions/DateTimeExtensions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Utility.Extensions 8 | { 9 | public static class DateTimeExtensions 10 | { 11 | /// 12 | /// 转时间戳 13 | /// 14 | /// DateTime 对象 15 | /// 16 | /// 默认true 17 | /// true 秒级 18 | /// false 毫秒级 19 | /// 20 | public static long ToTimestamp(this DateTime date, bool is10bitSec = true) 21 | { 22 | TimeSpan timeSpan = date.ToUniversalTime() - new DateTime(1970, 1, 1); 23 | return is10bitSec ? (long)timeSpan.TotalSeconds : (long)timeSpan.TotalMilliseconds; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/Extensions/LongExtensions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.Utility.Extensions 8 | { 9 | public static class LongExtensions 10 | { 11 | public static DateTime ToDateTime(this long time) 12 | { 13 | // todo 14 | return DateTime.Now; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/Helpers/CrontabUtility.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using TimeCrontab; 8 | 9 | namespace OpenTask.Utility.Helpers 10 | { 11 | public class CrontabUtility 12 | { 13 | public static Crontab Parse(string TimeExpression) 14 | { 15 | int len = TimeExpression.Trim().Split(" ").Length; 16 | CronStringFormat cronStringFormat = len == 6 17 | ? CronStringFormat.WithSeconds 18 | : len == 7 ? CronStringFormat.WithSecondsAndYears : throw new ArgumentException($"表达式错误: {TimeExpression}"); 19 | Crontab crontab = Crontab.Parse(TimeExpression, cronStringFormat); 20 | return crontab; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/Helpers/Md5Helper.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Security.Cryptography; 8 | using System.Text; 9 | 10 | namespace OpenTask.Utility.Helpers 11 | { 12 | public class Md5Helper 13 | { 14 | public static string MD5Encrypt64(string password) 15 | { 16 | string cl = $"BaoXin{password}KeJi"; 17 | MD5 md5 = MD5.Create(); 18 | byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl)); 19 | return Convert.ToBase64String(s); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/OpenTask.Utility/OpenTask.Utility.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi.Tests/CustomWebApplicationFactory.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.AspNetCore.Mvc.Testing; 8 | 9 | namespace OpenTask.WebApi.Tests; 10 | 11 | public class CustomWebApplicationFactory 12 | : WebApplicationFactory where TProgram : class 13 | { 14 | protected override void ConfigureWebHost(IWebHostBuilder builder) 15 | { 16 | _ = builder.ConfigureServices(services => 17 | { 18 | _ = services.AddTransient(); 19 | }); 20 | 21 | _ = builder.ConfigureAppConfiguration(config => 22 | { 23 | }); 24 | 25 | _ = builder.UseEnvironment("Development"); 26 | } 27 | 28 | protected override void ConfigureClient(HttpClient client) 29 | { 30 | base.ConfigureClient(client); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi.Tests/FakeUserStartupFilter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using System.Security.Claims; 8 | 9 | namespace OpenTask.WebApi.Tests 10 | { 11 | public class FakeUserStartupFilter : IStartupFilter 12 | { 13 | public Action Configure(Action next) 14 | { 15 | return app => 16 | { 17 | _ = app.Use(async (context, next) => 18 | { 19 | var claims = new Claim[] { new Claim(ClaimTypes.Name, "test") }; 20 | 21 | var claimsIdentity = new ClaimsIdentity(claims, "Basic"); 22 | var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); 23 | context.User = claimsPrincipal; 24 | 25 | await next(); 26 | }); 27 | 28 | next(app); 29 | }; 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi.Tests/IntegrationTests/ClientTests.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.AspNetCore.Mvc.Testing; 8 | using OpenTask.Application.Base; 9 | using OpenTask.Application.User.Login; 10 | 11 | namespace OpenTask.WebApi.Tests.IntegrationTests; 12 | 13 | public class ClientTests 14 | : IClassFixture> 15 | { 16 | private readonly CustomWebApplicationFactory _factory; 17 | private readonly HttpClient client; 18 | 19 | public ClientTests(CustomWebApplicationFactory factory) 20 | { 21 | _factory = factory; 22 | client = _factory.CreateClient(); 23 | } 24 | 25 | [Theory] 26 | [InlineData("/api/Client/ListClients")] 27 | public async Task Get_Clients(string url) 28 | { 29 | HttpResponseMessage response = await client.GetAsync(url); 30 | 31 | _ = response.EnsureSuccessStatusCode(); // Status Code 200-299 32 | BaseResponse? res = await response.Content.ReadFromJsonAsync>(); 33 | Assert.NotNull(res); 34 | Assert.Equal(401, res.Code); 35 | } 36 | } -------------------------------------------------------------------------------- /src/OpenTask.WebApi.Tests/IntegrationTests/DashboardTest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using OpenTask.Application.Base; 8 | using OpenTask.Application.Dashboard; 9 | 10 | namespace OpenTask.WebApi.Tests.IntegrationTests 11 | { 12 | public class DashboardTest : IClassFixture> 13 | { 14 | private readonly CustomWebApplicationFactory _factory; 15 | private readonly HttpClient client; 16 | 17 | public DashboardTest(CustomWebApplicationFactory factory) 18 | { 19 | _factory = factory; 20 | client = _factory.CreateClient(); 21 | } 22 | 23 | [Theory] 24 | [InlineData("/api/Dashboard/Statistics")] 25 | public async Task Get_Statistics(string url) 26 | { 27 | HttpResponseMessage response = await client.GetAsync(url); 28 | 29 | _ = response.EnsureSuccessStatusCode(); 30 | var res = await response.Content.ReadFromJsonAsync>(); 31 | 32 | Assert.NotNull(res); 33 | Assert.Equal(401, res.Code); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi.Tests/OpenTask.WebApi.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net8.0 5 | enable 6 | enable 7 | false 8 | true 9 | 10 | 11 | 12 | 13 | Always 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi.Tests/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "OpenTask.WebApi.Tests": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "https://localhost:54644;http://localhost:54645" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/ClientController.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using Microsoft.AspNetCore.Mvc; 9 | using OpenTask.Application.Base; 10 | using OpenTask.Application.Clients; 11 | 12 | namespace OpenTask.WebApi.Controllers 13 | { 14 | public class ClientController : BaseController 15 | { 16 | public ClientController(IMediator mediator) : base(mediator) 17 | { 18 | } 19 | 20 | [HttpGet] 21 | public async Task> ListClients([FromQuery] ListClientsRequest request) 22 | { 23 | return await RequestAsync(request); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/DashboardController.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using Microsoft.AspNetCore.Mvc; 9 | using OpenTask.Application.Base; 10 | using OpenTask.Application.Dashboard; 11 | using OpenTask.Application.TaskLogs; 12 | 13 | namespace OpenTask.WebApi.Controllers 14 | { 15 | public class DashboardController : BaseController 16 | { 17 | public DashboardController(IMediator mediator) : base(mediator) 18 | { 19 | } 20 | 21 | [HttpGet] 22 | public async Task> Statistics() 23 | { 24 | return await RequestAsync(new StatisticsRequest()); 25 | } 26 | 27 | [HttpGet] 28 | public async Task> TaskLogsDayTrend([FromQuery] TaskLogsDayTrendRequest request) 29 | { 30 | return await RequestAsync(request); 31 | } 32 | 33 | [HttpGet] 34 | public async Task> TopTaskLog([FromQuery] ListTopTaskLogRequest request) 35 | { 36 | return await RequestAsync(request); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/MembersController.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using OpenTask.Application.Base; 4 | using OpenTask.Application.Members.GetMember; 5 | using OpenTask.Application.Members.ListMembers; 6 | 7 | namespace OpenTask.WebApi.Controllers 8 | { 9 | [Route("api/Organization/{organizationId}/[controller]")] 10 | public class MembersController : BaseController 11 | { 12 | private readonly ILogger _logger; 13 | 14 | public MembersController(IMediator mediator, ILogger logger) 15 | : base(mediator) 16 | { 17 | _logger = logger; 18 | } 19 | 20 | [HttpGet] 21 | public async Task ListMembers(long organizationId) 22 | { 23 | return await RequestAsync(new ListMembersRequest 24 | { 25 | OrganizationId = organizationId 26 | }); 27 | } 28 | 29 | [HttpGet("{accountId}")] 30 | public async Task Member(long organizationId, long accountId) 31 | { 32 | return await RequestAsync(new MemberRequest 33 | { 34 | AccountId = accountId, 35 | OrganizationId = organizationId 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/OrganizationController.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using OpenTask.Application.Base; 4 | using OpenTask.Application.Orgs.CreateOrganization; 5 | using OpenTask.Application.Orgs.ListOrg; 6 | using System.ComponentModel.DataAnnotations; 7 | 8 | namespace OpenTask.WebApi.Controllers 9 | { 10 | [Route("api/[controller]/[action]")] 11 | public class OrganizationController : BaseController 12 | { 13 | private readonly ILogger _logger; 14 | 15 | public OrganizationController(IMediator mediator, ILogger logger) : base(mediator) 16 | { 17 | _logger = logger; 18 | } 19 | 20 | [HttpPut] 21 | public async Task CreateOrganization(CreateOrganizationRequest request) 22 | { 23 | request.UserId = CurrentUser.UserId; 24 | return await RequestAsync(request); 25 | } 26 | 27 | [HttpDelete] 28 | public IActionResult DeleteOrganization([Range(1, double.MaxValue)] long Id) 29 | { 30 | return Content($"deleted"); 31 | } 32 | 33 | [HttpGet] 34 | public async Task ListOrganizations() 35 | { 36 | return await RequestAsync(new ListOrgCommand { UserId = CurrentUser.UserId }); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/TaskLogController.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using MediatR; 8 | using Microsoft.AspNetCore.Mvc; 9 | using OpenTask.Application.Base; 10 | using OpenTask.Application.TaskLogs; 11 | 12 | namespace OpenTask.WebApi.Controllers 13 | { 14 | public class TaskLogController : BaseController 15 | { 16 | public TaskLogController(IMediator mediator) 17 | : base(mediator) 18 | { 19 | } 20 | 21 | [HttpGet] 22 | public async Task> ListLogs([FromQuery] LisTaskLogsRequest tasksCommand) 23 | { 24 | return await RequestAsync(tasksCommand); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/TodoItemController.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.OpenApi.Models; 4 | using OpenTask.Application.Base; 5 | using OpenTask.Application.Todos.GetTodoItems; 6 | using System.ComponentModel.DataAnnotations; 7 | 8 | namespace OpenTask.WebApi.Controllers 9 | { 10 | public class TodoItemController : BaseController 11 | { 12 | public TodoItemController(IMediator mediator) 13 | : base(mediator) 14 | { 15 | } 16 | 17 | [HttpGet] 18 | public async Task Get([FromServices] IMediator mediator, [Range(1, double.MaxValue)] long Id) 19 | { 20 | return await RequestAsync(new GetTodoItemsQuery { Id = Id }); 21 | } 22 | 23 | [HttpPut] 24 | public IActionResult Put(TodoDto item) 25 | { 26 | return Content($"insert"); 27 | } 28 | 29 | [HttpPost] 30 | public IActionResult Post(TodoDto item) 31 | { 32 | return Content($"updated"); 33 | } 34 | 35 | [HttpDelete] 36 | public IActionResult Delete(long Id) 37 | { 38 | return Content($"deleted"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Controllers/WorkitemsController.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using OpenTask.Application.Base; 4 | using OpenTask.Application.Issue; 5 | using System.ComponentModel.DataAnnotations; 6 | 7 | namespace OpenTask.WebApi.Controllers 8 | { 9 | [Route("api/Organization/{organizationId}/[controller]")] 10 | public class WorkitemsController : BaseController 11 | { 12 | public WorkitemsController(IMediator mediator) : base(mediator) 13 | { 14 | } 15 | 16 | [HttpGet("MyIssue")] 17 | public async Task MyIssueAsync([Required] long organizationId) 18 | { 19 | return await RequestAsync(new MyIssueCommand() 20 | { 21 | OrgId = organizationId, 22 | UserId = CurrentUser.UserId 23 | }); 24 | } 25 | 26 | // POST /organization/{organizationId}/workitems/create 27 | 28 | // POST /organization/{organizationId}/workitems/update 29 | 30 | // GET /organization/{organizationId}/workitems/{workitemId} 31 | 32 | // GET /organization/{organizationId}/workitems/{workitemId}/getActivity 33 | 34 | // DELETE /organization/{organizationId}/workitem/delete 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Extensions/MySchemaProcessor.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Swashbuckle.AspNetCore.SwaggerGen; 8 | 9 | namespace OpenTask.WebApi 10 | { 11 | public class MySchemaFilter : ISchemaFilter 12 | { 13 | public void Apply(Microsoft.OpenApi.Models.OpenApiSchema schema, SchemaFilterContext context) 14 | { 15 | foreach (KeyValuePair item in schema.Properties) 16 | { 17 | if (item.Value.Type == "integer" && item.Value.Format == "int64") 18 | { 19 | item.Value.Type = "string"; 20 | } 21 | } 22 | } 23 | } 24 | 25 | public class MyParameterFilter : IParameterFilter 26 | { 27 | public void Apply(Microsoft.OpenApi.Models.OpenApiParameter parameter, ParameterFilterContext context) 28 | { 29 | if (parameter.Schema.Type == "integer" && parameter.Schema.Format == "int64") 30 | { 31 | parameter.Schema.Type = "string"; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Filters/CustomExceptionFilterAttribute.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | using Microsoft.AspNetCore.Mvc; 8 | using Microsoft.AspNetCore.Mvc.Filters; 9 | using OpenTask.Application.Base; 10 | 11 | namespace OpenTask.WebApi.Filters 12 | { 13 | public class CustomExceptionFilterAttribute : ExceptionFilterAttribute 14 | { 15 | private readonly ILogger _logger; 16 | 17 | public CustomExceptionFilterAttribute(ILogger logger) 18 | { 19 | _logger = logger; 20 | } 21 | 22 | public override void OnException(ExceptionContext context) 23 | { 24 | _logger.LogError(context.Exception, "【全局异常捕获】"); 25 | BaseResponse res = new() 26 | { 27 | TraceId = context.HttpContext.TraceIdentifier, 28 | Result = null, 29 | Message = context.Exception.Message, 30 | Code = StatusCodes.Status500InternalServerError, 31 | }; 32 | 33 | JsonResult result = new(res) { StatusCode = StatusCodes.Status200OK }; 34 | 35 | context.Result = result; 36 | context.ExceptionHandled = true; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Filters/LongToStringSchemaFilter.cs: -------------------------------------------------------------------------------- 1 | namespace Qz.WebApi.Filters 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Reflection; 6 | using Microsoft.OpenApi.Models; 7 | using System.Text.Json; 8 | 9 | public class LongToStringSchemaFilter : ISchemaFilter 10 | { 11 | public void Apply(OpenApiSchema schema, SchemaFilterContext context) 12 | { 13 | var properties = context.Type.GetProperties() 14 | .Where(p => p.PropertyType == typeof(long) || p.PropertyType == typeof(long?)); 15 | 16 | foreach (var property in properties) 17 | { 18 | var propertySchema = schema.Properties 19 | .FirstOrDefault(p => string.Equals(p.Key, property.Name, StringComparison.OrdinalIgnoreCase)).Value; 20 | if (propertySchema != null) 21 | { 22 | propertySchema.Type = "string"; 23 | propertySchema.Format = "int64"; 24 | } 25 | } 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Models/DeleteJobRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.WebApi.Models 8 | { 9 | public class DeleteJobRequest 10 | { 11 | public long jobId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Models/GetJobListRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.WebApi.Models 8 | { 9 | public class GetJobListRequest 10 | { 11 | public int PageNumber { get; set; } = 1; 12 | 13 | public int PageSize { get; set; } = 15; 14 | 15 | public string? name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Models/GetTokenRequest.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.WebApi.Models 8 | { 9 | public class GetTokenRequest 10 | { 11 | public required string UserName { get; set; } 12 | 13 | public required string PassWord { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Models/ResultData.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the MIT License (the "License"). 2 | // You may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // https://github.com/SpringHgui/OpenTask/blob/master/LICENSE 5 | // Copyright (c) 2024 Gui.H 6 | 7 | namespace OpenTask.WebApi.Models 8 | { 9 | public class ResultData 10 | { 11 | public ResultData() 12 | { 13 | success = true; 14 | } 15 | 16 | public bool success { get; set; } 17 | 18 | public string message { get; set; } 19 | 20 | 21 | public object data { get; set; } 22 | 23 | /// 24 | /// 链路追踪标识 25 | /// 26 | public string trace_id { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/OpenTask.WebApi.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | https 5 | ApiControllerEmptyScaffolder 6 | root/Common/Api 7 | 8 | 9 | ProjectDebugger 10 | 11 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "http": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "swagger", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | }, 10 | "dotnetRunMessages": true, 11 | "applicationUrl": "http://localhost:5223" 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "launchBrowser": false, 16 | "launchUrl": "swagger", 17 | "environmentVariables": { 18 | "ASPNETCORE_ENVIRONMENT": "Development", 19 | //"ConnectionStrings__Core": "server=127.0.0.1;Port=3306;user id=root;database=open_task;pooling=true;password=OPEN_TASK_!@#" 20 | }, 21 | "dotnetRunMessages": true, 22 | "applicationUrl": "https://localhost:7254;http://localhost:5223" 23 | } 24 | }, 25 | "$schema": "http://json.schemastore.org/launchsettings.json", 26 | "iisSettings": { 27 | "windowsAuthentication": false, 28 | "anonymousAuthentication": true, 29 | "iisExpress": { 30 | "applicationUrl": "http://localhost:37854", 31 | "sslPort": 44325 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/OpenTask.WebApi/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "ConnectionStrings": { 9 | "Core": "server=101.37.166.120;Port=3306;user id=root;database=open_task;pooling=true;password=OPEN_123_TASK_123" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/OpenTask.WebApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | //"urls": "http://*:8080", 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | }, 12 | "Jwt": { 13 | "SigningKey": "c3VpZGFvLmlvIGlzIHl5ZHMgc3VpZGFvLmlvIGlzIHl5ZHMgc3VpZGFvLmlvIGlzIHl5ZHM=", 14 | "ClockSkew": 0, 15 | "ValidAudience": "https://opentask.run", 16 | "ValidIssuer": "opentask", 17 | "Expires": 120 18 | }, 19 | "ServerOptions": { 20 | "Port": 1883 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ui/vite-opentask/.env.development: -------------------------------------------------------------------------------- 1 | VITE_API_URL=https://localhost:7254 2 | -------------------------------------------------------------------------------- /ui/vite-opentask/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | "@typescript-eslint/no-explicit-any": "warn", 18 | "no-unused-vars": "off", 19 | "@typescript-eslint/no-unused-vars": "warn", 20 | "prefer-const": ["warn", { 21 | "destructuring": "any", 22 | "ignoreReadBeforeAssign": false 23 | }] 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /ui/vite-opentask/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /ui/vite-opentask/.npmrc: -------------------------------------------------------------------------------- 1 | @tiptap-pro:registry=https://registry.tiptap.dev/ 2 | //registry.tiptap.dev/:_authToken=XEJ383/ZpD3PS/9SWLK1dZiHdWubHQgAYuudtUQsw26tXPAeseOx9f+pKtTjEsHn -------------------------------------------------------------------------------- /ui/vite-opentask/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ## openapi-generator 17 | https://openapi-generator.tech/docs/generators/typescript-fetch/ 18 | 19 | ```js 20 | export default { 21 | // other rules... 22 | parserOptions: { 23 | ecmaVersion: 'latest', 24 | sourceType: 'module', 25 | project: ['./tsconfig.json', './tsconfig.node.json'], 26 | tsconfigRootDir: __dirname, 27 | }, 28 | } 29 | ``` 30 | 31 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` 32 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked` 33 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list 34 | -------------------------------------------------------------------------------- /ui/vite-opentask/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "app/globals.css", 9 | "baseColor": "zinc", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /ui/vite-opentask/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | OpenTask 新一代分布式任务调度 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ui/vite-opentask/openapitools.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", 3 | "spaces": 2, 4 | "generator-cli": { 5 | "version": "7.5.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ui/vite-opentask/package-lock.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpringHgui/OpenTask/a9e275c0057ee948c5a876b0a2950ab21486c03f/ui/vite-opentask/package-lock.json -------------------------------------------------------------------------------- /ui/vite-opentask/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /ui/vite-opentask/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/App.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | width: 100%; 5 | overflow: hidden; 6 | overflow-wrap: break-word; 7 | } 8 | 9 | #root { 10 | height: 100%; 11 | width: 100%; 12 | } 13 | 14 | /* jotai插件位置调整,防止开发期间挡住重要ui */ 15 | .jotai-devtools-trigger-button { 16 | left: 80px !important; 17 | } 18 | 19 | .layout-sider-menu::-webkit-scrollbar { 20 | display: none; 21 | } -------------------------------------------------------------------------------- /ui/vite-opentask/src/App.tsx: -------------------------------------------------------------------------------- 1 | import './App.css' 2 | import AppLayout, { ELayout } from './layout/app-layout'; 3 | export function App() { 4 | const AppContainer = AppLayout[ELayout.side]; 5 | 6 | return <> 7 | 8 | 9 | } -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis-gen/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # OpenAPI Generator Ignore 2 | # Generated by openapi-generator https://github.com/openapitools/openapi-generator 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis-gen/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | apis/ClientApi.ts 2 | apis/DashboardApi.ts 3 | apis/TaskInfoApi.ts 4 | apis/TaskLogApi.ts 5 | apis/UserApi.ts 6 | apis/index.ts 7 | index.ts 8 | models/AddTaskRequest.ts 9 | models/AddTaskResponseBaseResponse.ts 10 | models/DeleteTaskRequest.ts 11 | models/DeleteTaskResponseBaseResponse.ts 12 | models/ExcuteOnceRequest.ts 13 | models/ExcuteOnceResponseBaseResponse.ts 14 | models/ExecutorClient.ts 15 | models/GetNext5TriggertimesResponse.ts 16 | models/GetNext5TriggertimesResponseBaseResponse.ts 17 | models/LisTaskLogsResponse.ts 18 | models/LisTaskLogsResponseBaseResponse.ts 19 | models/ListClientsResponse.ts 20 | models/ListClientsResponseBaseResponse.ts 21 | models/ListTaskInfosResponse.ts 22 | models/ListTaskInfosResponseBaseResponse.ts 23 | models/ListTopTaskLogResponse.ts 24 | models/ListTopTaskLogResponseBaseResponse.ts 25 | models/LoginCommand.ts 26 | models/LoginResponse.ts 27 | models/LoginResponseBaseResponse.ts 28 | models/StatisticInfos.ts 29 | models/StatisticsResponse.ts 30 | models/StatisticsResponseBaseResponse.ts 31 | models/SwitchTaskStatusRequest.ts 32 | models/SwitchTaskStatusResponseBaseResponse.ts 33 | models/TaskInfo.ts 34 | models/TaskLog.ts 35 | models/TaskLogDayTrend.ts 36 | models/TaskLogsDayTrendResponse.ts 37 | models/TaskLogsDayTrendResponseBaseResponse.ts 38 | models/TopTaskLog.ts 39 | models/index.ts 40 | runtime.ts 41 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis-gen/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.5.0 2 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis-gen/apis/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | export * from './ClientApi'; 4 | export * from './DashboardApi'; 5 | export * from './TaskInfoApi'; 6 | export * from './TaskLogApi'; 7 | export * from './UserApi'; 8 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis-gen/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | export * from './runtime'; 4 | export * from './apis/index'; 5 | export * from './models/index'; 6 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis-gen/models/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | export * from './AddTaskRequest'; 4 | export * from './AddTaskResponseBaseResponse'; 5 | export * from './DeleteTaskRequest'; 6 | export * from './DeleteTaskResponseBaseResponse'; 7 | export * from './ExcuteOnceRequest'; 8 | export * from './ExcuteOnceResponseBaseResponse'; 9 | export * from './ExecutorClient'; 10 | export * from './GetNext5TriggertimesResponse'; 11 | export * from './GetNext5TriggertimesResponseBaseResponse'; 12 | export * from './LisTaskLogsResponse'; 13 | export * from './LisTaskLogsResponseBaseResponse'; 14 | export * from './ListClientsResponse'; 15 | export * from './ListClientsResponseBaseResponse'; 16 | export * from './ListTaskInfosResponse'; 17 | export * from './ListTaskInfosResponseBaseResponse'; 18 | export * from './ListTopTaskLogResponse'; 19 | export * from './ListTopTaskLogResponseBaseResponse'; 20 | export * from './LoginCommand'; 21 | export * from './LoginResponse'; 22 | export * from './LoginResponseBaseResponse'; 23 | export * from './StatisticInfos'; 24 | export * from './StatisticsResponse'; 25 | export * from './StatisticsResponseBaseResponse'; 26 | export * from './SwitchTaskStatusRequest'; 27 | export * from './SwitchTaskStatusResponseBaseResponse'; 28 | export * from './TaskInfo'; 29 | export * from './TaskLog'; 30 | export * from './TaskLogDayTrend'; 31 | export * from './TaskLogsDayTrendResponse'; 32 | export * from './TaskLogsDayTrendResponseBaseResponse'; 33 | export * from './TopTaskLog'; 34 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis/config.ts: -------------------------------------------------------------------------------- 1 | import { Configuration } from "@/apis-gen"; 2 | const config = new Configuration({ 3 | basePath: import.meta.env.VITE_API_URL || location.origin, 4 | accessToken: (name, scopes) => { 5 | return ( 6 | localStorage.getItem("token")?.replace('"', "").replace('"', "") ?? "" 7 | ); 8 | }, 9 | credentials: "include", 10 | middleware: [ 11 | { 12 | pre: (context) => { 13 | let token = 14 | localStorage.getItem("token")?.replace('"', "").replace('"', "") ?? 15 | ""; 16 | 17 | // console.log("headers", context.init.headers); 18 | return new Promise((resolve, reject) => { 19 | context.init.headers = { 20 | ...context.init.headers, 21 | Authorization: token, 22 | }; 23 | resolve(context); 24 | }); 25 | }, 26 | post(context) { 27 | return new Promise((resolve, reject) => { 28 | // console.log("post", context); 29 | if (context.response.status == 200) { 30 | resolve(); 31 | } 32 | 33 | reject(); 34 | }); 35 | }, 36 | }, 37 | ], 38 | }); 39 | 40 | export default config; 41 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis/index.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient, keepPreviousData } from "@tanstack/react-query"; 2 | 3 | import { useQuery } from "@tanstack/react-query"; 4 | import config from "./config"; 5 | import { 6 | ClientApi, 7 | ListClientsRequest, 8 | ListLogsRequest, 9 | ListTaskInfosRequest, 10 | TaskInfoApi, 11 | TaskLogApi, 12 | } from "@/apis-gen"; 13 | import { PaginationState } from "@tanstack/react-table"; 14 | 15 | export const queryClient = new QueryClient({ 16 | defaultOptions: { 17 | queries: { 18 | gcTime: 1000 * 60 * 60 * 24, // 24 hours 19 | }, 20 | }, 21 | }); 22 | 23 | export function useTaskInfos(request: ListTaskInfosRequest) { 24 | return useQuery({ 25 | queryKey: ["listTaskInfos", request.pageNumber, request.pageSize], 26 | queryFn: () => new TaskInfoApi(config).listTaskInfos(request), 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/apis/types/index.tsx: -------------------------------------------------------------------------------- 1 | 2 | export interface BaseResponse { 3 | code: number, 4 | message: string, 5 | data: T | undefined 6 | } 7 | 8 | export type JsonBodyType = Record | string | number | boolean | null | undefined; 9 | 10 | export interface LoginRequest { 11 | userName: string | object | undefined, 12 | passWord: string | object | undefined 13 | } 14 | 15 | export interface LoginResponse { 16 | token: string, 17 | } 18 | 19 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/common/types.tsx: -------------------------------------------------------------------------------- 1 | 2 | // 接收一个参数T,无返回值的函数委托 3 | export type Action = (arg: T) => void; 4 | 5 | // 接收一个参数T,返回R的函数委托 6 | export type Func = (arg: T) => R; 7 | 8 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/date-table/data-table-toolbar.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Cross2Icon } from "@radix-ui/react-icons"; 4 | 5 | import { Input } from "@/components/ui/input"; 6 | import { Button } from "@/components/ui/button"; 7 | import { Table } from "@tanstack/react-table"; 8 | import { DataTableFacetedFilter } from "./data-table-faceted-filter"; 9 | 10 | import { DataTableViewOptions } from "./data-table-view-options"; 11 | 12 | export interface DataTableToolbarProps { 13 | table: Table; 14 | } 15 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/drawer/index.css: -------------------------------------------------------------------------------- 1 | .EZDrawer .EZDrawer__checkbox { 2 | display: none; 3 | } 4 | 5 | .EZDrawer .EZDrawer__checkbox:checked~.EZDrawer__overlay { 6 | display: block; 7 | opacity: 1; 8 | } 9 | 10 | .EZDrawer .EZDrawer__checkbox:checked~.EZDrawer__container { 11 | visibility: visible; 12 | transform: translate3d(0, 0, 0) !important; 13 | } 14 | 15 | .EZDrawer .EZDrawer__overlay { 16 | display: none; 17 | height: 100vh; 18 | left: 0; 19 | position: fixed; 20 | top: 0; 21 | width: 100%; 22 | } 23 | 24 | .EZDrawer .EZDrawer__container { 25 | position: fixed; 26 | visibility: hidden; 27 | background: white; 28 | transition: all; 29 | box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.1); 30 | } -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/logo.tsx: -------------------------------------------------------------------------------- 1 | import { Shapes } from "lucide-react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | export function Logo() { 5 | // const [minimized, handleToggle] = useAtom(isMinimized); 6 | return <> 7 | 8 | {/* {!minimized && "OpenTask"} */} 9 | OpenTask 10 | 11 | 12 | } -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/mode-toggle.tsx: -------------------------------------------------------------------------------- 1 | import { Moon, Sun } from "lucide-react" 2 | 3 | import { Button } from "@/components/ui/button" 4 | import { 5 | DropdownMenu, 6 | DropdownMenuContent, 7 | DropdownMenuItem, 8 | DropdownMenuTrigger, 9 | } from "@/components/ui/dropdown-menu" 10 | import { useTheme } from "@/theme/theme-provider" 11 | 12 | export function ModeToggle() { 13 | const { setTheme } = useTheme() 14 | 15 | return ( 16 | 17 | 18 | 23 | 24 | 25 | setTheme("light")}> 26 | Light 27 | 28 | setTheme("dark")}> 29 | Dark 30 | 31 | setTheme("system")}> 32 | System 33 | 34 | 35 | 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/page.tsx: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction } from "react"; 2 | import { 3 | Pagination, 4 | PaginationContent, 5 | PaginationEllipsis, 6 | PaginationItem, 7 | PaginationLink, 8 | PaginationNext, 9 | PaginationPrevious, 10 | } from "./ui/pagination"; 11 | 12 | export interface PageProps { 13 | Count: number; 14 | PageSize: number; 15 | CurrentPage: number; 16 | PageChange: Dispatch>; 17 | } 18 | 19 | export function Page({ Count, PageSize, CurrentPage }: PageProps) { 20 | const pageCount = Math.ceil(Count / PageSize); 21 | 22 | return ( 23 | 24 | 25 | 26 | 27 | 28 | 29 | 1 30 | 31 | 32 | 33 | 2 34 | 35 | 36 | 37 | 3 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/pages/subpage-back.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@/components/ui/button" 2 | import { ArrowLeft, X } from "lucide-react"; 3 | import { MouseEventHandler, ReactNode } from "react"; 4 | 5 | export function SubpageBack({ onBack, children, title, showClose, onClose } 6 | : { onBack?: MouseEventHandler | undefined, onClose?: MouseEventHandler | undefined, title: string, showClose?: boolean, children: ReactNode }) { 7 | return
8 |
9 | 12 |
13 |

{title}

14 | {showClose 15 | && 18 | } 19 |
20 |
21 | {children} 22 |
23 | } -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as AvatarPrimitive from "@radix-ui/react-avatar" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const Avatar = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | )) 19 | Avatar.displayName = AvatarPrimitive.Root.displayName 20 | 21 | const AvatarImage = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, ...props }, ref) => ( 25 | 30 | )) 31 | AvatarImage.displayName = AvatarPrimitive.Image.displayName 32 | 33 | const AvatarFallback = React.forwardRef< 34 | React.ElementRef, 35 | React.ComponentPropsWithoutRef 36 | >(({ className, ...props }, ref) => ( 37 | 45 | )) 46 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 47 | 48 | export { Avatar, AvatarImage, AvatarFallback } 49 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ) 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 |
33 | ) 34 | } 35 | 36 | export { Badge, badgeVariants } 37 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox" 3 | import { CheckIcon } from "@radix-ui/react-icons" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const Checkbox = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 22 | 23 | 24 | 25 | )) 26 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 27 | 28 | export { Checkbox } 29 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 2 | 3 | const Collapsible = CollapsiblePrimitive.Root 4 | 5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 6 | 7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 8 | 9 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 10 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/hover-card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as HoverCardPrimitive from "@radix-ui/react-hover-card" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const HoverCard = HoverCardPrimitive.Root 7 | 8 | const HoverCardTrigger = HoverCardPrimitive.Trigger 9 | 10 | const HoverCardContent = React.forwardRef< 11 | React.ElementRef, 12 | React.ComponentPropsWithoutRef 13 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 14 | 24 | )) 25 | HoverCardContent.displayName = HoverCardPrimitive.Content.displayName 26 | 27 | export { HoverCard, HoverCardTrigger, HoverCardContent } 28 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const labelVariants = cva( 8 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 9 | ) 10 | 11 | const Label = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef & 14 | VariantProps 15 | >(({ className, ...props }, ref) => ( 16 | 21 | )) 22 | Label.displayName = LabelPrimitive.Root.displayName 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/popover.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as PopoverPrimitive from "@radix-ui/react-popover" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const Popover = PopoverPrimitive.Root 7 | 8 | const PopoverTrigger = PopoverPrimitive.Trigger 9 | 10 | const PopoverAnchor = PopoverPrimitive.Anchor 11 | 12 | const PopoverContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 16 | 17 | 27 | 28 | )) 29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 30 | 31 | export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } 32 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/radio-group.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { CheckIcon } from "@radix-ui/react-icons" 3 | import * as RadioGroupPrimitive from "@radix-ui/react-radio-group" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const RadioGroup = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => { 11 | return ( 12 | 17 | ) 18 | }) 19 | RadioGroup.displayName = RadioGroupPrimitive.Root.displayName 20 | 21 | const RadioGroupItem = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef 24 | >(({ className, ...props }, ref) => { 25 | return ( 26 | 34 | 35 | 36 | 37 | 38 | ) 39 | }) 40 | RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName 41 | 42 | export { RadioGroup, RadioGroupItem } 43 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const Separator = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >( 10 | ( 11 | { className, orientation = "horizontal", decorative = true, ...props }, 12 | ref 13 | ) => ( 14 | 25 | ) 26 | ) 27 | Separator.displayName = SeparatorPrimitive.Root.displayName 28 | 29 | export { Separator } 30 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/slider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as SliderPrimitive from "@radix-ui/react-slider" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const Slider = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | 19 | 20 | 21 | 22 | 23 | )) 24 | Slider.displayName = SliderPrimitive.Root.displayName 25 | 26 | export { Slider } 27 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from "next-themes" 2 | import { Toaster as Sonner } from "sonner" 3 | 4 | type ToasterProps = React.ComponentProps 5 | 6 | const Toaster = ({ ...props }: ToasterProps) => { 7 | const { theme = "system" } = useTheme() 8 | 9 | return ( 10 | 26 | ) 27 | } 28 | 29 | export { Toaster } 30 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/switch.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as SwitchPrimitives from "@radix-ui/react-switch" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const Switch = React.forwardRef< 7 | React.ElementRef, 8 | React.ComponentPropsWithoutRef 9 | >(({ className, ...props }, ref) => ( 10 | 18 | 23 | 24 | )) 25 | Switch.displayName = SwitchPrimitives.Root.displayName 26 | 27 | export { Switch } 28 | -------------------------------------------------------------------------------- /ui/vite-opentask/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |