import web code
diff --git a/.dlc.json b/.dlc.json
new file mode 100644
index 0000000..b638ba4
--- /dev/null
+++ b/.dlc.json
@@ -0,0 +1,35 @@
+{
+ "ignorePatterns": [
+ {
+ "pattern": "^http://localhost"
+ },
+ {
+ "pattern": "^https://mvnrepository.com"
+ },
+ {
+ "pattern": "^https://www.qutoutiao.net"
+ },
+ {
+ "pattern": "^https://img.shields.io"
+ },
+ {
+ "pattern": "^https://json.org/"
+ },
+ {
+ "pattern": "^/docs/category"
+ },
+ {
+ "pattern": "^https://opencollective.com"
+ }
+ ],
+ "timeout": "10s",
+ "retryOn429": true,
+ "retryCount": 10,
+ "fallbackRetryDelay": "1000s",
+ "aliveStatusCodes": [
+ 0,
+ 200,
+ 401,
+ 403
+ ]
+}
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
new file mode 100644
index 0000000..119698e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -0,0 +1,141 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Bug report
+title: "[Bug] [Module Name] Bug title"
+description: Problems and issues with code of seatunnel
+labels: ["bug"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Please make sure what you are reporting is indeed a bug with reproducible steps.
+ For better global communication, Please write in English.
+
+ If you feel the description in English is not clear, then you can append description in Chinese, thanks!
+
+ - type: checkboxes
+ attributes:
+ label: Search before asking
+ description: >
+ Please make sure to search in the [issues](https://github.com/apache/incubator-seatunnel/issues?q=is%3Aissue+label%3A%22bug%22)
+ first to see whether the same issue was reported already.
+ options:
+ - label: >
+ I had searched in the [issues](https://github.com/apache/incubator-seatunnel/issues?q=is%3Aissue+label%3A%22bug%22) and found
+ no similar issues.
+ required: true
+
+ - type: textarea
+ attributes:
+ label: What happened
+ description: Describe what happened.
+ placeholder: >
+ Please provide the context in which the problem occurred and explain what happened
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: SeaTunnel Version
+ description: Provide SeaTunnel version.
+ placeholder: >
+ Please provide the version of SeaTunnel.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: SeaTunnel Config
+ description: Provide SeaTunnel Config, please delete sensitive information to prevent information leakage
+ placeholder: >
+ Please provide the SeaTunnel Config here.
+ render: conf
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Running Command
+ description: Provide the command you begin and run SeaTunnel job.
+ placeholder: >
+ Please provide the running command here.
+ render: shell
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Error Exception
+ description: Provide the error exception when you run your command.
+ placeholder: >
+ Please provide the error exception here.
+ render: log
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Flink or Spark Version
+ description: Provide Flink or Spark Version.
+ placeholder: >
+ Please provide the version of Flink or Spark.
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Java or Scala Version
+ description: Provide Java or Scala Version.
+ placeholder: >
+ Please provide the version of Java or Scala.
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Screenshots
+ description: Provide the screenshots if necessary.
+ placeholder: >
+ Please copy-paste the screenshots here.
+ validations:
+ required: false
+
+ - type: checkboxes
+ attributes:
+ label: Are you willing to submit PR?
+ description: >
+ This is absolutely not required, but we are happy to guide you in the contribution process
+ especially if you already have a good understanding of how to implement the fix.
+ seatunnel is a totally community-driven project and we love to bring new contributors in.
+ options:
+ - label: Yes I am willing to submit a PR!
+
+ - type: checkboxes
+ attributes:
+ label: Code of Conduct
+ description: |
+ The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
+ options:
+ - label: >
+ I agree to follow this project's
+ [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
+ required: true
+
+ - type: markdown
+ attributes:
+ value: "Thanks for completing our form, and we will reply you as soon as possible."
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
new file mode 100644
index 0000000..2a9877e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -0,0 +1,83 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Feature request
+description: Suggest an idea for seatunnel
+title: "[Feature][Module Name] Feature title"
+labels: ["Feature"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ For better global communication, Please write in English.
+
+ If you feel the description in English is not clear, then you can append description in Chinese, thanks!
+
+ - type: checkboxes
+ attributes:
+ label: Search before asking
+ description: >
+ Please make sure to search in the [feature](https://github.com/apache/incubator-seatunnel/issues?q=is%3Aissue+label%3A%22Feature%22) first
+ to see whether the same feature was requested already.
+ options:
+ - label: >
+ I had searched in the [feature](https://github.com/apache/incubator-seatunnel/issues?q=is%3Aissue+label%3A%22Feature%22) and found no
+ similar feature requirement.
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Description
+ description: Please describe the function you want in as much detail as possible.
+ placeholder: >
+ Rather than telling us how you might implement this feature, try to take a
+ step back and describe what you are trying to achieve.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Usage Scenario
+ description: Please describe usage scenario of this feature.
+
+ - type: textarea
+ attributes:
+ label: Related issues
+ description: Is there currently another issue associated with this?
+
+ - type: checkboxes
+ attributes:
+ label: Are you willing to submit a PR?
+ description: >
+ This is absolutely not required, but we are happy to guide you in the contribution process
+ especially if you already have a good understanding of how to implement the feature.
+ seatunnel is a totally community-driven project and we love to bring new contributors in.
+ options:
+ - label: Yes I am willing to submit a PR!
+
+ - type: checkboxes
+ attributes:
+ label: Code of Conduct
+ description: |
+ The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
+ options:
+ - label: |
+ I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
+ required: true
+
+ - type: markdown
+ attributes:
+ value: "Thanks for completing our form, and we will reply you as soon as possible."
diff --git a/.github/ISSUE_TEMPLATE/umbrella.yml b/.github/ISSUE_TEMPLATE/umbrella.yml
new file mode 100644
index 0000000..8db9b4d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/umbrella.yml
@@ -0,0 +1,80 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Umbrella
+title: "[Umbrella] "
+description: An umbrella issue with multiple sub-tasks
+labels: [ "umbrella" ]
+body:
+
+ - type: checkboxes
+ attributes:
+ label: Code of Conduct
+ description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
+ options:
+ - label: >
+ I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
+ required: true
+
+ - type: checkboxes
+ attributes:
+ label: Search before asking
+ description: >
+ Please make sure to search in the [issues](https://github.com/apache/incubator-seatunnel/issues?q=is%3Aissue+label%3A%22bug%22)
+ first to see whether the same issue was reported already.
+ options:
+ - label: >
+ I had searched in the [issues](https://github.com/apache/incubator-seatunnel/issues?q=is%3Aissue+label%3A%22bug%22) and found
+ no similar issues.
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Describe the proposal
+ placeholder: >
+ Please describe the content of the proposal clearly.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Task list
+ description: >
+ For more details, please refer to [github docs](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-task-lists).
+ placeholder: >
+ Please create sub-tasks with the pre-create issues here and @ the assignees if you know any of them. A simple example is as follows:
+ - [ ] #1
+ - [ ] #2 @user1
+ - [ ] #3
+ - [ ] #2 @user2
+ - [ ] #3
+ validations:
+ required: true
+
+ - type: checkboxes
+ attributes:
+ label: Are you willing to submit PR?
+ description: >
+ This is absolutely not required, but we are happy to guide you in the contribution process
+ especially if you already have a good understanding of how to implement the fix.
+ seatunnel is a totally community-driven project and we love to bring new contributors in.
+ options:
+ - label: Yes I am willing to submit a PR!
+
+ - type: markdown
+ attributes:
+ value: "Thanks for taking the time to propose an umbrella issue!"
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..3752eb8
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,28 @@
+<!--
+
+Thank you for contributing to SeaTunnel! Please make sure that your code changes
+are covered with tests. And in case of new features or big changes
+remember to adjust the documentation.
+
+Feel free to ping committers for the review!
+
+## Contribution Checklist
+
+ - Make sure that the pull request corresponds to a [GITHUB issue](https://github.com/apache/incubator-seatunnel/issues).
+
+ - Name the pull request in the form "[Feature] [component] Title of the pull request", where *Feature* can be replaced by `Hotfix`, `Bug`, etc.
+
+ - Minor fixes should be named following this pattern: `[hotfix] [docs] Fix typo in README.md doc`.
+
+-->
+
+## Purpose of this pull request
+
+<!-- Describe the purpose of this pull request. For example: This pull request adds checkstyle plugin.-->
+
+## Check list
+
+* [ ] Code changed are covered with tests, or it does not need tests for reason:
+* [ ] If any new Jar binary package adding in your PR, please add License Notice according
+ [New License Guide](https://github.com/apache/incubator-seatunnel/blob/dev/docs/en/contribution/new-license.md)
+* [ ] If necessary, please update the documentation to describe the new feature. https://github.com/apache/incubator-seatunnel/tree/dev/docs
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 0000000..e4e0995
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+daysUntilStale: 90
+daysUntilClose: 30
+exemptLabels:
+ - bug
+staleLabel: stale
+markComment: >
+ This has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+closeComment: false
diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml
new file mode 100644
index 0000000..d32e88d
--- /dev/null
+++ b/.github/workflows/backend.yml
@@ -0,0 +1,183 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the 'License'); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Backend
+
+on:
+ push:
+ pull_request:
+ paths-ignore:
+ - 'docs/**'
+ - '**/*.md'
+ - 'seatunnel-ui/**'
+
+concurrency:
+ group: backend-${{ github.event.pull_request.number || github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ license-header:
+ if: github.repository == 'apache/incubator-seatunnel'
+ name: License header
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - name: Check license header
+ uses: apache/skywalking-eyes@985866ce7e324454f61e22eb2db2e998db09d6f3
+
+ code-style:
+ if: github.repository == 'apache/incubator-seatunnel'
+ name: Code style
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - name: Check code style
+ run: ./mvnw --batch-mode --quiet --no-snapshot-updates clean checkstyle:check
+
+ dead-link:
+ if: github.repository == 'apache/incubator-seatunnel'
+ name: Dead links
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ steps:
+ - uses: actions/checkout@v2
+ - run: sudo npm install -g markdown-link-check@3.8.7
+ - run: |
+ for file in $(find . -name "*.md"); do
+ markdown-link-check -c .dlc.json -q "$file"
+ done
+
+ sanity-check:
+ if: github.repository == 'apache/incubator-seatunnel'
+ name: Sanity check results
+ needs: [ license-header, code-style, dead-link ]
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Check results
+ run: |
+ [[ ${{ needs.license-header.result }} == 'success' ]] || exit 1;
+ [[ ${{ needs.code-style.result }} == 'success' ]] || exit 1;
+ [[ ${{ needs.dead-link.result }} == 'success' ]] || exit 1;
+
+ build:
+ if: github.repository == 'apache/incubator-seatunnel'
+ name: Build
+ needs: [ sanity-check ]
+ strategy:
+ matrix:
+ java: [ '8', '11' ]
+ os: [ 'ubuntu-latest', 'windows-latest' ]
+ runs-on: ${{ matrix.os }}
+ timeout-minutes: 80
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: ${{ matrix.java }}
+ cache: 'maven'
+ - name: Build distribution tar
+ run: >-
+ ./mvnw -B install scalastyle:check
+ -D"maven.test.skip"=true
+ -D"checkstyle.skip"=true
+ -D"license.skipAddThirdParty"=true
+ -D"http.keepAlive"=false
+ -D"maven.wagon.http.pool"=false
+ -D"maven.wagon.http.retryHandler.count"=3
+ -D"maven.wagon.httpconnectionManager.ttlSeconds"=120
+
+ dependency-license:
+ if: github.repository == 'apache/incubator-seatunnel'
+ name: Dependency licenses
+ needs: [ sanity-check ]
+ runs-on: ubuntu-latest
+ timeout-minutes: 40
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: true
+ - uses: actions/setup-java@v3
+ with:
+ distribution: 'temurin'
+ java-version: '8'
+ cache: 'maven'
+ - name: Install
+ run: >-
+ ./mvnw -B -q install -DskipTests
+ -D"maven.test.skip"=true
+ -D"maven.javadoc.skip"=true
+ -D"scalastyle.skip"=true
+ -D"checkstyle.skip"=true
+ -D"license.skipAddThirdParty"
+ - name: Check Dependencies Licenses
+ run: tools/dependencies/checkLicense.sh
+
+ unit-test:
+ name: Unit Test
+ runs-on: ${{ matrix.os }}
+ needs: [ sanity-check ]
+ strategy:
+ matrix:
+ java: [ '8', '11' ]
+ os: [ 'ubuntu-latest', 'windows-latest' ]
+ timeout-minutes: 90
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.java }}
+ distribution: 'temurin'
+ cache: 'maven'
+ - name: Run Unit tests
+ run: |
+ ./mvnw -B -T 1C clean verify -D"maven.test.skip"=false -D"checkstyle.skip"=true -D"scalastyle.skip"=true -D"license.skipAddThirdParty"=true --no-snapshot-updates
+ env:
+ MAVEN_OPTS: -Xmx2048m
+
+ integration-test:
+ name: Integration Test
+ runs-on: ${{ matrix.os }}
+ needs: [ sanity-check ]
+ strategy:
+ matrix:
+ java: [ '8', '11' ]
+ os: [ 'ubuntu-latest' ]
+ timeout-minutes: 90
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.java }}
+ distribution: 'temurin'
+ cache: 'maven'
+ - name: Run Integration tests
+ run: |
+ ./mvnw -T 1C -B verify -DskipUT=true -DskipIT=false -D"checkstyle.skip"=true -D"scalastyle.skip"=true -D"license.skipAddThirdParty"=true --no-snapshot-updates
+ env:
+ MAVEN_OPTS: -Xmx2048m
diff --git a/.github/workflows/code-analysys.yml b/.github/workflows/code-analysys.yml
new file mode 100644
index 0000000..4fda66e
--- /dev/null
+++ b/.github/workflows/code-analysys.yml
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: SonarCloud
+on:
+ push:
+ pull_request:
+ branches: [dev]
+ paths-ignore:
+ - 'docs/**'
+ - '**/*.md'
+ - 'seatunnel-ui/**'
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: true
+ - name: Set up JDK 11
+ uses: actions/setup-java@v2
+ with:
+ java-version: 11
+ distribution: 'adopt'
+ - name: Run SonarCloud Analysis
+ run: bash ./tools/sonarcheck/check.sh
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml
new file mode 100644
index 0000000..237bebd
--- /dev/null
+++ b/.github/workflows/codeql.yaml
@@ -0,0 +1,64 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+name: "CodeQL"
+
+on:
+ push:
+ pull_request:
+ branches: [dev]
+ paths-ignore:
+ - 'docs/**'
+ - '**/*.md'
+ - 'seatunnel-ui/**'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ env:
+ JAVA_TOOL_OPTIONS: -Xmx2G -Xms2G -Dhttp.keepAlive=false -Dmaven.test.skip=true -Dcheckstyle.skip=true -Dlicense.skipAddThirdParty=true -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.wagon.httpconnectionManager.ttlSeconds=120
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: ['java']
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v2
+ with:
+ java-version: 8
+ distribution: 'adopt'
+ - name: Cache local Maven repository
+ uses: actions/cache@v2
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: ${{ matrix.language }}
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..757280e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,49 @@
+# Package Files #
+*.jar
+*.zip
+*.tar.gz
+
+# see JDK-8214300
+.attach_pid*
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# build targets
+target/
+
+# Log file
+*.log
+/logs
+logs.zip
+
+# Intellij Idea files
+.idea/
+*.iml
+.idea/*
+
+.DS_Store
+
+metastore_db/
+
+work_dir
+
+all-dependencies.txt
+self-modules.txt
+third-party-dependencies.txt
+
+*.keytab
+/derby.log
+
+dependency-reduced-pom.xml
+
+apidoc
+
+# Python
+*.py[cod]
+
+Test.java
+Test.scala
+test.conf
+spark-warehouse
+*.flattened-pom.xml
diff --git a/.licenserc.yaml b/.licenserc.yaml
new file mode 100644
index 0000000..0fd78f9
--- /dev/null
+++ b/.licenserc.yaml
@@ -0,0 +1,44 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you under
+# the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+header:
+ license:
+ spdx-id: Apache-2.0
+ copyright-owner: Apache Software Foundation
+
+ paths-ignore:
+ - seatunnel-dist
+ - NOTICE
+ - LICENSE
+ - DISCLAIMER
+ - mvnw.cmd
+ - .mvn
+ - .gitattributes
+ - '**/known-dependencies-*.txt'
+ - '**/*.md'
+ - '**/*.mdx'
+ - '**/*.json'
+ - '**/*.iml'
+ - '**/*.ini'
+ - '**/*.svg'
+ - '**/.gitignore'
+ - '**/LICENSE'
+ - '**/NOTICE'
+ - '**/.gitkeep'
+ - '**/com/typesafe/config/**'
+
+ comment: on-failure
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..aa1e4df
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
diff --git a/mvnw b/mvnw
new file mode 100755
index 0000000..5643201
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,316 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100755
index 0000000..8a15b7f
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,188 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..df66f42
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>25</version>
+ </parent>
+
+ <groupId>org.apache.seatunnel</groupId>
+ <artifactId>seatunnel-web</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+
+ <name>SeaTunnel</name>
+
+ <description>
+ Production ready big data processing product based on Apache Spark and Apache Flink.
+ </description>
+
+ <url>https://github.com/apache/incubator-seatunnel</url>
+
+ <licenses>
+ <license>
+ <name>The Apache License, Version 2.0</name>
+ <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ </license>
+ </licenses>
+
+ <scm>
+ <connection>scm:git:https://github.com/apache/incubator-seatunnel.git</connection>
+ <developerConnection>scm:git:https://github.com/apache/incubator-seatunnel.git</developerConnection>
+ <url>https://github.com/apache/incubator-seatunnel</url>
+ <tag>HEAD</tag>
+ </scm>
+
+ <issueManagement>
+ <system>GitHub</system>
+ <url>https://github.com/apache/incubator-seatunnel/issues</url>
+ </issueManagement>
+
+ <mailingLists>
+ <mailingList>
+ <name>SeaTunnel Developer List</name>
+ <post>dev@seatunnel.apache.org</post>
+ <subscribe>dev-subscribe@seatunnel.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@seatunnel.apache.org</unsubscribe>
+ </mailingList>
+ <mailingList>
+ <name>SeaTunnel Commits List</name>
+ <post>commits@seatunnel.apache.org</post>
+ <subscribe>commits-subscribe@seatunnel.apache.org</subscribe>
+ <unsubscribe>commits-unsubscribe@seatunnel.apache.org</unsubscribe>
+ </mailingList>
+ </mailingLists>
+
+ <modules>
+ <module>seatunnel-server</module>
+ </modules>
+
+ <properties>
+ <maven.compiler.source>${java.version}</maven.compiler.source>
+ <maven.compiler.target>${java.version}</maven.compiler.target>
+ <lombok.version>1.18.0</lombok.version>
+ <commons.logging.version>1.2</commons.logging.version>
+ <slf4j.version>1.7.25</slf4j.version>
+ <jackson.version>2.12.6</jackson.version>
+ <mysql.version>8.0.16</mysql.version>
+ <junit.version>5.9.0</junit.version>
+ <commons-collections4.version>4.4</commons-collections4.version>
+ <commons-lang3.version>3.4</commons-lang3.version>
+ <guava.version>19.0</guava.version>
+ <maven.deploy.skip>false</maven.deploy.skip>
+ <maven.javadoc.skip>false</maven.javadoc.skip>
+ <maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
+ <maven-failsafe-plugin.version>2.22.2</maven-failsafe-plugin.version>
+ <maven-checkstyle-plugin.version>3.1.2</maven-checkstyle-plugin.version>
+ <maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
+ <maven-pmd-plugin.version>3.8</maven-pmd-plugin.version>
+ <maven-license-maven-plugin>1.20</maven-license-maven-plugin>
+ <checkstyle.fails.on.error>true</checkstyle.fails.on.error>
+
+ <maven-scm-provider-jgit.version>1.9.5</maven-scm-provider-jgit.version>
+
+ <skipUT>false</skipUT>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>${lombok.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${commons-lang3.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ <version>${commons-collections4.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.junit</groupId>
+ <artifactId>junit-bom</artifactId>
+ <version>${junit.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>${log4j-core.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.checkerframework</groupId>
+ <artifactId>checker-qual</artifactId>
+ <version>${checker.qual.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <version>${awaitility.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+
+ <finalName>${project.artifactId}-${project.version}</finalName>
+
+ <pluginManagement>
+ <plugins>
+
+ <!-- java compiler (Start) -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven-compiler-plugin.version}</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven-surefire-plugin.version}</version>
+ <configuration>
+ <skip>${skipUT}</skip>
+ <systemPropertyVariables>
+ <jacoco-agent.destfile>${project.build.directory}/jacoco.exec
+ </jacoco-agent.destfile>
+ </systemPropertyVariables>
+ <excludes>
+ <exclude>**/*IT.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+
+
+ <!-- assembly -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>${maven-assembly-plugin.version}</version>
+ </plugin>
+
+ <!-- checkstyle (Start) -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>${maven-checkstyle-plugin.version}</version>
+ <configuration>
+ <!--suppress UnresolvedMavenProperty -->
+ <configLocation>${maven.multiModuleProjectDirectory}/tools/checkstyle/checkStyle.xml
+ </configLocation>
+ <encoding>UTF-8</encoding>
+ <consoleOutput>true</consoleOutput>
+ <includeTestSourceDirectory>true</includeTestSourceDirectory>
+ <failOnViolation>${checkstyle.fails.on.error}</failOnViolation>
+ <sourceDirectories>
+ <sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
+ <sourceDirectory>${project.build.testSourceDirectory}</sourceDirectory>
+ </sourceDirectories>
+ <resourceIncludes>
+ **/*.properties,
+ **/*.sh,
+ **/*.bat,
+ **/*.yml,
+ **/*.yaml,
+ **/*.xml
+ </resourceIncludes>
+ <resourceExcludes>
+ **/.asf.yaml,
+ **/.github/**
+ </resourceExcludes>
+ <excludes>
+ </excludes>
+ </configuration>
+ <executions>
+ <execution>
+ <id>validate</id>
+ <phase>process-sources</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- checkstyle (End) -->
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${maven-source-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${maven-javadoc-plugin.version}</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <failOnError>false</failOnError>
+ <aggregate>true</aggregate>
+ <skip>${maven.javadoc.skip}</skip>
+ <additionalparam>-Xdoclint:none</additionalparam>
+ </configuration>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>${maven-helper-plugin.version}</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>license-maven-plugin</artifactId>
+ <version>${maven-license-maven-plugin}</version>
+ <configuration>
+ <outputDirectory>${project.basedir}/seatunnel-dist/target/</outputDirectory>
+ <thirdPartyFilename>THIRD-PARTY.txt</thirdPartyFilename>
+ <sortArtifactByName>false</sortArtifactByName>
+ <useMissingFile>false</useMissingFile>
+ <addJavaLicenseAfterPackage>true</addJavaLicenseAfterPackage>
+ <socketTimeout>30000</socketTimeout>
+ <connectTimeout>30000</connectTimeout>
+ <connectionRequestTimeout>30000</connectionRequestTimeout>
+ <excludedScopes>test,provided</excludedScopes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <autoVersionSubmodules>true</autoVersionSubmodules>
+ <tagNameFormat>@{project.version}</tagNameFormat>
+ <tagBase>${project.version}</tagBase>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.scm</groupId>
+ <artifactId>maven-scm-provider-jgit</artifactId>
+ <version>${maven-scm-provider-jgit.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>license-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/seatunnel-server/pom.xml b/seatunnel-server/pom.xml
new file mode 100644
index 0000000..ed50733
--- /dev/null
+++ b/seatunnel-server/pom.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>seatunnel-web</artifactId>
+ <groupId>org.apache.seatunnel</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>seatunnel-server</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>seatunnel-app</module>
+ <module>seatunnel-spi</module>
+ <module>seatunnel-scheduler</module>
+ <module>seatunnel-server-common</module>
+ </modules>
+
+ <properties>
+ <spring-boot.version>2.6.8</spring-boot.version>
+ <spring.version>5.3.20</spring.version>
+ <mybatis-spring-boot-starter.version>2.2.2</mybatis-spring-boot-starter.version>
+ <druid-spring-boot-starter.version>1.2.9</druid-spring-boot-starter.version>
+ <springfox-swagger.version>2.6.1</springfox-swagger.version>
+ <swagger-annotations.version>1.5.10</swagger-annotations.version>
+ <hibernate.validator.version>6.2.2.Final</hibernate.validator.version>
+ <javax.annotation-api.version>1.3.2</javax.annotation-api.version>
+ <jsoup.version>1.14.3</jsoup.version>
+ <jwt.version>0.10.7</jwt.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- springboot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <version>${spring-boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-jetty</artifactId>
+ <version>${spring-boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-aop</artifactId>
+ <version>${spring-boot.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>druid-spring-boot-starter</artifactId>
+ <version>${druid-spring-boot-starter.version}</version>
+ </dependency>
+
+ <!-- ORM -->
+ <dependency>
+ <groupId>org.mybatis.spring.boot</groupId>
+ <artifactId>mybatis-spring-boot-starter</artifactId>
+ <version>${mybatis-spring-boot-starter.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate.validator</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>${hibernate.validator.version}</version>
+ </dependency>
+
+ <!-- swagger -->
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${springfox-swagger.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${springfox-swagger.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ <version>${swagger-annotations.version}</version>
+ </dependency>
+
+ <!-- JWT -->
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt-api</artifactId>
+ <version>${jwt.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt-impl</artifactId>
+ <version>${jwt.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt-jackson</artifactId>
+ <version>${jwt.version}</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <!-- http -->
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ <version>${jsoup.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-app/pom.xml b/seatunnel-server/seatunnel-app/pom.xml
new file mode 100644
index 0000000..9fc02f3
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/pom.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>seatunnel-server</artifactId>
+ <groupId>org.apache.seatunnel</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>seatunnel-app</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.seatunnel</groupId>
+ <artifactId>seatunnel-common</artifactId>
+ <version>2.1.3</version>
+ </dependency>
+ <!--springboot-->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-tomcat</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>log4j-to-slf4j</artifactId>
+ <groupId>org.apache.logging.log4j</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-jetty</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty.websocket</groupId>
+ <artifactId>javax-websocket-server-impl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty.websocket</groupId>
+ <artifactId>websocket-server</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mybatis.spring.boot</groupId>
+ <artifactId>mybatis-spring-boot-starter</artifactId>
+ <version>${mybatis-spring-boot-starter.version}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>spring-beans</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-boot-autoconfigure</artifactId>
+ <groupId>org.springframework.boot</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-core</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-boot-starter</artifactId>
+ <groupId>org.springframework.boot</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger2</artifactId>
+ <version>${springfox-swagger.version}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>spring-aop</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-beans</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>spring-context</artifactId>
+ <groupId>org.springframework</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>io.springfox</groupId>
+ <artifactId>springfox-swagger-ui</artifactId>
+ <version>${springfox-swagger.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ <version>${swagger-annotations.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.hibernate.validator</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <exclusions>
+ <exclusion>
+ <artifactId>classmate</artifactId>
+ <groupId>com.fasterxml</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${mysql.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.seatunnel</groupId>
+ <artifactId>seatunnel-spi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.seatunnel</groupId>
+ <artifactId>seatunnel-scheduler-dolphinscheduler</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <version>${spring-boot.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.jsonwebtoken</groupId>
+ <artifactId>jjwt-jackson</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-aop</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/SeatunnelApplication.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/SeatunnelApplication.java
new file mode 100644
index 0000000..4947195
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/SeatunnelApplication.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication(scanBasePackages = {"org.apache.seatunnel.app", "org.apache.seatunnel.scheduler"})
+@EnableTransactionManagement
+@EnableConfigurationProperties
+@EnableScheduling
+@EnableAsync(proxyTargetClass = true)
+@MapperScan({"org.apache.seatunnel.app.dal"})
+public class SeatunnelApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(SeatunnelApplication.class, args);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/adapter/SeatunnelWebAdapter.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/adapter/SeatunnelWebAdapter.java
new file mode 100644
index 0000000..9f1d4ab
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/adapter/SeatunnelWebAdapter.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.adapter;
+
+import org.apache.seatunnel.app.interceptor.AuthenticationInterceptor;
+import org.apache.seatunnel.app.resolver.UserIdMethodArgumentResolver;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+
+@Configuration
+public class SeatunnelWebAdapter implements WebMvcConfigurer {
+ @Bean
+ public AuthenticationInterceptor authenticationInterceptor() {
+ return new AuthenticationInterceptor();
+ }
+
+ @Resource
+ private UserIdMethodArgumentResolver currentUserMethodArgumentResolver;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(authenticationInterceptor()).order(1).addPathPatterns("/**")
+ // exclude swagger api path
+ .excludePathPatterns(
+ "/swagger-resources/**",
+ "/webjars/**",
+ "/v2/**",
+ "/swagger-ui.html**"
+ )
+ // exclude login
+ .excludePathPatterns("/api/v1/user/login**")
+ ;
+ }
+
+ @Override
+ public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
+ argumentResolvers.add(currentUserMethodArgumentResolver);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/LoginAspect.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/LoginAspect.java
new file mode 100644
index 0000000..1bba7f7
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/LoginAspect.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.aspect;
+
+import static org.apache.seatunnel.server.common.Constants.TOKEN;
+
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.app.common.UserTokenStatusEnum;
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.domain.dto.user.UserLoginLogDto;
+import org.apache.seatunnel.app.domain.response.user.UserSimpleInfoRes;
+import org.apache.seatunnel.app.security.JwtUtils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
+@Slf4j
+@Aspect
+@Component
+@Order(2)
+public class LoginAspect {
+ @Resource
+ private JwtUtils jwtUtils;
+
+ @Resource
+ private IUserDao userDaoImpl;
+
+ @Pointcut("execution(public * org.apache.seatunnel.app.controller.UserController.login(..))")
+ public void loginPointCut() {
+
+ }
+
+ @AfterReturning(value = "loginPointCut()", returning = "obj")
+ public void check(JoinPoint pjp, Object obj) {
+ final Result<UserSimpleInfoRes> target = (Result<UserSimpleInfoRes>) obj;
+ final UserSimpleInfoRes data = target.getData();
+
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ final HttpServletResponse response = attributes.getResponse();
+ final String token = jwtUtils.genToken(data.toMap());
+ response.setHeader(TOKEN, token);
+
+ final UserLoginLogDto logDto = UserLoginLogDto.builder()
+ .token(token)
+ .tokenStatus(UserTokenStatusEnum.ENABLE.enable())
+ .userId(data.getId())
+ .build();
+ userDaoImpl.insertLoginLog(logDto);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/LogoutAspect.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/LogoutAspect.java
new file mode 100644
index 0000000..3d481c2
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/LogoutAspect.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.aspect;
+
+import static org.apache.seatunnel.server.common.Constants.USER_ID;
+
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@Slf4j
+@Aspect
+@Component
+@Order(2)
+public class LogoutAspect {
+
+ @Resource
+ private IUserDao userDaoImpl;
+
+ @Pointcut("execution(public * org.apache.seatunnel.app.controller.UserController.logout(..))")
+ public void logoutPointCut() {
+
+ }
+
+ @Before("logoutPointCut()")
+ public void check(JoinPoint pjp) {
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = attributes.getRequest();
+ final Integer userId = (Integer) request.getAttribute(USER_ID);
+ userDaoImpl.disableToken(userId);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/UserId.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/UserId.java
new file mode 100644
index 0000000..628e103
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/aspect/UserId.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.aspect;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UserId {
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/DatasourceStatusEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/DatasourceStatusEnum.java
new file mode 100644
index 0000000..b271a5b
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/DatasourceStatusEnum.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum DatasourceStatusEnum {
+ ONLINE(1, "online"),
+ OFFLINE(2, "offline"),
+ DELETED(3, "deleted"),
+ ;
+
+ private final int code;
+ private final String description;
+
+ DatasourceStatusEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Result.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Result.java
new file mode 100644
index 0000000..e08323f
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/Result.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+import org.apache.seatunnel.server.common.SeatunnelErrorEnum;
+
+public class Result<T> {
+
+ private static final Result<Void> OK = success();
+
+ private int code = 0;
+
+ private String msg;
+
+ private T data;
+
+ private Result() {
+ this.data = null;
+ }
+
+ private Result(SeatunnelErrorEnum errorEnum) {
+ this.code = errorEnum.getCode();
+ this.msg = errorEnum.getMsg();
+ this.data = null;
+ }
+
+ private Result(SeatunnelErrorEnum errorEnum, String... messages) {
+ this.code = errorEnum.getCode();
+ this.msg = String.format(errorEnum.getTemplate(), messages);
+ this.data = null;
+ }
+
+ public static <T> Result<T> success() {
+ return new Result<>();
+ }
+
+ public static <T> Result<T> success(T data) {
+ Result<T> result = success();
+ result.setData(data);
+ return result;
+ }
+
+ public static <T> Result<T> failure(SeatunnelErrorEnum errorEnum) {
+ Result<T> result = new Result<>(errorEnum);
+ return result;
+ }
+
+ public static <T> Result<T> failure(SeatunnelErrorEnum errorEnum, String... messages) {
+ Result<T> result = new Result<>(errorEnum, messages);
+ return result;
+ }
+
+ public boolean isSuccess() {
+ return OK.getCode() == this.code;
+ }
+
+ public boolean isFailed() {
+ return !this.isSuccess();
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/RoleTypeEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/RoleTypeEnum.java
new file mode 100644
index 0000000..cd2566a
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/RoleTypeEnum.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum RoleTypeEnum {
+ NORMAL(0, "NORMAL_ROLE"),
+ ADMIN(1, "ADMIN_ROLE"),
+ ;
+
+ private final int code;
+ private final String description;
+
+ RoleTypeEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptParamStatusEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptParamStatusEnum.java
new file mode 100644
index 0000000..56195dd
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptParamStatusEnum.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum ScriptParamStatusEnum {
+ NORMAL(0, "normal"),
+ DELETED(1, "deleted"),
+ ;
+
+ private final int code;
+ private final String description;
+
+ ScriptParamStatusEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptStatusEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptStatusEnum.java
new file mode 100644
index 0000000..17704a2
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptStatusEnum.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum ScriptStatusEnum {
+ UNPUBLISHED(0, "unpublished"),
+ PUBLISHED(1, "published"),
+ DELETED(2, "deleted"),
+ ;
+
+ private final int code;
+ private final String description;
+
+ ScriptStatusEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptTypeEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptTypeEnum.java
new file mode 100644
index 0000000..89d627c
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/ScriptTypeEnum.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum ScriptTypeEnum {
+ OFFLINE(0, "offline"),
+ REALTIME(1, "realtime"),
+ ;
+
+ private final int code;
+ private final String description;
+
+ ScriptTypeEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserStatusEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserStatusEnum.java
new file mode 100644
index 0000000..c62b7e1
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserStatusEnum.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum UserStatusEnum {
+ ENABLE(0, "enable"),
+ DISABLE(1, "disable"),
+ ;
+ private final int code;
+ private final String description;
+
+ UserStatusEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserTokenStatusEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserTokenStatusEnum.java
new file mode 100644
index 0000000..502a964
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserTokenStatusEnum.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum UserTokenStatusEnum {
+ ENABLE,
+ DISABLE,
+ ;
+
+ public boolean enable() {
+ return this == ENABLE;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserTypeEnum.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserTypeEnum.java
new file mode 100644
index 0000000..b583e6f
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/common/UserTypeEnum.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.common;
+
+public enum UserTypeEnum {
+ NORMAL(0, "normal"),
+ ADMIN(1, "admin"),
+ ;
+
+ private final int code;
+ private final String description;
+
+ UserTypeEnum(int code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/Swagger2.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/Swagger2.java
new file mode 100644
index 0000000..3eb93a8
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/config/Swagger2.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class Swagger2{
+ @Bean
+ public Docket createRestApi() {
+
+ return new Docket(DocumentationType.SWAGGER_2)
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("org.apache.seatunnel.app.controller"))
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ private ApiInfo apiInfo() {
+ return new ApiInfoBuilder()
+ .title("seatunnel api docs")
+ .version("1.0.0")
+ .description("API description of Seatunnel")
+ .termsOfServiceUrl("https://seatunnel.apache.org/")
+ .build();
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/AuthController.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/AuthController.java
new file mode 100644
index 0000000..3f720be
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/AuthController.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.controller;
+
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.app.service.IRoleService;
+
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+@RequestMapping("/api/v1/auth")
+@RestController
+public class AuthController {
+
+ @Resource
+ private IRoleService roleServiceImpl;
+
+ @GetMapping("/userRole")
+ @ApiOperation(value = "check relation between user and role", httpMethod = "GET")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "username", value = "user name", dataType = "String"),
+ @ApiImplicitParam(name = "roleName", value = "role name", dataType = "String"),
+ })
+ public Result<Boolean> userRole(@RequestParam("username") @NotNull String username, @RequestParam("roleName") @NotNull String roleName){
+ final boolean b = roleServiceImpl.checkUserRole(username, roleName);
+ return Result.success(b);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/ScriptController.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/ScriptController.java
new file mode 100644
index 0000000..f983cbd
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/ScriptController.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.controller;
+
+import org.apache.seatunnel.app.aspect.UserId;
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.app.domain.request.script.AddEmptyScriptReq;
+import org.apache.seatunnel.app.domain.request.script.PublishScriptReq;
+import org.apache.seatunnel.app.domain.request.script.ScriptListReq;
+import org.apache.seatunnel.app.domain.request.script.UpdateScriptContentReq;
+import org.apache.seatunnel.app.domain.request.script.UpdateScriptParamReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.script.AddEmptyScriptRes;
+import org.apache.seatunnel.app.domain.response.script.ScriptParamRes;
+import org.apache.seatunnel.app.domain.response.script.ScriptSimpleInfoRes;
+import org.apache.seatunnel.app.service.IScriptService;
+
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+import java.util.List;
+
+@RequestMapping("/api/v1/script")
+@RestController
+public class ScriptController {
+ @Resource
+ private IScriptService iScriptService;
+
+ @PostMapping
+ @ApiOperation(value = "add an empty script", httpMethod = "POST")
+ public Result<AddEmptyScriptRes> addEmptyScript(@RequestBody @NotNull AddEmptyScriptReq addEmptyScriptReq,
+ @ApiIgnore @UserId Integer operatorId) {
+ addEmptyScriptReq.setCreatorId(operatorId);
+ return Result.success(iScriptService.addEmptyScript(addEmptyScriptReq));
+ }
+
+ @PutMapping("/{scriptId}/content")
+ @ApiOperation(value = "update script", httpMethod = "PUT")
+ public Result<Void> updateScriptContent(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId,
+ @RequestBody @NotNull String content,
+ @ApiIgnore @UserId Integer operatorId) {
+ final UpdateScriptContentReq req = new UpdateScriptContentReq();
+ req.setScriptId(scriptId);
+ req.setContent(content);
+ req.setMenderId(operatorId);
+
+ iScriptService.updateScriptContent(req);
+ return Result.success();
+ }
+
+ @DeleteMapping("/{scriptId}")
+ @ApiOperation(value = "delete script", httpMethod = "DELETE")
+ public Result<Void> delete(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId) {
+ iScriptService.delete(scriptId);
+ return Result.success();
+ }
+
+ @GetMapping
+ @ApiOperation(value = "script list", httpMethod = "GET")
+ public Result<PageInfo<ScriptSimpleInfoRes>> list(@ApiParam(value = "script name") @RequestParam(required = false) String name,
+ @ApiParam(value = "script status") @RequestParam(required = false) Byte status,
+ @ApiParam(value = "page num", required = true) @RequestParam Integer pageNo,
+ @ApiParam(value = "page size", required = true) @RequestParam Integer pageSize) {
+
+ final ScriptListReq req = new ScriptListReq();
+ req.setName(name);
+ req.setStatus(status);
+ req.setPageNo(pageNo);
+ req.setPageSize(pageSize);
+
+ return Result.success(iScriptService.list(req));
+ }
+
+ @GetMapping("/{scriptId}/content")
+ @ApiOperation(value = "fetch script content", httpMethod = "GET")
+ public Result<String> fetchScriptContent(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId) {
+ return Result.success(iScriptService.fetchScriptContent(scriptId));
+ }
+
+ @PutMapping("/{scriptId}/param")
+ @ApiOperation(value = "update script param", httpMethod = "PUT")
+ public Result<Void> updateScriptParam(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId,
+ @RequestBody @NotNull UpdateScriptParamReq updateScriptParamReq) {
+ updateScriptParamReq.setScriptId(scriptId);
+ iScriptService.updateScriptParam(updateScriptParamReq);
+ return Result.success();
+ }
+
+ @GetMapping("/{scriptId}/param")
+ @ApiOperation(value = "fetch script param", httpMethod = "GET")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "script id", dataType = "Integer"),
+ })
+ public Result<List<ScriptParamRes>> fetchScriptParam(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId) {
+ return Result.success(iScriptService.fetchScriptParam(scriptId));
+ }
+
+ @PatchMapping("/{scriptId}/publish")
+ @ApiOperation(value = "publish script", httpMethod = "PATCH")
+ public Result<Void> publish(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId,
+ @ApiIgnore @UserId Integer operatorId) {
+
+ final PublishScriptReq req = new PublishScriptReq();
+ req.setScriptId(scriptId);
+ req.setOperatorId(operatorId);
+
+ iScriptService.publishScript(req);
+ return Result.success();
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/TaskController.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/TaskController.java
new file mode 100644
index 0000000..5ca3ace
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/TaskController.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.controller;
+
+import org.apache.seatunnel.app.aspect.UserId;
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.app.domain.request.task.ExecuteReq;
+import org.apache.seatunnel.app.domain.request.task.InstanceListReq;
+import org.apache.seatunnel.app.domain.request.task.InstanceLogRes;
+import org.apache.seatunnel.app.domain.request.task.JobListReq;
+import org.apache.seatunnel.app.domain.request.task.RecycleScriptReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.task.InstanceSimpleInfoRes;
+import org.apache.seatunnel.app.domain.response.task.JobSimpleInfoRes;
+import org.apache.seatunnel.app.service.ITaskService;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+@RequestMapping("/api/v1/task")
+@RestController
+public class TaskController {
+
+ @Resource
+ private ITaskService iTaskService;
+
+ @PatchMapping("/{scriptId}/recycle")
+ @ApiOperation(value = "recycle script", httpMethod = "PATCH")
+ Result<Void> recycle(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId,
+ @ApiIgnore @UserId Integer operatorId) {
+ final RecycleScriptReq req = new RecycleScriptReq();
+ req.setScriptId(scriptId);
+ req.setOperatorId(operatorId);
+
+ iTaskService.recycleScriptFromScheduler(req);
+ return Result.success();
+ }
+
+ @GetMapping("/job")
+ @ApiOperation(value = "list job", httpMethod = "GET")
+ Result<PageInfo<JobSimpleInfoRes>> listJob(@ApiParam(value = "job name") @RequestParam(required = false) String name,
+ @ApiParam(value = "page num", required = true) @RequestParam Integer pageNo,
+ @ApiParam(value = "page size", required = true) @RequestParam Integer pageSize) {
+ final JobListReq req = new JobListReq();
+ req.setName(name);
+ req.setPageNo(pageNo);
+ req.setPageSize(pageSize);
+
+ return Result.success(iTaskService.listJob(req));
+ }
+
+ @GetMapping("/instance")
+ @ApiOperation(value = "list instance", httpMethod = "GET")
+ Result<PageInfo<InstanceSimpleInfoRes>> listInstance(@ApiParam(value = "job name") @RequestParam(required = false) String name,
+ @ApiParam(value = "page num", required = true) @RequestParam Integer pageNo,
+ @ApiParam(value = "page size", required = true) @RequestParam Integer pageSize) {
+ final InstanceListReq req = new InstanceListReq();
+ req.setName(name);
+ req.setPageNo(pageNo);
+ req.setPageSize(pageSize);
+
+ return Result.success(iTaskService.listInstance(req));
+ }
+
+ @PostMapping("/{scriptId}/execute")
+ @ApiOperation(value = "execute script temporary", httpMethod = "POST")
+ Result<InstanceSimpleInfoRes> tmpExecute(@ApiParam(value = "script id", required = true) @PathVariable(value = "scriptId") Integer scriptId,
+ @RequestBody @NotNull ExecuteReq req,
+ @ApiIgnore @UserId Integer operatorId) {
+ req.setScriptId(scriptId);
+ req.setOperatorId(operatorId);
+
+ return Result.success(iTaskService.tmpExecute(req));
+ }
+
+ @GetMapping("/{taskInstanceId}")
+ @ApiOperation(value = "query instance log", httpMethod = "GET")
+ Result<InstanceLogRes> queryInstanceLog(@ApiParam(value = "task instance id", required = true) @PathVariable(value = "taskInstanceId") Long taskInstanceId) {
+ return Result.success(iTaskService.queryInstanceLog(taskInstanceId));
+ }
+
+ @PatchMapping("/{taskInstanceId}")
+ @ApiOperation(value = "kill running instance", httpMethod = "POST")
+ Result<Void> kill(@ApiParam(value = "task instance id", required = true) @PathVariable(value = "taskInstanceId") Long taskInstanceId) {
+ iTaskService.kill(taskInstanceId);
+ return Result.success();
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java
new file mode 100644
index 0000000..59a59ee
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/controller/UserController.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.controller;
+
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.app.domain.request.user.AddUserReq;
+import org.apache.seatunnel.app.domain.request.user.UpdateUserReq;
+import org.apache.seatunnel.app.domain.request.user.UserListReq;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.user.AddUserRes;
+import org.apache.seatunnel.app.domain.response.user.UserSimpleInfoRes;
+import org.apache.seatunnel.app.service.IUserService;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+
+@RequestMapping("/api/v1/user")
+@RestController
+public class UserController {
+
+ @Resource
+ private IUserService iUserService;
+
+ @PostMapping
+ @ApiOperation(value = "add user", httpMethod = "POST")
+ public Result<AddUserRes> add(@RequestBody @NotNull AddUserReq addReq) {
+ return Result.success(iUserService.add(addReq));
+ }
+
+ @PutMapping("/{userId}")
+ @ApiOperation(value = "update user", httpMethod = "PUT")
+ public Result<Void> update(@ApiParam(value = "user id", required = true) @PathVariable(value = "userId") Integer userId,
+ @RequestBody @NotNull UpdateUserReq updateReq) {
+ updateReq.setUserId(userId);
+
+ iUserService.update(updateReq);
+ return Result.success();
+ }
+
+ @DeleteMapping("/{userId}")
+ @ApiOperation(value = "delete user", httpMethod = "DELETE")
+ public Result<Void> delete(@ApiParam(value = "user id", required = true) @PathVariable(value = "userId") Integer userId) {
+ iUserService.delete(userId);
+ return Result.success();
+ }
+
+ @GetMapping
+ @ApiOperation(value = "user list", httpMethod = "GET")
+ public Result<PageInfo<UserSimpleInfoRes>> list(@ApiParam(value = "job name") @RequestParam(required = false) String name,
+ @ApiParam(value = "page num", required = true) @RequestParam Integer pageNo,
+ @ApiParam(value = "page size", required = true) @RequestParam Integer pageSize) {
+ final UserListReq req = new UserListReq();
+ req.setName(name);
+ req.setPageNo(pageNo);
+ req.setPageSize(pageSize);
+
+ return Result.success(iUserService.list(req));
+ }
+
+ @PatchMapping("/{userId}/enable")
+ @ApiOperation(value = "enable a user", httpMethod = "PATCH")
+ public Result<Void> enable(@ApiParam(value = "user id", required = true) @PathVariable(value = "userId") Integer userId) {
+ iUserService.enable(userId);
+ return Result.success();
+ }
+
+ @PutMapping("/{userId}/disable")
+ @ApiOperation(value = "disable a user", httpMethod = "PUT")
+ public Result<Void> disable(@ApiParam(value = "user id", required = true) @PathVariable(value = "userId") Integer userId) {
+ iUserService.disable(userId);
+ return Result.success();
+ }
+
+ @PostMapping("/login")
+ public Result<UserSimpleInfoRes> login(@RequestBody UserLoginReq req) {
+ return Result.success(iUserService.login(req));
+ }
+
+ @PatchMapping("/logout")
+ public Result<Void> logout() {
+ return Result.success();
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IRoleDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IRoleDao.java
new file mode 100644
index 0000000..e7552e1
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IRoleDao.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.Role;
+
+public interface IRoleDao {
+
+ void add(Role role);
+
+ Role getByRoleName(String roleName);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IRoleUserRelationDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IRoleUserRelationDao.java
new file mode 100644
index 0000000..d5f0da7
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IRoleUserRelationDao.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.RoleUserRelation;
+
+public interface IRoleUserRelationDao {
+
+ void add(RoleUserRelation roleUserRelation);
+
+ RoleUserRelation getByUserAndRole(Integer userId, Integer roleId);
+
+ void deleteByUserId(Integer userId);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/ISchedulerConfigDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/ISchedulerConfigDao.java
new file mode 100644
index 0000000..1844db1
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/ISchedulerConfigDao.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.SchedulerConfig;
+
+public interface ISchedulerConfigDao {
+ boolean exists(int scriptId);
+
+ SchedulerConfig getSchedulerConfig(int scriptId);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptDao.java
new file mode 100644
index 0000000..0178b58
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptDao.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.Script;
+import org.apache.seatunnel.app.domain.dto.script.AddEmptyScriptDto;
+import org.apache.seatunnel.app.domain.dto.script.CheckScriptDuplicateDto;
+import org.apache.seatunnel.app.domain.dto.script.ListScriptsDto;
+import org.apache.seatunnel.app.domain.dto.script.UpdateScriptContentDto;
+import org.apache.seatunnel.server.common.PageData;
+
+public interface IScriptDao {
+ void checkScriptDuplicate(CheckScriptDuplicateDto dto);
+
+ int addEmptyScript(AddEmptyScriptDto dto);
+
+ Script getScript(Integer id);
+
+ void updateScriptContent(UpdateScriptContentDto dto);
+
+ void deleteScript(int id);
+
+ PageData<Script> list(ListScriptsDto dto, Integer pageNo, Integer pageSize);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptJobApplyDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptJobApplyDao.java
new file mode 100644
index 0000000..0efdae2
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptJobApplyDao.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.ScriptJobApply;
+import org.apache.seatunnel.app.domain.dto.job.ScriptJobApplyDto;
+
+public interface IScriptJobApplyDao {
+ void insertOrUpdate(ScriptJobApplyDto dto);
+
+ ScriptJobApply getByScriptId(Integer id);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptParamDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptParamDao.java
new file mode 100644
index 0000000..2e06895
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IScriptParamDao.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.ScriptParam;
+import org.apache.seatunnel.app.domain.dto.script.UpdateScriptParamDto;
+
+import java.util.List;
+
+public interface IScriptParamDao {
+ List<ScriptParam> getParamsByScriptId(int id);
+
+ void updateStatusByScriptId(int scriptId, int code);
+
+ void batchInsert(UpdateScriptParamDto dto);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java
new file mode 100644
index 0000000..db2f166
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/IUserDao.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao;
+
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.dal.entity.UserLoginLog;
+import org.apache.seatunnel.app.domain.dto.user.ListUserDto;
+import org.apache.seatunnel.app.domain.dto.user.UpdateUserDto;
+import org.apache.seatunnel.app.domain.dto.user.UserLoginLogDto;
+import org.apache.seatunnel.server.common.PageData;
+
+public interface IUserDao {
+ int add(UpdateUserDto dto);
+
+ void checkUserExists(String username);
+
+ void update(UpdateUserDto dto);
+
+ void delete(int id);
+
+ void enable(int id);
+
+ void disable(int id);
+
+ PageData<User> list(ListUserDto dto, int pageNo, int pageSize);
+
+ User getById(int operatorId);
+
+ User getByName(String user);
+
+ User checkPassword(String username, String password);
+
+ long insertLoginLog(UserLoginLogDto dto);
+
+ void disableToken(int userId);
+
+ UserLoginLog getLastLoginLog(Integer userId);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/RoleDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/RoleDaoImpl.java
new file mode 100644
index 0000000..ae0b326
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/RoleDaoImpl.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import org.apache.seatunnel.app.dal.dao.IRoleDao;
+import org.apache.seatunnel.app.dal.entity.Role;
+import org.apache.seatunnel.app.dal.mapper.RoleMapper;
+
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+@Repository
+public class RoleDaoImpl implements IRoleDao {
+
+ @Resource
+ private RoleMapper roleMapper;
+
+ @Override
+ public void add(Role role){
+ roleMapper.insert(role);
+ }
+
+ @Override
+ public Role getByRoleName(String roleName) {
+ return roleMapper.selectByRole(roleName);
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/RoleUserRelationDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/RoleUserRelationDaoImpl.java
new file mode 100644
index 0000000..8bc66dd
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/RoleUserRelationDaoImpl.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import org.apache.seatunnel.app.dal.dao.IRoleUserRelationDao;
+import org.apache.seatunnel.app.dal.entity.RoleUserRelation;
+import org.apache.seatunnel.app.dal.mapper.RoleUserRelationMapper;
+
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+@Repository
+public class RoleUserRelationDaoImpl implements IRoleUserRelationDao {
+
+ @Resource
+ private RoleUserRelationMapper roleUserRelationMapper;
+
+ @Override
+ public void add(RoleUserRelation roleUserRelation){
+ roleUserRelationMapper.insert(roleUserRelation);
+ }
+
+ @Override
+ public RoleUserRelation getByUserAndRole(Integer userId, Integer roleId) {
+ final RoleUserRelation roleUserRelation = roleUserRelationMapper.selectByUserIdAndRoleId(userId, roleId);
+ return roleUserRelation;
+ }
+
+ @Override
+ public void deleteByUserId(Integer userId) {
+ roleUserRelationMapper.deleteByUserId(userId);
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/SchedulerConfigDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/SchedulerConfigDaoImpl.java
new file mode 100644
index 0000000..fa78042
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/SchedulerConfigDaoImpl.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import org.apache.seatunnel.app.dal.dao.ISchedulerConfigDao;
+import org.apache.seatunnel.app.dal.entity.SchedulerConfig;
+import org.apache.seatunnel.app.dal.mapper.SchedulerConfigMapper;
+
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import java.util.Objects;
+
+@Repository
+public class SchedulerConfigDaoImpl implements ISchedulerConfigDao {
+ @Resource
+ private SchedulerConfigMapper schedulerConfigMapper;
+
+ @Override
+ public boolean exists(int scriptId) {
+ SchedulerConfig config = schedulerConfigMapper.selectByScriptId(scriptId);
+ return Objects.nonNull(config);
+ }
+
+ @Override
+ public SchedulerConfig getSchedulerConfig(int scriptId) {
+ return schedulerConfigMapper.selectByScriptId(scriptId);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptDaoImpl.java
new file mode 100644
index 0000000..0f2c735
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptDaoImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.SCRIPT_ALREADY_EXIST;
+import static com.google.common.base.Preconditions.checkState;
+
+import org.apache.seatunnel.app.common.ScriptStatusEnum;
+import org.apache.seatunnel.app.dal.dao.IScriptDao;
+import org.apache.seatunnel.app.dal.entity.Script;
+import org.apache.seatunnel.app.dal.mapper.ScriptMapper;
+import org.apache.seatunnel.app.domain.dto.script.AddEmptyScriptDto;
+import org.apache.seatunnel.app.domain.dto.script.CheckScriptDuplicateDto;
+import org.apache.seatunnel.app.domain.dto.script.ListScriptsDto;
+import org.apache.seatunnel.app.domain.dto.script.UpdateScriptContentDto;
+import org.apache.seatunnel.server.common.PageData;
+
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+import java.util.Objects;
+
+@Repository
+public class ScriptDaoImpl implements IScriptDao {
+
+ @Resource
+ private ScriptMapper scriptMapper;
+
+ @Override
+ public void checkScriptDuplicate(CheckScriptDuplicateDto dto) {
+ final Script script = scriptMapper.selectByNameAndCreatorAndStatusNotEq(dto.getName(), dto.getCreatorId(), (byte) ScriptStatusEnum.DELETED.getCode());
+ checkState(Objects.isNull(script), String.format(SCRIPT_ALREADY_EXIST.getTemplate(), dto.getName()));
+ }
+
+ @Override
+ public int addEmptyScript(AddEmptyScriptDto dto) {
+ final Script script = new Script();
+ script.setName(dto.getName());
+ script.setType(dto.getType());
+ script.setStatus(dto.getStatus());
+ script.setCreatorId(dto.getCreatorId());
+ script.setMenderId(dto.getMenderId());
+ scriptMapper.insert(script);
+ return script.getId();
+ }
+
+ @Override
+ public Script getScript(Integer id) {
+ return scriptMapper.selectByPrimaryKey(id);
+ }
+
+ @Override
+ public void updateScriptContent(UpdateScriptContentDto dto) {
+ scriptMapper.updateContentByPrimaryKey(dto.getId(), dto.getContent(), dto.getContentMd5(), dto.getMenderId());
+ }
+
+ @Override
+ public void deleteScript(int id) {
+ scriptMapper.updateStatus(id, (byte) ScriptStatusEnum.DELETED.getCode());
+ }
+
+ @Override
+ public PageData<Script> list(ListScriptsDto dto, Integer pageNo, Integer pageSize) {
+ final Script script = new Script();
+ script.setName(dto.getName());
+ script.setStatus(dto.getStatus());
+
+ final List<Script> scripts = scriptMapper.selectBySelectiveAndPage(script, pageNo * pageSize, pageSize);
+ int count = scriptMapper.countBySelectiveAndPage(script);
+
+ return new PageData<Script>(count, scripts);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptJobApplyDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptJobApplyDaoImpl.java
new file mode 100644
index 0000000..1b5b1d5
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptJobApplyDaoImpl.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import org.apache.seatunnel.app.dal.dao.IScriptJobApplyDao;
+import org.apache.seatunnel.app.dal.entity.ScriptJobApply;
+import org.apache.seatunnel.app.dal.mapper.ScriptJobApplyMapper;
+import org.apache.seatunnel.app.domain.dto.job.ScriptJobApplyDto;
+
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import java.util.Objects;
+
+@Repository
+public class ScriptJobApplyDaoImpl implements IScriptJobApplyDao {
+
+ @Resource
+ private ScriptJobApplyMapper scriptJobApplyMapper;
+
+ @Override
+ public void insertOrUpdate(ScriptJobApplyDto dto) {
+ ScriptJobApply apply = scriptJobApplyMapper.selectByScriptId(dto.getScriptId());
+ if (Objects.isNull(apply)) {
+ apply = new ScriptJobApply();
+ apply.setScriptId(dto.getScriptId());
+ apply.setJobId(dto.getJobId());
+ apply.setOperatorId(dto.getUserId());
+ apply.setSchedulerConfigId(dto.getSchedulerConfigId());
+ scriptJobApplyMapper.insert(apply);
+ } else {
+ apply.setJobId(dto.getJobId());
+ apply.setOperatorId(dto.getUserId());
+ apply.setSchedulerConfigId(dto.getSchedulerConfigId());
+ scriptJobApplyMapper.update(apply);
+ }
+ }
+
+ @Override
+ public ScriptJobApply getByScriptId(Integer id) {
+ return scriptJobApplyMapper.selectByScriptId(id);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptParamDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptParamDaoImpl.java
new file mode 100644
index 0000000..fad680c
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/ScriptParamDaoImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import org.apache.seatunnel.app.common.ScriptParamStatusEnum;
+import org.apache.seatunnel.app.dal.dao.IScriptParamDao;
+import org.apache.seatunnel.app.dal.entity.ScriptParam;
+import org.apache.seatunnel.app.dal.mapper.ScriptParamMapper;
+import org.apache.seatunnel.app.domain.dto.script.UpdateScriptParamDto;
+
+import com.google.common.collect.Lists;
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public class ScriptParamDaoImpl implements IScriptParamDao {
+ @Resource
+ private ScriptParamMapper scriptParamMapper;
+
+ @Override
+ public List<ScriptParam> getParamsByScriptId(int id) {
+ return scriptParamMapper.selectByScriptId(id);
+ }
+
+ @Override
+ public void updateStatusByScriptId(int scriptId, int code) {
+ scriptParamMapper.updateStatusByScriptId(scriptId, (byte) code);
+ }
+
+ @Override
+ public void batchInsert(UpdateScriptParamDto dto) {
+ final Map<String, String> keyAndValue = dto.getParams();
+ final List<ScriptParam> scriptParams = Lists.newArrayListWithCapacity(keyAndValue.size());
+ keyAndValue.forEach((k, v) -> {
+ final ScriptParam scriptParam = new ScriptParam();
+ scriptParam.setStatus((byte) ScriptParamStatusEnum.NORMAL.getCode());
+ scriptParam.setKey(k);
+ scriptParam.setValue(v);
+ scriptParam.setScriptId(dto.getScriptId());
+ scriptParams.add(scriptParam);
+ });
+
+ scriptParamMapper.batchInsert(scriptParams);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java
new file mode 100644
index 0000000..a94ee5e
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/dao/impl/UserDaoImpl.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.dao.impl;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.NO_SUCH_USER;
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.USER_ALREADY_EXISTS;
+import static com.google.common.base.Preconditions.checkState;
+
+import org.apache.seatunnel.app.common.UserStatusEnum;
+import org.apache.seatunnel.app.common.UserTokenStatusEnum;
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.dal.entity.UserLoginLog;
+import org.apache.seatunnel.app.dal.mapper.UserLoginLogMapper;
+import org.apache.seatunnel.app.dal.mapper.UserMapper;
+import org.apache.seatunnel.app.domain.dto.user.ListUserDto;
+import org.apache.seatunnel.app.domain.dto.user.UpdateUserDto;
+import org.apache.seatunnel.app.domain.dto.user.UserLoginLogDto;
+import org.apache.seatunnel.server.common.PageData;
+
+import org.springframework.stereotype.Repository;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+import java.util.Objects;
+
+@Repository
+public class UserDaoImpl implements IUserDao {
+ @Resource
+ private UserMapper userMapper;
+ @Resource
+ private UserLoginLogMapper userLoginLogMapper;
+
+ @Override
+ public int add(UpdateUserDto dto) {
+ final User user = new User();
+ user.setUsername(dto.getUsername());
+ user.setPassword(dto.getPassword());
+ user.setType((byte) dto.getType());
+ user.setStatus((byte) dto.getStatus());
+
+ userMapper.insert(user);
+ return user.getId();
+ }
+
+ @Override
+ public void checkUserExists(String username) {
+ User user = userMapper.selectByName(username);
+ checkState(Objects.isNull(user), String.format(USER_ALREADY_EXISTS.getTemplate(), username));
+ }
+
+ @Override
+ public void update(UpdateUserDto dto) {
+ final User user = new User();
+ user.setUsername(dto.getUsername());
+ user.setPassword(dto.getPassword());
+ user.setType((byte) dto.getType());
+ user.setStatus((byte) dto.getStatus());
+ user.setId(dto.getId());
+
+ final int i = userMapper.updateByPrimaryKey(user);
+ checkState(i == 1, NO_SUCH_USER.getTemplate());
+ }
+
+ @Override
+ public void delete(int id) {
+ userMapper.deleteByPrimaryKey(id);
+ }
+
+ @Override
+ public void enable(int id) {
+ userMapper.updateStatus(id, (byte) UserStatusEnum.ENABLE.getCode());
+ }
+
+ @Override
+ public void disable(int id) {
+ userMapper.updateStatus(id, (byte) UserStatusEnum.DISABLE.getCode());
+ }
+
+ @Override
+ public PageData<User> list(ListUserDto dto, int pageNo, int pageSize) {
+ final User user = new User();
+ user.setUsername(dto.getName());
+
+ int count = userMapper.countBySelective(user);
+ final List<User> userList = userMapper.selectBySelectiveAndPage(user, pageNo * pageSize, pageSize);
+ return new PageData<User>(count, userList);
+ }
+
+ @Override
+ public User getById(int operatorId) {
+ return userMapper.selectByPrimaryKey(operatorId);
+ }
+
+ @Override
+ public User getByName(String user) {
+ return userMapper.selectByName(user);
+ }
+
+ @Override
+ public User checkPassword(String username, String password) {
+ return userMapper.selectByNameAndPasswd(username, password);
+ }
+
+ @Override
+ public long insertLoginLog(UserLoginLogDto dto) {
+ final UserLoginLog log = new UserLoginLog();
+ log.setToken(dto.getToken());
+ log.setTokenStatus(dto.getTokenStatus());
+ log.setUserId(dto.getUserId());
+
+ userLoginLogMapper.insert(log);
+ return log.getId();
+ }
+
+ @Override
+ public void disableToken(int userId) {
+ userLoginLogMapper.updateStatus(userId, UserTokenStatusEnum.DISABLE.enable());
+ }
+
+ @Override
+ public UserLoginLog getLastLoginLog(Integer userId) {
+ return userLoginLogMapper.checkLastTokenEnable(userId);
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/Role.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/Role.java
new file mode 100644
index 0000000..f3e218c
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/Role.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class Role {
+
+ private Integer id;
+
+ private Integer type;
+
+ private String roleName;
+
+ private String description;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/RoleUserRelation.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/RoleUserRelation.java
new file mode 100644
index 0000000..7eeb44c
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/RoleUserRelation.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class RoleUserRelation {
+
+ private Integer id;
+
+ private Integer roleId;
+
+ private Integer userId;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/SchedulerConfig.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/SchedulerConfig.java
new file mode 100644
index 0000000..b529c30
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/SchedulerConfig.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SchedulerConfig {
+ private Integer id;
+
+ private Integer scriptId;
+
+ private String triggerExpression;
+
+ private Integer retryTimes;
+
+ private Integer retryInterval;
+
+ private Date activeStartTime;
+
+ private Date activeEndTime;
+
+ private Date createTime;
+
+ private Date updateTime;
+
+ private Integer creatorId;
+
+ private Integer updateId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/Script.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/Script.java
new file mode 100644
index 0000000..3b1d7db
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/Script.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class Script {
+ private Integer id;
+
+ private String name;
+
+ private Byte type;
+
+ private Byte status;
+
+ private String content;
+
+ private String contentMd5;
+
+ private Integer creatorId;
+
+ private Integer menderId;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/ScriptJobApply.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/ScriptJobApply.java
new file mode 100644
index 0000000..d986bc5
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/ScriptJobApply.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class ScriptJobApply {
+ private Integer id;
+
+ private Integer scriptId;
+
+ private Integer schedulerConfigId;
+
+ private Long jobId;
+
+ private Integer operatorId;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/ScriptParam.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/ScriptParam.java
new file mode 100644
index 0000000..96d9b31
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/ScriptParam.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class ScriptParam {
+ private Integer id;
+
+ private Integer scriptId;
+
+ private String key;
+
+ private String value;
+
+ private Byte status;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
new file mode 100644
index 0000000..7377765
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/User.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class User {
+ private Integer id;
+
+ private String username;
+
+ private String password;
+
+ private Byte status;
+
+ private Byte type;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/UserLoginLog.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/UserLoginLog.java
new file mode 100644
index 0000000..008d46d
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/entity/UserLoginLog.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class UserLoginLog {
+ private Long id;
+
+ private Integer userId;
+
+ private String token;
+
+ private Boolean tokenStatus;
+
+ private Date createTime;
+
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/RoleMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/RoleMapper.java
new file mode 100644
index 0000000..4e81a45
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/RoleMapper.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.Role;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface RoleMapper {
+
+ int insert(Role record);
+
+ Role selectByRole(@Param("roleName") String roleName);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/RoleUserRelationMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/RoleUserRelationMapper.java
new file mode 100644
index 0000000..5ba02dc
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/RoleUserRelationMapper.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.RoleUserRelation;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface RoleUserRelationMapper {
+
+ int insert(RoleUserRelation record);
+
+ RoleUserRelation selectByUserIdAndRoleId(@Param("userId")Integer userId, @Param("roleId")Integer roleId);
+
+ void deleteByUserId(@Param("userId")Integer userId);
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/SchedulerConfigMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/SchedulerConfigMapper.java
new file mode 100644
index 0000000..ab4ee6c
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/SchedulerConfigMapper.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.SchedulerConfig;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface SchedulerConfigMapper {
+ int deleteByPrimaryKey(Integer id);
+
+ int insert(SchedulerConfig record);
+
+ SchedulerConfig selectByPrimaryKey(Integer id);
+
+ SchedulerConfig selectByScriptId(@Param("scriptId") int scriptId);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptJobApplyMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptJobApplyMapper.java
new file mode 100644
index 0000000..4115fd9
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptJobApplyMapper.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.ScriptJobApply;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface ScriptJobApplyMapper {
+ int deleteByPrimaryKey(Integer id);
+
+ int insert(ScriptJobApply record);
+
+ ScriptJobApply selectByPrimaryKey(Integer id);
+
+ void update(ScriptJobApply record);
+
+ ScriptJobApply selectByScriptId(@Param("scriptId") int scriptId);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptMapper.java
new file mode 100644
index 0000000..0732ad0
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptMapper.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.Script;
+
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ScriptMapper {
+ Script selectByPrimaryKey(Integer id);
+
+ void insert(Script script);
+
+ void updateContentByPrimaryKey(@Param("id") int id, @Param("content") String content, @Param("contentMd5") String contentMd5, @Param("menderId") int menderId);
+
+ void updateStatus(@Param("id") int id, @Param("code") byte code);
+
+ List<Script> selectBySelectiveAndPage(@Param("script") Script script, @Param("start") int start, @Param("offset") int offset);
+
+ Script selectByNameAndCreatorAndStatusNotEq(@Param("name") String name, @Param("creatorId") int creatorId, @Param("status") byte status);
+
+ int countBySelectiveAndPage(@Param("script") Script script);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptParamMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptParamMapper.java
new file mode 100644
index 0000000..aa473c4
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/ScriptParamMapper.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.ScriptParam;
+
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ScriptParamMapper {
+ ScriptParam selectByPrimaryKey(Integer id);
+
+ List<ScriptParam> selectByScriptId(@Param("scriptId") int scriptId);
+
+ void updateStatusByScriptId(@Param("scriptId") int scriptId, @Param("code") byte code);
+
+ void batchInsert(@Param("params") List<ScriptParam> params);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserLoginLogMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserLoginLogMapper.java
new file mode 100644
index 0000000..4480116
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserLoginLogMapper.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.UserLoginLog;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface UserLoginLogMapper {
+ int insert(UserLoginLog userLoginLog);
+
+ int updateStatus(@Param("userId") int userId, @Param("enable") boolean enable);
+
+ UserLoginLog checkLastTokenEnable(@Param("userId") Integer userId);
+}
+
+
+
+
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java
new file mode 100644
index 0000000..3bd74f2
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/dal/mapper/UserMapper.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.dal.mapper;
+
+import org.apache.seatunnel.app.dal.entity.User;
+
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface UserMapper {
+ User selectByPrimaryKey(@Param("id") Integer id);
+
+ void insert(User user);
+
+ int updateByPrimaryKey(User user);
+
+ void deleteByPrimaryKey(@Param("id") int id);
+
+ List<User> selectBySelectiveAndPage(@Param("user") User user, @Param("start") int start, @Param("offset") int offset);
+
+ void updateStatus(@Param("id") int id, @Param("status") byte status);
+
+ User selectByName(@Param("username") String username);
+
+ int countBySelective(@Param("user") User user);
+
+ User selectByNameAndPasswd(@Param("username") String username, @Param("password") String password);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/PushScriptDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/PushScriptDto.java
new file mode 100644
index 0000000..c17a22b
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/PushScriptDto.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.job;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class PushScriptDto {
+ private int scriptId;
+ private int userId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/RecycleScriptDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/RecycleScriptDto.java
new file mode 100644
index 0000000..b8480a3
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/RecycleScriptDto.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.job;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class RecycleScriptDto {
+ private int scriptId;
+ private int operatorId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/ScriptJobApplyDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/ScriptJobApplyDto.java
new file mode 100644
index 0000000..2b1ffe9
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/job/ScriptJobApplyDto.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.job;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class ScriptJobApplyDto {
+ private int scriptId;
+ private int schedulerConfigId;
+ private long jobId;
+ private int userId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/AddEmptyScriptDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/AddEmptyScriptDto.java
new file mode 100644
index 0000000..f2245c4
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/AddEmptyScriptDto.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.script;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class AddEmptyScriptDto {
+ private String name;
+ private byte type;
+ private int creatorId;
+ private int menderId;
+ private byte status;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/CheckScriptDuplicateDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/CheckScriptDuplicateDto.java
new file mode 100644
index 0000000..f1c9576
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/CheckScriptDuplicateDto.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.script;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class CheckScriptDuplicateDto {
+ private String name;
+ private Integer creatorId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/ListScriptsDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/ListScriptsDto.java
new file mode 100644
index 0000000..8d15ccc
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/ListScriptsDto.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.script;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class ListScriptsDto {
+ private String name;
+ private Byte status;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/UpdateScriptContentDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/UpdateScriptContentDto.java
new file mode 100644
index 0000000..b0bf1c1
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/UpdateScriptContentDto.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.script;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class UpdateScriptContentDto {
+ private int id;
+ private String content;
+ private String contentMd5;
+ private int menderId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/UpdateScriptParamDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/UpdateScriptParamDto.java
new file mode 100644
index 0000000..69f7551
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/script/UpdateScriptParamDto.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.script;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Map;
+
+@Builder
+@Data
+public class UpdateScriptParamDto {
+ private int scriptId;
+ private Map<String, String> params;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/ListUserDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/ListUserDto.java
new file mode 100644
index 0000000..5fe2089
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/ListUserDto.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.user;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class ListUserDto {
+ private String name;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
new file mode 100644
index 0000000..d65383e
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UpdateUserDto.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.user;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class UpdateUserDto {
+ private Integer id;
+ private String username;
+ private String password;
+ private int status;
+ private int type;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UserLoginLogDto.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UserLoginLogDto.java
new file mode 100644
index 0000000..55af565
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/dto/user/UserLoginLogDto.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.dto.user;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class UserLoginLogDto {
+ private Long id;
+
+ private Integer userId;
+
+ private String token;
+
+ private Boolean tokenStatus;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/BasePageReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/BasePageReq.java
new file mode 100644
index 0000000..a04f8af
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/BasePageReq.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class BasePageReq {
+ @ApiModelProperty(value = "page number", required = true, dataType = "Integer")
+ private Integer pageNo;
+ @ApiModelProperty(value = "page size", required = true, dataType = "Integer")
+ private Integer pageSize;
+
+ public int getRealPageNo() {
+ return pageNo - 1;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/AddEmptyScriptReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/AddEmptyScriptReq.java
new file mode 100644
index 0000000..4bd650d
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/AddEmptyScriptReq.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.script;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "addEmptyScriptReq", description = "add a new empty script")
+public class AddEmptyScriptReq {
+ @ApiModelProperty(value = "script name", required = true, dataType = "String")
+ private String name;
+ @ApiModelProperty(value = "script type", required = true, dataType = "Byte")
+ @NotNull
+ private Byte type;
+ @ApiModelProperty(value = "script creator id", required = true, dataType = "Integer", hidden = true)
+ @NotNull
+ private Integer creatorId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/PublishScriptReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/PublishScriptReq.java
new file mode 100644
index 0000000..1b1352f
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/PublishScriptReq.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.script;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "publishScriptReq", description = "publish script")
+public class PublishScriptReq {
+ @ApiModelProperty(value = "script id", required = true, dataType = "Integer")
+ @NotNull
+ private int scriptId;
+ @ApiModelProperty(value = "operator id", required = true, dataType = "Integer")
+ @NotNull
+ private int operatorId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/ScriptListReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/ScriptListReq.java
new file mode 100644
index 0000000..3ac64ba
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/ScriptListReq.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.script;
+
+import org.apache.seatunnel.app.domain.request.BasePageReq;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel(value = "scriptListReq", description = "script list")
+@Data
+public class ScriptListReq extends BasePageReq {
+ @ApiModelProperty(value = "script name", required = false, dataType = "String")
+ private String name;
+ @ApiModelProperty(value = "script status", required = false, dataType = "Integer")
+ private Byte status;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/UpdateScriptContentReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/UpdateScriptContentReq.java
new file mode 100644
index 0000000..5a70d69
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/UpdateScriptContentReq.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.script;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "updateScriptContentReq", description = "update an exist script content request")
+public class UpdateScriptContentReq {
+ @ApiModelProperty(value = "script id", required = true, dataType = "Integer", hidden = true)
+ private Integer scriptId;
+ @ApiModelProperty(value = "script id", required = true, dataType = "Integer")
+ @NotBlank
+ private String content;
+ @ApiModelProperty(value = "script mender id", required = true, dataType = "Integer", hidden = true)
+ @NotNull
+ private Integer menderId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/UpdateScriptParamReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/UpdateScriptParamReq.java
new file mode 100644
index 0000000..df10570
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/script/UpdateScriptParamReq.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.script;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+import java.util.Map;
+
+@Data
+@ApiModel(value = "update", description = "update script param request")
+public class UpdateScriptParamReq {
+ @ApiModelProperty(value = "script id", required = true, dataType = "Integer", hidden = true)
+ private Integer scriptId;
+ @ApiModelProperty(value = "script params", required = true, dataType = "Map")
+ @NotEmpty
+ private Map<String, String> params;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/ExecuteReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/ExecuteReq.java
new file mode 100644
index 0000000..fd853d4
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/ExecuteReq.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.task;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+import java.util.Date;
+import java.util.Map;
+
+@Data
+public class ExecuteReq {
+ @ApiModelProperty(value = "script id", required = true, dataType = "Integer", hidden = true)
+ private Integer scriptId;
+ @ApiModelProperty(value = "execute content", required = true, dataType = "String")
+ private String content;
+ @ApiModelProperty(value = "operator id", required = true, dataType = "Integer", hidden = true)
+ private Integer operatorId;
+ @ApiModelProperty(value = "script params", required = true, dataType = "Map")
+ @NotEmpty
+ private Map<String, Object> params;
+ @ApiModelProperty(value = "execute type", required = true, dataType = "Integer", allowableValues = "0, 1, 2, 3")
+ private Integer executeType;
+ @ApiModelProperty(value = "start time", required = false, dataType = "Date", hidden = true)
+ private Date startTime = new Date();
+ @ApiModelProperty(value = "end time", required = false, dataType = "Date", hidden = true)
+ private Date endTime = new Date();
+ @ApiModelProperty(value = "parallelism number", required = false, dataType = "Integer", hidden = true)
+ private Integer parallelismNum = 1;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/InstanceListReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/InstanceListReq.java
new file mode 100644
index 0000000..dcabb54
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/InstanceListReq.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.task;
+
+import org.apache.seatunnel.app.domain.request.BasePageReq;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "listInstanceReq", description = "list instance")
+public class InstanceListReq extends BasePageReq {
+ @ApiModelProperty(value = "instance name", required = true, dataType = "String")
+ private String name;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/InstanceLogRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/InstanceLogRes.java
new file mode 100644
index 0000000..60d371b
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/InstanceLogRes.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.task;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "instanceLogRes", description = "instance log")
+@Builder
+public class InstanceLogRes {
+ @ApiModelProperty(value = "instance id", dataType = "long")
+ private long instanceId;
+
+ @ApiModelProperty(value = "instance id", dataType = "String")
+ private String logContent;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/JobListReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/JobListReq.java
new file mode 100644
index 0000000..55be19b
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/JobListReq.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.task;
+
+import org.apache.seatunnel.app.domain.request.BasePageReq;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "listJobReq", description = "list job")
+public class JobListReq extends BasePageReq {
+ @ApiModelProperty(value = "job name", required = true, dataType = "String")
+ private String name;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/RecycleScriptReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/RecycleScriptReq.java
new file mode 100644
index 0000000..5ee65d6
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/task/RecycleScriptReq.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.task;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "recycleScriptReq", description = "recycle script")
+public class RecycleScriptReq {
+ @ApiModelProperty(value = "script id", required = true, dataType = "Integer")
+ @NotNull
+ private int scriptId;
+ @ApiModelProperty(value = "operator id", required = true, dataType = "Integer")
+ @NotNull
+ private int operatorId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/AddUserReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/AddUserReq.java
new file mode 100644
index 0000000..fab6512
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/AddUserReq.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.user;
+
+import io.swagger.annotations.ApiModel;
+
+@ApiModel(value = "addUserReq", description = "add a new user request")
+public class AddUserReq extends BaseUserReq{
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/BaseUserReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/BaseUserReq.java
new file mode 100644
index 0000000..8ee3b67
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/BaseUserReq.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.user;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class BaseUserReq {
+ @ApiModelProperty(value = "user name", required = true, dataType = "String")
+ private String username;
+ @ApiModelProperty(value = "user password", required = true, dataType = "String")
+ private String password;
+ @ApiModelProperty(value = "user status", required = true, dataType = "Byte")
+ @NotNull
+ private Byte status;
+ @ApiModelProperty(value = "user type", required = true, dataType = "Byte")
+ @NotNull
+ private Byte type;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UpdateUserReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UpdateUserReq.java
new file mode 100644
index 0000000..29fae94
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UpdateUserReq.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.user;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@ApiModel(value = "updateUserReq", description = "update an exists user request")
+@Data
+public class UpdateUserReq extends BaseUserReq{
+ @ApiModelProperty(value = "user id", required = true, dataType = "Integer", hidden = true)
+ @NotNull
+ private Integer userId;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UserListReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UserListReq.java
new file mode 100644
index 0000000..80bcdf9
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UserListReq.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.user;
+
+import org.apache.seatunnel.app.domain.request.BasePageReq;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel(value = "userListReq", description = "user list")
+@Data
+public class UserListReq extends BasePageReq {
+ @ApiModelProperty(value = "user name", required = false, dataType = "String")
+ private String name;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UserLoginReq.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UserLoginReq.java
new file mode 100644
index 0000000..fdf2cd3
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/request/user/UserLoginReq.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.request.user;
+
+import lombok.Data;
+
+@Data
+public class UserLoginReq {
+ private String username;
+ private String password;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/PageInfo.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/PageInfo.java
new file mode 100644
index 0000000..f4ced6e
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/PageInfo.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response;
+
+import io.swagger.annotations.ApiModel;
+
+import java.util.List;
+
+@ApiModel(value = "pageInfo", description = "page info")
+@SuppressWarnings("MagicNumber")
+public class PageInfo<T> {
+ private List<T> data;
+ private Integer totalCount = 0;
+ private Integer totalPage = 0;
+ private Integer pageNo = 1;
+ private Integer pageSize = 20;
+
+ public List<T> getData() {
+ return data;
+ }
+
+ public void setData(List<T> data) {
+ this.data = data;
+ }
+
+ public Integer getTotalCount() {
+ return totalCount;
+ }
+
+ public void setTotalCount(Integer totalCount) {
+ this.totalCount = totalCount;
+
+ if (pageSize == null || pageSize == 0) {
+ pageSize = 20;
+ }
+ if (this.totalCount % this.pageSize == 0) {
+ this.totalPage = this.totalCount / this.pageSize == 0 ? 1 : this.totalCount / this.pageSize;
+ return;
+ }
+ this.totalPage = this.totalCount / this.pageSize + 1;
+ }
+
+ public Integer getTotalPage() {
+ return totalPage;
+ }
+
+ public Integer getPageNo() {
+ return pageNo;
+ }
+
+ public void setPageNo(Integer pageNo) {
+ this.pageNo = pageNo;
+ }
+
+ public Integer getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(Integer pageSize) {
+ this.pageSize = pageSize;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/AddEmptyScriptRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/AddEmptyScriptRes.java
new file mode 100644
index 0000000..1037f9f
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/AddEmptyScriptRes.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.script;
+
+import lombok.Data;
+
+@Data
+public class AddEmptyScriptRes {
+ private int id;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/BaseScriptInfoRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/BaseScriptInfoRes.java
new file mode 100644
index 0000000..4358058
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/BaseScriptInfoRes.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.script;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BaseScriptInfoRes {
+ @ApiModelProperty(value = "script id", dataType = "int")
+ private int id;
+ @ApiModelProperty(value = "script name", dataType = "String")
+ private String name;
+ @ApiModelProperty(value = "script status", dataType = "type")
+ private byte status;
+ @ApiModelProperty(value = "script type", dataType = "type")
+ private byte type;
+ @ApiModelProperty(value = "script creator id", required = true, dataType = "Integer")
+ private Integer creatorId;
+ @ApiModelProperty(value = "script mender id", required = true, dataType = "Integer")
+ private Integer menderId;
+ @ApiModelProperty(value = "script create time", dataType = "Date")
+ private Date createTime;
+ @ApiModelProperty(value = "script update time", dataType = "Date")
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/ScriptParamRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/ScriptParamRes.java
new file mode 100644
index 0000000..ae9e616
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/ScriptParamRes.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.script;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "scriptParamRes", description = "script param")
+public class ScriptParamRes {
+ @ApiModelProperty(value = "script param id", dataType = "String")
+ private int id;
+ @ApiModelProperty(value = "script param key", dataType = "String")
+ private String key;
+ @ApiModelProperty(value = "script param value", dataType = "String")
+ private String value;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/ScriptSimpleInfoRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/ScriptSimpleInfoRes.java
new file mode 100644
index 0000000..82de888
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/script/ScriptSimpleInfoRes.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.script;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@ApiModel(value = "scriptSimpleInfoRes", description = "script simple information")
+@Data
+public class ScriptSimpleInfoRes extends BaseScriptInfoRes {
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/task/InstanceSimpleInfoRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/task/InstanceSimpleInfoRes.java
new file mode 100644
index 0000000..2a68157
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/task/InstanceSimpleInfoRes.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.task;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@Builder
+@ApiModel(value = "instanceSimpleInfoRes", description = "instance simple information")
+public class InstanceSimpleInfoRes {
+ @ApiModelProperty(value = "instance id", dataType = "Long")
+ private long instanceId;
+ @ApiModelProperty(value = "job id", dataType = "Long")
+ private long jobId;
+ @ApiModelProperty(value = "instance name", dataType = "String")
+ private String instanceName;
+ @ApiModelProperty(value = "submit time", dataType = "Date")
+ private Date submitTime;
+ @ApiModelProperty(value = "start time", dataType = "Date")
+ private Date startTime;
+ @ApiModelProperty(value = "end time", dataType = "Date")
+ private Date endTime;
+ @ApiModelProperty(value = "task status", dataType = "String")
+ private String status;
+ @ApiModelProperty(value = "execution duration", dataType = "String")
+ private String executionDuration;
+ @ApiModelProperty(value = "retry times", dataType = "Long")
+ private long retryTimes;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/task/JobSimpleInfoRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/task/JobSimpleInfoRes.java
new file mode 100644
index 0000000..40b003b
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/task/JobSimpleInfoRes.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.task;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@ApiModel(value = "jobSimpleInfoRes", description = "job simple information")
+@Data
+@Builder
+public class JobSimpleInfoRes {
+ @ApiModelProperty(value = "job id", dataType = "Long")
+ private long jobId;
+ @ApiModelProperty(value = "job status", dataType = "String")
+ private String jobStatus;
+ @ApiModelProperty(value = "job creator", dataType = "String")
+ private String creatorName;
+ @ApiModelProperty(value = "job mender", dataType = "String")
+ private String menderName;
+ @ApiModelProperty(value = "job create time", dataType = "String")
+ private Date createTime;
+ @ApiModelProperty(value = "job update time", dataType = "String")
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/AddUserRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/AddUserRes.java
new file mode 100644
index 0000000..e115a93
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/AddUserRes.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.user;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "addUserRes", description = "add user response")
+public class AddUserRes {
+ private int id;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/BaseUserInfoRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/BaseUserInfoRes.java
new file mode 100644
index 0000000..a50a2ce
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/BaseUserInfoRes.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.user;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BaseUserInfoRes {
+ @ApiModelProperty(value = "user id", dataType = "int")
+ private int id;
+ @ApiModelProperty(value = "user name", dataType = "String")
+ private String name;
+ @ApiModelProperty(value = "user status", dataType = "type")
+ private byte status;
+ @ApiModelProperty(value = "user type", dataType = "type")
+ private byte type;
+ @ApiModelProperty(value = "user create time", dataType = "Date")
+ private Date createTime;
+ @ApiModelProperty(value = "user update time", dataType = "Date")
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/UserSimpleInfoRes.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/UserSimpleInfoRes.java
new file mode 100644
index 0000000..b1c6af2
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/domain/response/user/UserSimpleInfoRes.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.domain.response.user;
+
+import com.google.common.collect.Maps;
+import io.swagger.annotations.ApiModel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@ApiModel(value = "userSimpleInfoRes", description = "user simple information")
+public class UserSimpleInfoRes extends BaseUserInfoRes {
+
+ public Map<String, Object> toMap() {
+ final HashMap<String, Object> userMap = Maps.newHashMap();
+ userMap.put("id", getId());
+ userMap.put("name", getName());
+ userMap.put("status", getStatus());
+ userMap.put("type", getType());
+ return userMap;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/interceptor/AuthenticationInterceptor.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/interceptor/AuthenticationInterceptor.java
new file mode 100644
index 0000000..3b43262
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/interceptor/AuthenticationInterceptor.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.interceptor;
+
+import static org.apache.seatunnel.server.common.Constants.OPTIONS;
+import static org.apache.seatunnel.server.common.Constants.TOKEN;
+import static org.apache.seatunnel.server.common.Constants.USER_ID;
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.TOKEN_ILLEGAL;
+import static io.jsonwebtoken.Claims.EXPIRATION;
+
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.UserLoginLog;
+import org.apache.seatunnel.app.security.JwtUtils;
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+public class AuthenticationInterceptor implements HandlerInterceptor {
+
+ @Resource
+ private IUserDao userDaoImpl;
+
+ @Resource
+ private JwtUtils jwtUtils;
+
+ @Override
+ @SuppressWarnings("MagicNumber")
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ if (request.getMethod().equals(OPTIONS)) {
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ response.setHeader("Access-Control-Allow-Headers", "*");
+ response.setHeader("Access-Control-Allow-Methods", "*");
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ response.setHeader("Access-Control-Max-Age", "3600");
+ return true;
+ }
+ long currentTimestamp = System.currentTimeMillis();
+ final String token = request.getHeader(TOKEN);
+ if (StringUtils.isBlank(token)) {
+ throw new SeatunnelException(TOKEN_ILLEGAL);
+ }
+ final Map<String, Object> map = jwtUtils.parseToken(token);
+ final Integer userId = (Integer) map.get(USER_ID);
+ if (Objects.isNull(userId)) {
+ throw new SeatunnelException(TOKEN_ILLEGAL);
+ }
+ final UserLoginLog userLoginLog = userDaoImpl.getLastLoginLog(userId);
+ if (Objects.isNull(userLoginLog) || !userLoginLog.getTokenStatus()) {
+ throw new SeatunnelException(TOKEN_ILLEGAL);
+ }
+
+ final Integer expireDate = (Integer) map.get(EXPIRATION);
+ if (Objects.isNull(expireDate) || currentTimestamp - (long) expireDate * 1000 > 0) {
+ throw new SeatunnelException(TOKEN_ILLEGAL);
+ }
+
+ map.forEach(request::setAttribute);
+
+ return true;
+ }
+
+ @Override
+ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+ // do nothing
+ }
+
+ @Override
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+ // do nothing
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/resolver/UserIdMethodArgumentResolver.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/resolver/UserIdMethodArgumentResolver.java
new file mode 100644
index 0000000..3ebfca7
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/resolver/UserIdMethodArgumentResolver.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.resolver;
+
+import static org.apache.seatunnel.server.common.Constants.USER_ID;
+
+import org.apache.seatunnel.app.aspect.UserId;
+
+import org.springframework.core.MethodParameter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.support.WebDataBinderFactory;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.method.support.ModelAndViewContainer;
+
+@Component
+public class UserIdMethodArgumentResolver implements HandlerMethodArgumentResolver {
+ @Override
+ public boolean supportsParameter(MethodParameter parameter) {
+ return parameter.getParameterType().isAssignableFrom(Integer.class)
+ && parameter.hasParameterAnnotation(UserId.class);
+ }
+
+ @Override
+ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
+ return (Integer) webRequest.getAttribute(USER_ID, RequestAttributes.SCOPE_REQUEST);
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/JwtUtils.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/JwtUtils.java
new file mode 100644
index 0000000..9ddc9b4
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/security/JwtUtils.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.security;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jws;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.apache.commons.lang3.time.DateUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+@Component
+public class JwtUtils implements InitializingBean {
+ @Value("${jwt.expireTime}")
+ private int expireTime;
+ @Value("${jwt.secretKey}")
+ private String secretKey;
+ @Value("${jwt.algorithm}")
+ private String algorithmString;
+ private SignatureAlgorithm algorithm = null;
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ algorithm = SignatureAlgorithm.valueOf(algorithmString);
+ }
+
+ public String genToken(Map<String, Object> data) {
+ final Date currentDate = new Date();
+ final Date expireDate = DateUtils.addSeconds(currentDate, expireTime);
+
+ return Jwts.builder()
+ .signWith(SignatureAlgorithm.HS256, secretKey.getBytes(StandardCharsets.UTF_8))
+ .setId(UUID.randomUUID().toString())
+ .setClaims(data)
+ .setIssuedAt(currentDate)
+ .setExpiration(expireDate)
+ .compact();
+ }
+
+ public Map<String, Object> parseToken(String token) {
+ final Jws<Claims> claims = Jwts.parser().setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token);
+ return claims.getBody();
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IRoleService.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IRoleService.java
new file mode 100644
index 0000000..3dcf1e3
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IRoleService.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service;
+
+public interface IRoleService {
+ boolean addUserToRole(Integer userId, Integer type);
+
+ boolean checkUserRole(String username, String roleName);
+
+ void deleteByUserId(Integer id);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IScriptService.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IScriptService.java
new file mode 100644
index 0000000..4e9a9eb
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IScriptService.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service;
+
+import org.apache.seatunnel.app.domain.request.script.AddEmptyScriptReq;
+import org.apache.seatunnel.app.domain.request.script.PublishScriptReq;
+import org.apache.seatunnel.app.domain.request.script.ScriptListReq;
+import org.apache.seatunnel.app.domain.request.script.UpdateScriptContentReq;
+import org.apache.seatunnel.app.domain.request.script.UpdateScriptParamReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.script.AddEmptyScriptRes;
+import org.apache.seatunnel.app.domain.response.script.ScriptParamRes;
+import org.apache.seatunnel.app.domain.response.script.ScriptSimpleInfoRes;
+
+import java.util.List;
+
+public interface IScriptService {
+ AddEmptyScriptRes addEmptyScript(AddEmptyScriptReq addEmptyScriptReq);
+
+ void updateScriptContent(UpdateScriptContentReq updateScriptContentReq);
+
+ void delete(Integer id);
+
+ PageInfo<ScriptSimpleInfoRes> list(ScriptListReq scriptListReq);
+
+ String fetchScriptContent(Integer id);
+
+ List<ScriptParamRes> fetchScriptParam(Integer id);
+
+ void updateScriptParam(UpdateScriptParamReq updateScriptParamReq);
+
+ void publishScript(PublishScriptReq req);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/ITaskService.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/ITaskService.java
new file mode 100644
index 0000000..a197f1e
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/ITaskService.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service;
+
+import org.apache.seatunnel.app.domain.dto.job.PushScriptDto;
+import org.apache.seatunnel.app.domain.request.task.ExecuteReq;
+import org.apache.seatunnel.app.domain.request.task.InstanceListReq;
+import org.apache.seatunnel.app.domain.request.task.InstanceLogRes;
+import org.apache.seatunnel.app.domain.request.task.JobListReq;
+import org.apache.seatunnel.app.domain.request.task.RecycleScriptReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.task.InstanceSimpleInfoRes;
+import org.apache.seatunnel.app.domain.response.task.JobSimpleInfoRes;
+
+public interface ITaskService {
+ Long pushScriptToScheduler(PushScriptDto pushScriptDto);
+
+ void recycleScriptFromScheduler(RecycleScriptReq req);
+
+ PageInfo<JobSimpleInfoRes> listJob(JobListReq req);
+
+ PageInfo<InstanceSimpleInfoRes> listInstance(InstanceListReq req);
+
+ InstanceSimpleInfoRes tmpExecute(ExecuteReq req);
+
+ InstanceLogRes queryInstanceLog(Long instanceId);
+
+ void kill(Long instanceId);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java
new file mode 100644
index 0000000..60ba8d4
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/IUserService.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service;
+
+import org.apache.seatunnel.app.domain.request.user.AddUserReq;
+import org.apache.seatunnel.app.domain.request.user.UpdateUserReq;
+import org.apache.seatunnel.app.domain.request.user.UserListReq;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.user.AddUserRes;
+import org.apache.seatunnel.app.domain.response.user.UserSimpleInfoRes;
+
+public interface IUserService {
+
+ AddUserRes add(AddUserReq addReq);
+
+ void update(UpdateUserReq updateReq);
+
+ void delete(int id);
+
+ PageInfo<UserSimpleInfoRes> list(UserListReq userListReq);
+
+ void enable(int id);
+
+ void disable(int id);
+
+ UserSimpleInfoRes login(UserLoginReq req);
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/RoleServiceImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/RoleServiceImpl.java
new file mode 100644
index 0000000..e0f3171
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/RoleServiceImpl.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service.impl;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.NO_SUCH_USER;
+import static com.google.common.base.Preconditions.checkState;
+
+import org.apache.seatunnel.app.common.RoleTypeEnum;
+import org.apache.seatunnel.app.dal.dao.IRoleDao;
+import org.apache.seatunnel.app.dal.dao.IRoleUserRelationDao;
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.Role;
+import org.apache.seatunnel.app.dal.entity.RoleUserRelation;
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.service.IRoleService;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+import java.util.Objects;
+
+@Service
+@Slf4j
+public class RoleServiceImpl implements IRoleService {
+
+ @Resource
+ private IRoleDao roleDaoImpl;
+
+ @Resource
+ private IRoleUserRelationDao roleUserRelationDaoImpl;
+
+ @Resource
+ private IUserDao userDaoImpl;
+
+ @Override
+ public boolean addUserToRole(Integer userId, Integer type){
+
+ String roleName = type == RoleTypeEnum.ADMIN.getCode() ? RoleTypeEnum.ADMIN.getDescription() : RoleTypeEnum.NORMAL.getDescription();
+
+ final Role role = roleDaoImpl.getByRoleName(roleName);
+
+ final RoleUserRelation build = RoleUserRelation.builder()
+ .roleId(role.getId())
+ .userId(userId)
+ .build();
+
+ roleUserRelationDaoImpl.add(build);
+ return true;
+ }
+
+ @Override
+ public boolean checkUserRole(String username, String roleName){
+
+ final User user = userDaoImpl.getByName(username);
+
+ checkState(!Objects.isNull(user), NO_SUCH_USER.getTemplate());
+
+ final Role role = roleDaoImpl.getByRoleName(roleName);
+
+ final RoleUserRelation byUserAndRole = roleUserRelationDaoImpl.getByUserAndRole(user.getId(), role.getId());
+
+ return !Objects.isNull(byUserAndRole);
+
+ }
+
+ @Override
+ public void deleteByUserId(Integer userId) {
+ roleUserRelationDaoImpl.deleteByUserId(userId);
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/ScriptServiceImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/ScriptServiceImpl.java
new file mode 100644
index 0000000..6d654c9
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/ScriptServiceImpl.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service.impl;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.NO_SUCH_SCRIPT;
+import static com.google.common.base.Preconditions.checkState;
+
+import org.apache.seatunnel.app.common.ScriptParamStatusEnum;
+import org.apache.seatunnel.app.common.ScriptStatusEnum;
+import org.apache.seatunnel.app.dal.dao.IScriptDao;
+import org.apache.seatunnel.app.dal.dao.IScriptParamDao;
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.Script;
+import org.apache.seatunnel.app.dal.entity.ScriptParam;
+import org.apache.seatunnel.app.domain.dto.job.PushScriptDto;
+import org.apache.seatunnel.app.domain.dto.script.AddEmptyScriptDto;
+import org.apache.seatunnel.app.domain.dto.script.CheckScriptDuplicateDto;
+import org.apache.seatunnel.app.domain.dto.script.ListScriptsDto;
+import org.apache.seatunnel.app.domain.dto.script.UpdateScriptContentDto;
+import org.apache.seatunnel.app.domain.dto.script.UpdateScriptParamDto;
+import org.apache.seatunnel.app.domain.request.script.AddEmptyScriptReq;
+import org.apache.seatunnel.app.domain.request.script.PublishScriptReq;
+import org.apache.seatunnel.app.domain.request.script.ScriptListReq;
+import org.apache.seatunnel.app.domain.request.script.UpdateScriptContentReq;
+import org.apache.seatunnel.app.domain.request.script.UpdateScriptParamReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.script.AddEmptyScriptRes;
+import org.apache.seatunnel.app.domain.response.script.ScriptParamRes;
+import org.apache.seatunnel.app.domain.response.script.ScriptSimpleInfoRes;
+import org.apache.seatunnel.app.service.IScriptService;
+import org.apache.seatunnel.app.service.ITaskService;
+import org.apache.seatunnel.app.utils.Md5Utils;
+import org.apache.seatunnel.scheduler.dolphinscheduler.impl.InstanceServiceImpl;
+import org.apache.seatunnel.server.common.PageData;
+
+import com.google.common.base.Strings;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Component
+public class ScriptServiceImpl implements IScriptService {
+
+ @Resource
+ private IScriptDao scriptDaoImpl;
+
+ @Resource
+ private IScriptParamDao scriptParamDaoImpl;
+
+ @Resource
+ private InstanceServiceImpl instanceService;
+
+ @Resource
+ private IUserDao userDaoImpl;
+
+ @Resource
+ private ITaskService iTaskService;
+
+ @Override
+ public AddEmptyScriptRes addEmptyScript(AddEmptyScriptReq addEmptyScriptReq) {
+ // 1. check script name.
+ checkDuplicate(addEmptyScriptReq.getName(), addEmptyScriptReq.getCreatorId());
+ // 2. create an empty script
+ int scriptId = addEmptyScript(addEmptyScriptReq.getName(), addEmptyScriptReq.getCreatorId(), addEmptyScriptReq.getCreatorId(), addEmptyScriptReq.getType());
+
+ final AddEmptyScriptRes res = new AddEmptyScriptRes();
+ res.setId(scriptId);
+ return res;
+ }
+
+ private int addEmptyScript(String name, Integer creatorId, Integer menderId, Byte type) {
+ final AddEmptyScriptDto dto = AddEmptyScriptDto.builder()
+ .name(name)
+ .menderId(creatorId)
+ .creatorId(menderId)
+ .type(type)
+ .status((byte) ScriptStatusEnum.UNPUBLISHED.getCode())
+ .build();
+ return scriptDaoImpl.addEmptyScript(dto);
+ }
+
+ private void checkDuplicate(String name, Integer creatorId) {
+ final CheckScriptDuplicateDto dto = CheckScriptDuplicateDto.builder()
+ .creatorId(creatorId)
+ .name(name)
+ .build();
+ scriptDaoImpl.checkScriptDuplicate(dto);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateScriptContent(UpdateScriptContentReq updateScriptContentReq) {
+ // 1. check content md5 is consistent
+ final String content = updateScriptContentReq.getContent();
+ final String contentMd5 = Strings.isNullOrEmpty(content) ? "" : Md5Utils.toMd5(content);
+
+ final boolean needSave = checkIfNeedSave(updateScriptContentReq.getScriptId(), contentMd5);
+
+ if (needSave){
+ final UpdateScriptContentDto dto = UpdateScriptContentDto.builder()
+ .id(updateScriptContentReq.getScriptId())
+ .content(content)
+ .contentMd5(contentMd5)
+ .menderId(updateScriptContentReq.getMenderId())
+ .build();
+ scriptDaoImpl.updateScriptContent(dto);
+ }
+ }
+
+ private boolean checkIfNeedSave(int id, String newContentMd5) {
+ Script script = scriptDaoImpl.getScript(id);
+ checkState(Objects.nonNull(script) && (int) script.getStatus() != ScriptStatusEnum.DELETED.getCode(), NO_SUCH_SCRIPT.getTemplate());
+
+ final String oldContentMd5 = Strings.isNullOrEmpty(script.getContentMd5()) ? "" : script.getContentMd5();
+ return !newContentMd5.equals(oldContentMd5);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void delete(Integer id) {
+ // no need check script if exist.
+ scriptDaoImpl.deleteScript(id);
+ }
+
+ @Override
+ public PageInfo<ScriptSimpleInfoRes> list(ScriptListReq scriptListReq) {
+
+ final ListScriptsDto dto = ListScriptsDto.builder()
+ .name(scriptListReq.getName())
+ .status(scriptListReq.getStatus())
+ .build();
+
+ PageData<Script> scriptPageData = scriptDaoImpl.list(dto, scriptListReq.getRealPageNo(), scriptListReq.getPageSize());
+ final List<ScriptSimpleInfoRes> data = scriptPageData.getData().stream().map(this::translate).collect(Collectors.toList());
+
+ final PageInfo<ScriptSimpleInfoRes> pageInfo = new PageInfo<>();
+ pageInfo.setPageNo(scriptListReq.getPageNo());
+ pageInfo.setPageSize(scriptListReq.getPageSize());
+ pageInfo.setTotalCount(scriptPageData.getTotalCount());
+ pageInfo.setData(data);
+ return pageInfo;
+ }
+
+ @Override
+ public String fetchScriptContent(Integer id) {
+ Script script = scriptDaoImpl.getScript(id);
+ checkState(Objects.nonNull(script), NO_SUCH_SCRIPT.getTemplate());
+ return script.getContent();
+ }
+
+ @Override
+ public List<ScriptParamRes> fetchScriptParam(Integer id) {
+ List<ScriptParam> scriptParamRes = scriptParamDaoImpl.getParamsByScriptId(id);
+ if (CollectionUtils.isEmpty(scriptParamRes)){
+ return Collections.emptyList();
+ }
+ return scriptParamRes.stream().map(this::translate).collect(Collectors.toList());
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateScriptParam(UpdateScriptParamReq updateScriptParamReq) {
+ // 1. delete all old params first.
+ // 2. save new params. (check params correctness)
+ scriptParamDaoImpl.updateStatusByScriptId(updateScriptParamReq.getScriptId(), ScriptParamStatusEnum.DELETED.getCode());
+
+ UpdateScriptParamDto dto = UpdateScriptParamDto.builder()
+ .scriptId(updateScriptParamReq.getScriptId())
+ .params(updateScriptParamReq.getParams())
+ .build();
+
+ scriptParamDaoImpl.batchInsert(dto);
+ }
+
+ @Override
+ public void publishScript(PublishScriptReq req){
+ final PushScriptDto dto = PushScriptDto.builder()
+ .scriptId(req.getScriptId())
+ .userId(req.getOperatorId())
+ .build();
+ iTaskService.pushScriptToScheduler(dto);
+ }
+
+ private ScriptParamRes translate(ScriptParam scriptParam) {
+ final ScriptParamRes res = new ScriptParamRes();
+ res.setId(scriptParam.getId());
+ res.setKey(scriptParam.getKey());
+ res.setValue(scriptParam.getValue());
+ return res;
+ }
+
+ private ScriptSimpleInfoRes translate(Script script) {
+ final ScriptSimpleInfoRes res = new ScriptSimpleInfoRes();
+ res.setId(script.getId());
+ res.setName(script.getName());
+ res.setStatus(script.getStatus());
+ res.setType(script.getType());
+ res.setCreatorId(script.getCreatorId());
+ res.setMenderId(script.getMenderId());
+ res.setCreateTime(script.getCreateTime());
+ res.setUpdateTime(script.getUpdateTime());
+ return res;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/TaskServiceImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/TaskServiceImpl.java
new file mode 100644
index 0000000..c687c93
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/TaskServiceImpl.java
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service.impl;
+
+import static org.apache.seatunnel.server.common.Constants.UNDERLINE;
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.NO_SUCH_SCRIPT;
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.SCHEDULER_CONFIG_NOT_EXIST;
+import static org.apache.seatunnel.spi.scheduler.constants.SchedulerConstant.NEVER_TRIGGER_EXPRESSION;
+import static org.apache.seatunnel.spi.scheduler.constants.SchedulerConstant.RETRY_INTERVAL_DEFAULT;
+import static org.apache.seatunnel.spi.scheduler.constants.SchedulerConstant.RETRY_TIMES_DEFAULT;
+
+import org.apache.seatunnel.app.dal.dao.ISchedulerConfigDao;
+import org.apache.seatunnel.app.dal.dao.IScriptDao;
+import org.apache.seatunnel.app.dal.dao.IScriptJobApplyDao;
+import org.apache.seatunnel.app.dal.dao.IScriptParamDao;
+import org.apache.seatunnel.app.dal.entity.SchedulerConfig;
+import org.apache.seatunnel.app.dal.entity.Script;
+import org.apache.seatunnel.app.dal.entity.ScriptJobApply;
+import org.apache.seatunnel.app.dal.entity.ScriptParam;
+import org.apache.seatunnel.app.domain.dto.job.PushScriptDto;
+import org.apache.seatunnel.app.domain.dto.job.ScriptJobApplyDto;
+import org.apache.seatunnel.app.domain.request.task.ExecuteReq;
+import org.apache.seatunnel.app.domain.request.task.InstanceListReq;
+import org.apache.seatunnel.app.domain.request.task.InstanceLogRes;
+import org.apache.seatunnel.app.domain.request.task.JobListReq;
+import org.apache.seatunnel.app.domain.request.task.RecycleScriptReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.task.InstanceSimpleInfoRes;
+import org.apache.seatunnel.app.domain.response.task.JobSimpleInfoRes;
+import org.apache.seatunnel.app.service.ITaskService;
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.server.common.SeatunnelException;
+import org.apache.seatunnel.spi.scheduler.IInstanceService;
+import org.apache.seatunnel.spi.scheduler.IJobService;
+import org.apache.seatunnel.spi.scheduler.dto.ExecuteDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceListDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceLogDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobListDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobSimpleInfoDto;
+import org.apache.seatunnel.spi.scheduler.dto.SchedulerConfigDto;
+import org.apache.seatunnel.spi.scheduler.enums.ExecuteTypeEnum;
+
+import com.google.common.collect.Maps;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class TaskServiceImpl implements ITaskService {
+
+ @Resource
+ private IJobService iJobService;
+
+ @Resource
+ private IInstanceService iInstanceService;
+
+ @Resource
+ private IScriptDao scriptDaoImpl;
+
+ @Resource
+ private IScriptParamDao scriptParamDaoImpl;
+
+ @Resource
+ private ISchedulerConfigDao schedulerConfigDaoImpl;
+
+ @Resource
+ private IScriptJobApplyDao scriptJobApplyDaoImpl;
+
+ @Override
+ public Long pushScriptToScheduler(PushScriptDto pushScriptDto) {
+ final int scriptId = pushScriptDto.getScriptId();
+ final int userId = pushScriptDto.getUserId();
+
+ // check scheduler param
+ SchedulerConfig config = schedulerConfigDaoImpl.getSchedulerConfig(scriptId);
+ if (Objects.isNull(config)) {
+ throw new SeatunnelException(SCHEDULER_CONFIG_NOT_EXIST);
+ }
+
+ final Script script = checkAndGetScript(scriptId);
+ final List<ScriptParam> scriptParams = scriptParamDaoImpl.getParamsByScriptId(scriptId);
+ Map<String, Object> params = getScriptParamMap(scriptParams);
+
+ final SchedulerConfigDto schedulerConfigDto = SchedulerConfigDto.builder()
+ .retryInterval(config.getRetryInterval())
+ .retryTimes(config.getRetryTimes())
+ .startTime(config.getActiveStartTime())
+ .endTime(config.getActiveEndTime())
+ .triggerExpression(config.getTriggerExpression())
+ .build();
+
+ final JobDto jobDto = JobDto.builder()
+ .jobName(script.getName())
+ .jobContent(script.getContent())
+ .params(params)
+ .operatorId(userId)
+ .schedulerConfigDto(schedulerConfigDto)
+ //todo fix to real execute script
+ .executorScript(script.getContent())
+ .jobId(null)
+ .build();
+
+ ScriptJobApply apply = scriptJobApplyDaoImpl.getByScriptId(script.getId());
+ if (Objects.nonNull(apply)) {
+ jobDto.setJobId(apply.getJobId());
+ }
+
+ // push script
+ final long jobId = iJobService.submitJob(jobDto);
+
+ // Use future to ensure that the page does not show exceptions due to database errors.
+ syncScriptJobMapping(scriptId, userId, config.getId(), jobId);
+ return jobId;
+ }
+
+ @Override
+ public void recycleScriptFromScheduler(RecycleScriptReq req) {
+ final Script script = checkAndGetScript(req.getScriptId());
+ ScriptJobApply apply = scriptJobApplyDaoImpl.getByScriptId(script.getId());
+
+ final JobDto jobDto = JobDto.builder()
+ .jobId(apply.getJobId())
+ .jobName(script.getName())
+ .operatorId(req.getOperatorId())
+ .build();
+
+ iJobService.offlineJob(jobDto);
+
+ syncScriptJobMapping(script.getId(), req.getOperatorId(), apply.getSchedulerConfigId(), apply.getJobId());
+ }
+
+ @Override
+ public PageInfo<JobSimpleInfoRes> listJob(JobListReq req) {
+ // Search from scheduler.
+ final JobListDto dto = JobListDto.builder()
+ .name(req.getName())
+ .pageNo(req.getPageNo())
+ .pageSize(req.getPageSize())
+ .build();
+ final PageData<JobSimpleInfoDto> jobPageData = iJobService.list(dto);
+ final List<JobSimpleInfoRes> data = jobPageData.getData().stream().map(this::translate).collect(Collectors.toList());
+ final PageInfo<JobSimpleInfoRes> pageInfo = new PageInfo<>();
+ pageInfo.setData(data);
+ pageInfo.setTotalCount(jobPageData.getTotalCount());
+ pageInfo.setPageNo(req.getPageNo());
+ pageInfo.setPageSize(req.getPageSize());
+
+ return pageInfo;
+ }
+
+ @Override
+ public PageInfo<InstanceSimpleInfoRes> listInstance(InstanceListReq req) {
+ // Search from scheduler.
+ final InstanceListDto dto = InstanceListDto.builder()
+ .name(req.getName())
+ .pageNo(req.getPageNo())
+ .pageSize(req.getPageSize())
+ .build();
+ final PageData<InstanceDto> instancePageData = iInstanceService.list(dto);
+ final List<InstanceSimpleInfoRes> data = instancePageData.getData().stream().map(this::translate).collect(Collectors.toList());
+ final PageInfo<InstanceSimpleInfoRes> pageInfo = new PageInfo<>();
+ pageInfo.setData(data);
+ pageInfo.setTotalCount(instancePageData.getTotalCount());
+ pageInfo.setPageNo(req.getPageNo());
+ pageInfo.setPageSize(req.getPageSize());
+
+ return pageInfo;
+ }
+
+ @Override
+ public InstanceSimpleInfoRes tmpExecute(ExecuteReq req) {
+ final Script script = checkAndGetScript(req.getScriptId());
+
+ final SchedulerConfigDto schedulerConfigDto = SchedulerConfigDto.builder()
+ .retryInterval(RETRY_INTERVAL_DEFAULT)
+ .retryTimes(RETRY_TIMES_DEFAULT)
+ .startTime(new Date())
+ .endTime(new Date())
+ .triggerExpression(NEVER_TRIGGER_EXPRESSION)
+ .build();
+
+ final JobDto jobDto = JobDto.builder()
+ .jobName(script.getName().concat(UNDERLINE).concat(String.valueOf(System.currentTimeMillis())))
+ .jobContent(req.getContent())
+ .params(req.getParams())
+ .operatorId(req.getOperatorId())
+ .schedulerConfigDto(schedulerConfigDto)
+ //todo fix to real execute script
+ .executorScript(script.getContent())
+ .jobId(null)
+ .build();
+
+ final ExecuteDto dto = ExecuteDto.builder()
+ .jobDto(jobDto)
+ .executeTypeEnum(ExecuteTypeEnum.parse(req.getExecuteType()))
+ .complementDataDto(null)
+ .build();
+
+ return this.translate(iJobService.execute(dto));
+ }
+
+ @Override
+ public InstanceLogRes queryInstanceLog(Long instanceId) {
+ final InstanceLogDto dto = iInstanceService.queryInstanceLog(instanceId);
+
+ return InstanceLogRes.builder()
+ .instanceId(instanceId)
+ .logContent(dto.getLogContent())
+ .build();
+ }
+
+ @Override
+ public void kill(Long instanceId) {
+ iJobService.kill(instanceId);
+ }
+
+ private JobSimpleInfoRes translate(JobSimpleInfoDto dto) {
+ return JobSimpleInfoRes.builder()
+ .jobId(dto.getJobId())
+ .jobStatus(dto.getJobStatus())
+ .creatorName(dto.getCreatorName())
+ .menderName(dto.getMenderName())
+ .createTime(dto.getCreateTime())
+ .updateTime(dto.getUpdateTime())
+ .build();
+ }
+
+ private InstanceSimpleInfoRes translate(InstanceDto dto) {
+ return InstanceSimpleInfoRes.builder()
+ .instanceId(dto.getInstanceId())
+ .jobId(dto.getJobId())
+ .instanceName(dto.getInstanceName())
+ .submitTime(dto.getSubmitTime())
+ .startTime(dto.getStartTime())
+ .endTime(dto.getEndTime())
+ .status(dto.getStatus())
+ .executionDuration(dto.getExecutionDuration())
+ .retryTimes(dto.getRetryTimes())
+ .build();
+ }
+
+ private Script checkAndGetScript(int scriptId) {
+ final Script script = scriptDaoImpl.getScript(scriptId);
+ if (Objects.isNull(script)) {
+ throw new SeatunnelException(NO_SUCH_SCRIPT);
+ }
+ return script;
+ }
+
+ private void syncScriptJobMapping(int scriptId, int userId, int schedulerConfigId, long jobId) {
+ CompletableFuture.runAsync(() -> {
+ // store script and job mapping
+ final ScriptJobApplyDto dto = ScriptJobApplyDto.builder()
+ .scriptId(scriptId)
+ .schedulerConfigId(schedulerConfigId)
+ .jobId(jobId)
+ .userId(userId)
+ .build();
+ scriptJobApplyDaoImpl.insertOrUpdate(dto);
+ }).whenComplete((_return, e) -> {
+ if (Objects.nonNull(e)) {
+ log.error("Store script and job mapping failed, please maintain this mapping manually. \n" +
+ "scriptId [{}], schedulerConfigId [{}], jobId [{}], userId [{}]", scriptId, schedulerConfigId, jobId, userId, e);
+ }
+ });
+ }
+
+ private Map<String, Object> getScriptParamMap(List<ScriptParam> scriptParams) {
+ Map<String, Object> params = Maps.newHashMap();
+
+ if (!CollectionUtils.isEmpty(params)) {
+ scriptParams.forEach(scriptParam -> params.put(scriptParam.getKey(), scriptParam.getValue()));
+ }
+ return params;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..aa63f60
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/service/impl/UserServiceImpl.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.service.impl;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.USERNAME_PASSWORD_NO_MATCHED;
+
+import org.apache.seatunnel.app.dal.dao.IUserDao;
+import org.apache.seatunnel.app.dal.entity.User;
+import org.apache.seatunnel.app.domain.dto.user.ListUserDto;
+import org.apache.seatunnel.app.domain.dto.user.UpdateUserDto;
+import org.apache.seatunnel.app.domain.request.user.AddUserReq;
+import org.apache.seatunnel.app.domain.request.user.UpdateUserReq;
+import org.apache.seatunnel.app.domain.request.user.UserListReq;
+import org.apache.seatunnel.app.domain.request.user.UserLoginReq;
+import org.apache.seatunnel.app.domain.response.PageInfo;
+import org.apache.seatunnel.app.domain.response.user.AddUserRes;
+import org.apache.seatunnel.app.domain.response.user.UserSimpleInfoRes;
+import org.apache.seatunnel.app.service.IRoleService;
+import org.apache.seatunnel.app.service.IUserService;
+import org.apache.seatunnel.app.utils.PasswordUtils;
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Component
+public class UserServiceImpl implements IUserService {
+ @Resource
+ private IUserDao userDaoImpl;
+
+ @Resource
+ private IRoleService roleServiceImpl;
+
+ @Value("${user.default.passwordSalt:seatunnel}")
+ private String defaultSalt;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public AddUserRes add(AddUserReq addReq) {
+ // 1. check duplicate user first
+ userDaoImpl.checkUserExists(addReq.getUsername());
+
+ // 2. add a new user.
+ final UpdateUserDto dto = UpdateUserDto.builder()
+ .id(null)
+ .username(addReq.getUsername())
+ // encryption user's password
+ .password(PasswordUtils.encryptWithSalt(defaultSalt, addReq.getPassword()))
+ .status(addReq.getStatus())
+ .type(addReq.getType())
+ .build();
+
+ final int userId = userDaoImpl.add(dto);
+ final AddUserRes res = new AddUserRes();
+ res.setId(userId);
+
+ // 3. add to role
+ roleServiceImpl.addUserToRole(userId, addReq.getType().intValue());
+ return res;
+ }
+
+ @Override
+ public void update(UpdateUserReq updateReq) {
+ final UpdateUserDto dto = UpdateUserDto.builder()
+ .id(updateReq.getUserId())
+ .username(updateReq.getUsername())
+ // encryption user's password
+ .password(PasswordUtils.encryptWithSalt(defaultSalt, updateReq.getPassword()))
+ .status(updateReq.getStatus())
+ .type(updateReq.getType())
+ .build();
+
+ userDaoImpl.update(dto);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void delete(int id) {
+ userDaoImpl.delete(id);
+ roleServiceImpl.deleteByUserId(id);
+ }
+
+ @Override
+ public PageInfo<UserSimpleInfoRes> list(UserListReq userListReq) {
+
+ final ListUserDto dto = ListUserDto.builder()
+ .name(userListReq.getName())
+ .build();
+
+ final PageData<User> userPageData = userDaoImpl.list(dto, userListReq.getRealPageNo(), userListReq.getPageSize());
+
+ final List<UserSimpleInfoRes> data = userPageData.getData().stream().map(this::translate).collect(Collectors.toList());
+ final PageInfo<UserSimpleInfoRes> pageInfo = new PageInfo<>();
+ pageInfo.setPageNo(userListReq.getPageNo());
+ pageInfo.setPageSize(userListReq.getPageSize());
+ pageInfo.setData(data);
+ pageInfo.setTotalCount(userPageData.getTotalCount());
+
+ return pageInfo;
+ }
+
+ @Override
+ public void enable(int id) {
+ userDaoImpl.enable(id);
+ }
+
+ @Override
+ public void disable(int id) {
+ userDaoImpl.disable(id);
+ }
+
+ @Override
+ public UserSimpleInfoRes login(UserLoginReq req) {
+
+ final String username = req.getUsername();
+ final String password = PasswordUtils.encryptWithSalt(defaultSalt, req.getPassword());
+
+ final User user = userDaoImpl.checkPassword(username, password);
+ if (Objects.isNull(user)) {
+ throw new SeatunnelException(USERNAME_PASSWORD_NO_MATCHED);
+ }
+ return translate(user);
+ }
+
+ private UserSimpleInfoRes translate(User user) {
+ final UserSimpleInfoRes info = new UserSimpleInfoRes();
+ info.setId(user.getId());
+ info.setStatus(user.getStatus());
+ info.setType(user.getType());
+ info.setCreateTime(user.getCreateTime());
+ info.setUpdateTime(user.getUpdateTime());
+ info.setName(user.getUsername());
+ return info;
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/GlobalExceptionHandler.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/GlobalExceptionHandler.java
new file mode 100644
index 0000000..307ea95
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/GlobalExceptionHandler.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.utils;
+
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.server.common.SeatunnelErrorEnum;
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.Optional;
+
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(value = SeatunnelException.class)
+ private Result<String> portalExceptionHandler(SeatunnelException e) {
+ logError(e);
+
+ final SeatunnelException seatunnelException = Optional.ofNullable(e).orElse(SeatunnelException.newInstance(SeatunnelErrorEnum.UNKNOWN));
+
+ final String message = seatunnelException.getMessage();
+ final SeatunnelErrorEnum errorEnum = seatunnelException.getErrorEnum();
+
+ return Result.failure(errorEnum, message);
+ }
+
+ @ExceptionHandler(value = IllegalStateException.class)
+ private Result<String> exceptionHandler(IllegalStateException e) {
+ logError(e);
+ return Result.failure(SeatunnelErrorEnum.ILLEGAL_STATE, e.getMessage());
+ }
+
+ @ExceptionHandler(value = Exception.class)
+ private Result<String> exceptionHandler(Exception e) {
+ logError(e);
+ return Result.failure(SeatunnelErrorEnum.UNKNOWN, e.getMessage());
+ }
+
+ private void logError(Throwable throwable) {
+ log.error(throwable.getMessage(), throwable);
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/Md5Utils.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/Md5Utils.java
new file mode 100644
index 0000000..781e95a
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/Md5Utils.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.utils;
+
+import org.springframework.util.DigestUtils;
+
+import java.nio.charset.StandardCharsets;
+
+public class Md5Utils {
+ private Md5Utils() {
+ }
+
+ public static String toMd5(String origin) {
+ return DigestUtils.md5DigestAsHex(origin.getBytes(StandardCharsets.UTF_8));
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/PasswordUtils.java b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/PasswordUtils.java
new file mode 100644
index 0000000..53fcb00
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/java/org/apache/seatunnel/app/utils/PasswordUtils.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.utils;
+
+import org.springframework.util.DigestUtils;
+
+import javax.validation.constraints.NotBlank;
+
+import java.nio.charset.StandardCharsets;
+
+public class PasswordUtils {
+ public static String encryptWithSalt(@NotBlank String salt, @NotBlank String password){
+ return DigestUtils.md5DigestAsHex(salt.concat(password).getBytes(StandardCharsets.UTF_8));
+ }
+}
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/application.yml b/seatunnel-server/seatunnel-app/src/main/resources/application.yml
new file mode 100644
index 0000000..1d05098
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/application.yml
@@ -0,0 +1,43 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+spring:
+ application:
+ name: seatunnel
+ datasource:
+ driver-class-name: com.mysql.jdbc.Driver
+ url: jdbc:mysql://127.0.0.1:3306/seatunnel?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
+ username: root
+ password: 123456
+ mvc:
+ pathmatch:
+ matching-strategy: ant_path_matcher
+ds:
+ script:
+ dir: /dj
+ project:
+ default: test_dj
+ tenant:
+ default: default
+ api:
+ token: 12345678
+ prefix: http://127.0.0.1:12345/dolphinscheduler
+
+jwt:
+ expireTime: 86400
+ secretKey: https://github.com/apache/incubator-seatunnel
+ algorithm: HS256
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/logback-spring.xml b/seatunnel-server/seatunnel-app/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..eb41353
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/logback-spring.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration scan="true" scanPeriod="10 seconds">
+ <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
+ <property name="APP_LOG_PATH" value="./logs" />
+ <property name="HOST_NAME" value="${HOSTNAME:-UNKNOWN}"/>
+ <property name="TRACE" value="[tr:%X{X-B3-TraceId:-},sp:%X{X-B3-SpanId:-}]"/>
+ <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+
+ <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${APP_NAME} ${HOST_NAME} %p ${TRACE} [%thread] [%C{0}.%M\(\):%L] - %m%n</pattern>
+ <charset>UTF-8</charset>
+ </encoder>
+ </appender>
+
+ <appender name="thirdPartyAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${APP_LOG_PATH}/thirdParty.${APP_NAME}.log</file>
+ <append>true</append>
+ <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+ <FileNamePattern>${APP_LOG_PATH}/thirdParty.${APP_NAME}.log.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+ <MaxHistory>30</MaxHistory>
+ <MaxFileSize>100MB</MaxFileSize>
+ </rollingPolicy>
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${APP_NAME} ${HOST_NAME} %p [%thread] [%C{0}.%M\(\):%L] - %m%n</pattern>
+ <charset>UTF-8</charset>
+ </encoder>
+ </appender>
+
+ <logger name="org.apache.seatunnel.app.dal.mapper" level="DEBUG" additivity="false">
+ <appender-ref ref="console" />
+ </logger>
+
+ <logger name="org.springframework" level="INFO" additivity="false">
+ <appender-ref ref="thirdPartyAppender" />
+ <appender-ref ref="console" />
+ </logger>
+
+ <root level="INFO">
+ <appender-ref ref="console" />
+ </root>
+</configuration>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/RoleMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/RoleMapper.xml
new file mode 100644
index 0000000..e1c133d
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/RoleMapper.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.RoleMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.Role">
+ <id column="id" jdbcType="INTEGER" property="id" />
+ <result column="type" jdbcType="INTEGER" property="type" />
+ <result column="role_name" jdbcType="VARCHAR" property="roleName" />
+ <result column="description" jdbcType="VARCHAR" property="description" />
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+ </resultMap>
+ <sql id="Base_Column_List">
+ id, `type`, `role_name`, `description`, create_time, update_time
+ </sql>
+ <insert id="insert" keyColumn="id" keyProperty="id" parameterType="org.apache.seatunnel.app.dal.entity.Role" useGeneratedKeys="true">
+ insert into `role` (`type`, `role_name`, `description`)
+ values (#{type,jdbcType=INTEGER}, #{roleName,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR})
+ </insert>
+ <select id="selectByRole" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List" />
+ from `role`
+ where role_name = #{roleName,jdbcType=VARCHAR}
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/RoleUserRelationMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/RoleUserRelationMapper.xml
new file mode 100644
index 0000000..27d5132
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/RoleUserRelationMapper.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.RoleUserRelationMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.RoleUserRelation">
+ <id column="id" jdbcType="INTEGER" property="id" />
+ <result column="role_id" jdbcType="INTEGER" property="roleId" />
+ <result column="user_id" jdbcType="INTEGER" property="userId" />
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+ </resultMap>
+ <sql id="Base_Column_List">
+ id, role_id, user_id, create_time, update_time
+ </sql>
+ <insert id="insert" parameterType="org.apache.seatunnel.app.dal.entity.RoleUserRelation">
+ insert into role_user_relation (id, role_id, user_id)
+ values (#{id,jdbcType=INTEGER}, #{roleId,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER})
+ </insert>
+ <select id="selectByUserIdAndRoleId" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List" />
+ from role_user_relation
+ where role_id = #{roleId,jdbcType=INTEGER}
+ and user_id = #{userId,jdbcType=INTEGER}
+ </select>
+ <delete id="deleteByUserId">
+ delete from role_user_relation
+ where user_id = #{userId,jdbcType=INTEGER}
+ </delete>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/SchedulerConfigMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/SchedulerConfigMapper.xml
new file mode 100644
index 0000000..30a6ad9
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/SchedulerConfigMapper.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.SchedulerConfigMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.SchedulerConfig">
+ <id column="id" jdbcType="INTEGER" property="id"/>
+ <result column="script_id" jdbcType="INTEGER" property="scriptId"/>
+ <result column="trigger_expression" jdbcType="VARCHAR" property="triggerExpression"/>
+ <result column="retry_times" jdbcType="INTEGER" property="retryTimes"/>
+ <result column="retry_interval" jdbcType="INTEGER" property="retryInterval"/>
+ <result column="active_start_time" jdbcType="TIMESTAMP" property="activeStartTime"/>
+ <result column="active_end_time" jdbcType="TIMESTAMP" property="activeEndTime"/>
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+ <result column="creator_id" jdbcType="INTEGER" property="creatorId"/>
+ <result column="update_id" jdbcType="INTEGER" property="updateId"/>
+ </resultMap>
+ <sql id="Base_Column_List">
+ id,
+ script_id,
+ trigger_expression,
+ retry_times,
+ retry_interval,
+ active_start_time,
+ active_end_time,
+ create_time,
+ update_time,
+ creator_id,
+ update_id
+ </sql>
+ <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from scheduler_config
+ where id = #{id,jdbcType=INTEGER}
+ </select>
+ <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
+ delete
+ from scheduler_config
+ where id = #{id,jdbcType=INTEGER}
+ </delete>
+ <insert id="insert" keyColumn="id" keyProperty="id"
+ parameterType="org.apache.seatunnel.app.dal.entity.SchedulerConfig" useGeneratedKeys="true">
+ insert into scheduler_config (script_id, trigger_expression, retry_times, retry_interval,
+ active_start_time, active_end_time, create_time,
+ update_time, creator_id, update_id)
+ values (#{scriptId,jdbcType=INTEGER}, #{retryTimes,jdbcType=INTEGER}, #{retryInterval,jdbcType=INTEGER},
+ #{activeStartTime,jdbcType=TIMESTAMP}, #{activeEndTime,jdbcType=TIMESTAMP},
+ #{createTime,jdbcType=TIMESTAMP},
+ #{updateTime,jdbcType=TIMESTAMP}, #{creatorId,jdbcType=INTEGER}, #{updateId,jdbcType=INTEGER})
+ </insert>
+ <select id="selectByScriptId" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from scheduler_config
+ where script_id = #{scriptId,jdbcType=INTEGER}
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptJobApplyMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptJobApplyMapper.xml
new file mode 100644
index 0000000..c5e28ed
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptJobApplyMapper.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.ScriptJobApplyMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.ScriptJobApply">
+ <id column="id" jdbcType="INTEGER" property="id"/>
+ <result column="script_id" jdbcType="INTEGER" property="scriptId"/>
+ <result column="scheduler_config_id" jdbcType="INTEGER" property="schedulerConfigId"/>
+ <result column="job_id" jdbcType="BIGINT" property="jobId"/>
+ <result column="operator_id" jdbcType="INTEGER" property="operatorId"/>
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+ </resultMap>
+ <sql id="Base_Column_List">
+ id,
+ script_id,
+ scheduler_config_id,
+ job_id,
+ operator_id,
+ create_time,
+ update_time
+ </sql>
+ <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from script_job_apply
+ where id = #{id,jdbcType=INTEGER}
+ </select>
+ <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
+ delete
+ from script_job_apply
+ where id = #{id,jdbcType=INTEGER}
+ </delete>
+ <insert id="insert" parameterType="org.apache.seatunnel.app.dal.entity.ScriptJobApply">
+ insert into script_job_apply (script_id, scheduler_config_id,
+ job_id, operator_id)
+ values (#{scriptId,jdbcType=INTEGER}, #{schedulerConfigId,jdbcType=INTEGER},
+ #{jobId,jdbcType=BIGINT}, #{operatorId,jdbcType=INTEGER})
+ </insert>
+ <update id="update">
+ update script_job_apply
+ set script_id = #{scriptId,jdbcType=INTEGER},
+ scheduler_config_id = #{schedulerConfigId,jdbcType=INTEGER},
+ job_id = #{jobId},
+ operator_id = #{operatorId,jdbcType=INTEGER}
+ </update>
+ <select id="selectByScriptId" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from script_job_apply
+ where script_id = #{scriptId,jdbcType=INTEGER}
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptMapper.xml
new file mode 100644
index 0000000..c74563b
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptMapper.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.ScriptMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.Script">
+ <id column="id" jdbcType="INTEGER" property="id"/>
+ <result column="name" jdbcType="VARCHAR" property="name"/>
+ <result column="type" jdbcType="TINYINT" property="type"/>
+ <result column="status" jdbcType="TINYINT" property="status"/>
+ <result column="content" jdbcType="LONGVARCHAR" property="content"/>
+ <result column="content_md5" jdbcType="VARCHAR" property="contentMd5"/>
+ <result column="creator_id" jdbcType="INTEGER" property="creatorId"/>
+ <result column="mender_id" jdbcType="INTEGER" property="menderId"/>
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+ </resultMap>
+ <sql id="Base_Column_List">
+ id,
+ `name`,
+ `type`,
+ `status`,
+ content,
+ content_md5,
+ creator_id,
+ mender_id,
+ create_time,
+ update_time
+ </sql>
+ <insert id="insert" keyColumn="id" keyProperty="id" parameterType="org.apache.seatunnel.app.dal.entity.Script"
+ useGeneratedKeys="true">
+ insert into `script` (name, type, status, creator_id, mender_id)
+ VALUES (#{name,jdbcType=VARCHAR}, #{type,jdbcType=TINYINT}, #{status,jdbcType=TINYINT},
+ #{creatorId,jdbcType=INTEGER},
+ #{menderId,jdbcType=INTEGER})
+ </insert>
+ <update id="updateContentByPrimaryKey">
+ update `script`
+ set `content` = #{content,jdbcType=VARCHAR},
+ `content_md5` = #{contentMd5,jdbcType=VARCHAR},
+ `mender_id` = #{menderId, jdbcType=INTEGER}
+ where id = #{id,jdbcType=INTEGER}
+ </update>
+ <update id="updateStatus">
+ update `script`
+ set `status` = #{code,jdbcType=TINYINT}
+ where id = #{id,jdbcType=INTEGER}
+ </update>
+ <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from script
+ where id = #{id,jdbcType=INTEGER}
+ </select>
+ <select id="selectBySelectiveAndPage" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from script
+ <where>
+ <if test="script.name != null and script.name != ''">
+ and `name` = #{script.name,jdbcType=VARCHAR}
+ </if>
+ <if test="script.status != null">
+ and `status` = #{script.status,jdbcType=TINYINT}
+ </if>
+ </where>
+ limit #{start,jdbcType=INTEGER}, #{offset,jdbcType=INTEGER}
+ </select>
+ <select id="selectByNameAndCreatorAndStatusNotEq" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from script
+ where `name` = #{name,jdbcType=VARCHAR}
+ and `creator_id` = #{creatorId,jdbcType=INTEGER}
+ and `status` != #{status,jdbcType=TINYINT}
+ </select>
+ <select id="countBySelectiveAndPage" resultType="java.lang.Integer">
+ select
+ count(1)
+ from script
+ <where>
+ <if test="script.name != null and script.name != ''">
+ and `name` = #{script.name,jdbcType=VARCHAR}
+ </if>
+ <if test="script.status != null">
+ and `status` = #{script.status,jdbcType=TINYINT}
+ </if>
+ </where>
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptParamMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptParamMapper.xml
new file mode 100644
index 0000000..6971fc8
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/ScriptParamMapper.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.ScriptParamMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.ScriptParam">
+ <id column="id" jdbcType="INTEGER" property="id"/>
+ <result column="script_id" jdbcType="INTEGER" property="scriptId"/>
+ <result column="key" jdbcType="VARCHAR" property="key"/>
+ <result column="value" jdbcType="VARCHAR" property="value"/>
+ <result column="status" jdbcType="TINYINT" property="status"/>
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+ </resultMap>
+ <sql id="Base_Column_List">
+ id,
+ script_id,
+ `key`,
+ `value`,
+ `status`,
+ create_time,
+ update_time
+ </sql>
+ <insert id="batchInsert" parameterType="map">
+ insert into `script_param` (`script_id`, `key`, `value`, `status`)
+ values
+ <foreach collection="params" item="item" separator=",">
+ (#{item.scriptId,jdbcType=INTEGER}, #{item.key,jdbcType=VARCHAR}, #{item.value,jdbcType=VARCHAR},
+ #{item.status,jdbcType=TINYINT})
+ </foreach>
+ </insert>
+ <update id="updateStatusByScriptId">
+ update `script_param`
+ set `status` = #{code, jdbcType=TINYINT}
+ where `script_id` = #{scriptId, jdbcType=INTEGER}
+ </update>
+ <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from script_param
+ where id = #{id,jdbcType=INTEGER}
+ </select>
+ <select id="selectByScriptId" resultType="org.apache.seatunnel.app.dal.entity.ScriptParam">
+ select
+ <include refid="Base_Column_List"/>
+ from script_param
+ where script_id = #{scriptId,jdbcType=INTEGER}
+ and `status` != 1
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserLoginLogMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserLoginLogMapper.xml
new file mode 100644
index 0000000..f8f9444
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserLoginLogMapper.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper
+ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.UserLoginLogMapper">
+
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.UserLoginLog">
+ <id property="id" column="id" jdbcType="BIGINT"/>
+ <result property="userId" column="user_id" jdbcType="INTEGER"/>
+ <result property="token" column="token" jdbcType="VARCHAR"/>
+ <result property="tokenStatus" column="token_status" jdbcType="BOOLEAN"/>
+ <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+ <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+ </resultMap>
+
+ <sql id="Base_Column_List">
+ id,
+ user_id,
+ token,
+ token_status,
+ create_time,
+ update_time
+ </sql>
+
+ <insert id="insert" keyColumn="id" keyProperty="id" parameterType="org.apache.seatunnel.app.dal.entity.UserLoginLog"
+ useGeneratedKeys="true">
+ insert into `user_login_log` (user_id, token, `token_status`)
+ VALUES (#{userId,jdbcType=INTEGER}, #{token,jdbcType=VARCHAR}, #{tokenStatus,jdbcType=BOOLEAN})
+ </insert>
+
+ <update id="updateStatus">
+ update user_login_log
+ set token_status = #{enable,jdbcType=BOOLEAN}
+ where user_id = #{userId,jdbcType=INTEGER} and token_status != #{enable}
+ </update>
+ <select id="checkLastTokenEnable" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from user_login_log
+ where user_id = #{userId,jdbcType=INTEGER}
+ order by id desc
+ limit 1
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml
new file mode 100644
index 0000000..1c22238
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/main/resources/org/apache/seatunnel/app/dal/mapper/UserMapper.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.apache.seatunnel.app.dal.mapper.UserMapper">
+ <resultMap id="BaseResultMap" type="org.apache.seatunnel.app.dal.entity.User">
+ <id column="id" jdbcType="INTEGER" property="id"/>
+ <result column="username" jdbcType="VARCHAR" property="username"/>
+ <result column="password" jdbcType="VARCHAR" property="password"/>
+ <result column="status" jdbcType="TINYINT" property="status"/>
+ <result column="type" jdbcType="TINYINT" property="type"/>
+ <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
+ <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
+ </resultMap>
+ <sql id="Base_Column_List">
+ id,
+ username,
+ `password`,
+ `status`,
+ `type`,
+ create_time,
+ update_time
+ </sql>
+ <insert id="insert" keyColumn="id" keyProperty="id" parameterType="org.apache.seatunnel.app.dal.entity.User"
+ useGeneratedKeys="true">
+ insert into `user` (username, password, status, type)
+ value (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{status,jdbcType=TINYINT},
+ #{type,jdbcType=TINYINT})
+ </insert>
+ <update id="updateByPrimaryKey">
+ update `user`
+ set username = #{username,jdbcType=VARCHAR},
+ password = #{password,jdbcType=VARCHAR},
+ status = #{status,jdbcType=TINYINT},
+ type = #{type,jdbcType=TINYINT}
+ where id = #{id,jdbcType=INTEGER}
+ </update>
+ <update id="updateStatus">
+ update `user`
+ set status = #{status,jdbcType=TINYINT}
+ where id = #{id,jdbcType=INTEGER}
+ </update>
+ <delete id="deleteByPrimaryKey">
+ delete
+ from `user`
+ where id = #{id,jdbcType=INTEGER}
+ </delete>
+ <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from `user`
+ where id = #{id,jdbcType=INTEGER}
+ </select>
+ <select id="selectBySelectiveAndPage" resultType="org.apache.seatunnel.app.dal.entity.User">
+ select
+ <include refid="Base_Column_List"/>
+ from `user`
+ <where>
+ <if test="user.username != null and user.username != ''">
+ and `username` = #{user.username,jdbcType=VARCHAR}
+ </if>
+ </where>
+ limit #{start,jdbcType=INTEGER}, #{offset,jdbcType=INTEGER}
+ </select>
+ <select id="selectByName" resultType="org.apache.seatunnel.app.dal.entity.User">
+ select
+ <include refid="Base_Column_List"/>
+ from `user`
+ where username = #{username,jdbcType=VARCHAR}
+ </select>
+ <select id="countBySelective" resultType="java.lang.Integer">
+ select
+ count(1)
+ from `user`
+ <where>
+ <if test="user.username != null and user.username != ''">
+ and `username` = #{user.username,jdbcType=VARCHAR}
+ </if>
+ </where>
+ </select>
+ <select id="selectByNameAndPasswd" resultType="org.apache.seatunnel.app.dal.entity.User">
+ select
+ <include refid="Base_Column_List"/>
+ from `user`
+ where username = #{username,jdbcType=VARCHAR} and password = #{password,jdbcType=VARCHAR}
+ </select>
+</mapper>
diff --git a/seatunnel-server/seatunnel-app/src/test/java/org/apache/seatunnel/app/WebMvcApplicationTest.java b/seatunnel-server/seatunnel-app/src/test/java/org/apache/seatunnel/app/WebMvcApplicationTest.java
new file mode 100644
index 0000000..97526ca
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/test/java/org/apache/seatunnel/app/WebMvcApplicationTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.web.servlet.MockMvc;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
+public class WebMvcApplicationTest {
+
+ @LocalServerPort
+ protected int port;
+
+ @Autowired
+ protected MockMvc mockMvc;
+
+}
diff --git a/seatunnel-server/seatunnel-app/src/test/java/org/apache/seatunnel/app/controller/UserControllerTest.java b/seatunnel-server/seatunnel-app/src/test/java/org/apache/seatunnel/app/controller/UserControllerTest.java
new file mode 100644
index 0000000..4b1b911
--- /dev/null
+++ b/seatunnel-server/seatunnel-app/src/test/java/org/apache/seatunnel/app/controller/UserControllerTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.app.controller;
+
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.apache.seatunnel.app.WebMvcApplicationTest;
+import org.apache.seatunnel.app.common.Result;
+import org.apache.seatunnel.app.dal.dao.impl.UserDaoImpl;
+import org.apache.seatunnel.app.domain.request.user.AddUserReq;
+import org.apache.seatunnel.app.domain.response.user.AddUserRes;
+import org.apache.seatunnel.common.utils.JsonUtils;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
+
+@Disabled("todo:this test is not working, waiting fix")
+public class UserControllerTest extends WebMvcApplicationTest {
+
+ @MockBean
+ private UserDaoImpl userDaoImpl;
+
+ @Test
+ public void testAdd() throws Exception {
+ AddUserReq requestDTO = new AddUserReq();
+ requestDTO.setUsername("admin");
+ requestDTO.setPassword("123456");
+ requestDTO.setStatus(new Byte("1"));
+ requestDTO.setType(new Byte("1"));
+ String url = "/api/v1/user/user";
+ when(this.userDaoImpl.add(Mockito.any())).thenReturn(1);
+ MvcResult mvcResult = mockMvc.perform(post(url).contentType(MediaType.APPLICATION_JSON).content(JsonUtils.toJsonString(requestDTO)))
+ .andExpect(status().isOk())
+ .andDo(MockMvcResultHandlers.print())
+ .andReturn();
+ String result = mvcResult.getResponse().getContentAsString();
+ Result<AddUserRes> data = JsonUtils.parseObject(result, new TypeReference<Result<AddUserRes>>() {
+ });
+ Assertions.assertTrue(data.isSuccess());
+ Assertions.assertNotNull(data.getData());
+ }
+
+}
diff --git a/seatunnel-server/seatunnel-scheduler/pom.xml b/seatunnel-server/seatunnel-scheduler/pom.xml
new file mode 100644
index 0000000..80c9aa4
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>seatunnel-server</artifactId>
+ <groupId>org.apache.seatunnel</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>seatunnel-scheduler</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>seatunnel-scheduler-dolphinscheduler</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.seatunnel</groupId>
+ <artifactId>seatunnel-spi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/pom.xml b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/pom.xml
new file mode 100644
index 0000000..5bf89de
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>seatunnel-scheduler</artifactId>
+ <groupId>org.apache.seatunnel</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>seatunnel-scheduler-dolphinscheduler</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ <version>${spring.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- http -->
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ <version>${javax.annotation-api.version}</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/ExecuteTypeEnum.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/ExecuteTypeEnum.java
new file mode 100644
index 0000000..f8b77a8
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/ExecuteTypeEnum.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler;
+
+public enum ExecuteTypeEnum {
+ NONE,
+ REPEAT_RUNNING,
+ RECOVER_SUSPENDED_PROCESS,
+ START_FAILURE_TASK_PROCESS,
+ STOP,
+ PAUSE
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/IDolphinschedulerService.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/IDolphinschedulerService.java
new file mode 100644
index 0000000..a460ec2
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/IDolphinschedulerService.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler;
+
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListProcessInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListTaskInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProcessInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ResourceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.SchedulerDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.StartProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.UpdateProcessDefinitionDto;
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceLogDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobDto;
+
+import java.util.List;
+
+public interface IDolphinschedulerService {
+
+ ProcessDefinitionDto createOrUpdateProcessDefinition(UpdateProcessDefinitionDto dto);
+
+ PageData<ProcessDefinitionDto> listProcessDefinition(ListProcessDefinitionDto dto);
+
+ ProcessDefinitionDto fetchProcessDefinitionByName(String processDefinitionName);
+
+ void startProcessDefinition(StartProcessDefinitionDto dto);
+
+ void updateProcessDefinitionState(long processDefinitionCode, String processDefinitionName, String state);
+
+ SchedulerDto createOrUpdateSchedule(JobDto dto);
+
+ List<SchedulerDto> listSchedule(long processDefinitionCode);
+
+ void scheduleOnline(int scheduleId);
+
+ void scheduleOffline(int scheduleId);
+
+ List<Long> genTaskCodes(long projectCode, int num);
+
+ ResourceDto createOrUpdateScriptContent(String resourceName, String content);
+
+ PageData<TaskInstanceDto> listTaskInstance(ListTaskInstanceDto dto);
+
+ void deleteProcessDefinition(long code);
+
+ PageData<ProcessInstanceDto> listProcessInstance(ListProcessInstanceDto dto);
+
+ InstanceLogDto queryInstanceLog(long instanceId);
+
+ void killProcessInstance(long processInstanceId);
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/constants/DolphinschedulerConstants.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/constants/DolphinschedulerConstants.java
new file mode 100644
index 0000000..e8f886f
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/constants/DolphinschedulerConstants.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.constants;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class DolphinschedulerConstants {
+
+ /**
+ * api url
+ */
+ public static final String QUERY_PROJECT_LIST_PAGING = "/projects";
+ public static final String QUERY_LIST_PAGING = "/projects/%s/process-definition";
+ public static final String GEN_TASK_CODE_LIST = "/projects/%s/task-definition/gen-task-codes";
+ public static final String VERIFY_RESOURCE_NAME = "/resources/verify-name";
+ public static final String QUERY_RESOURCE = "/resources/%s";
+ public static final String ONLINE_CREATE_RESOURCE = "/resources/online-create";
+ public static final String UPDATE_CONTENT = "/resources/%s/update-content";
+ public static final String LOG_DETAIL = "/log/detail";
+ public static final String RELEASE = "/projects/%s/process-definition/%s/release";
+ public static final String START_PROCESS_INSTANCE = "/projects/%s/executors/start-process-instance";
+ public static final String QUERY_PROCESS_DEFINITION_BY_NAME = "/projects/%s/process-definition/query-by-name";
+ public static final String QUERY_TASK_LIST_PAGING = "/projects/%s/task-instances";
+ public static final String CREATE_PROCESS_DEFINITION = "/projects/%s/process-definition/";
+ public static final String CREATE_SCHEDULE = "/projects/%s/schedules/";
+ public static final String QUERY_SCHEDULE_LIST_PAGING = "/projects/%s/schedules";
+ public static final String SCHEDULE_ONLINE = "/projects/%s/schedules/%s/online";
+ public static final String SCHEDULE_OFFLINE = "/projects/%s/schedules/%s/offline";
+ public static final String DELETE_PROCESS_DEFINITION = "/projects/%s/process-definition/%s";
+ public static final String PROCESS_INSTANCE_LIST = "/projects/%s/process-instances";
+ public static final String EXECUTE = "/projects/%s/executors/execute";
+
+ /**
+ * request param
+ */
+ public static final String TOKEN = "token";
+ public static final String SEARCH_VAL = "searchVal";
+ public static final String PAGE_SIZE = "pageSize";
+ public static final int PAGE_SIZE_DEFAULT = 10;
+ public static final int PAGE_SIZE_MIN = 1;
+ public static final String PAGE_NO = "pageNo";
+ public static final int PAGE_NO_DEFAULT = 1;
+ public static final String GEN_NUM = "genNum";
+ public static final int GEN_NUM_DEFAULT = 1;
+ public static final String RESOURCE_SEPARATOR = "/";
+ public static final String FULL_NAME = "fullName";
+ public static final String RESOURCE_TYPE = "type";
+ public static final String RESOURCE_TYPE_FILE = "FILE";
+ public static final String RESOURCE_TYPE_FILE_SUFFIX = "suffix";
+ public static final String RESOURCE_TYPE_FILE_SUFFIX_DEFAULT = "conf";
+ public static final String RESOURCE_TYPE_FILE_CONTENT = "content";
+ public static final String RESOURCE_TYPE_UDF = "UDF";
+ public static final int RESOURCE_ID_DEFAULT = 0;
+ public static final String RESOURCE_ID = "id";
+ public static final String TASK_INSTANCE_ID = "taskInstanceId";
+ public static final String LOG_SKIP_LINE_NUM = "skipLineNum";
+ public static final String LOG_LIMIT_NUM = "limit";
+ public static final String PROCESS_DEFINITION_NAME = "name";
+ public static final String RELEASE_STATE = "releaseState";
+ public static final String RELEASE_STATE_ONLINE = "ONLINE";
+ public static final String RELEASE_STATE_OFFLINE = "OFFLINE";
+ public static final String FAILURE_STRATEGY = "failureStrategy";
+ public static final String FAILURE_STRATEGY_DEFAULT = "CONTINUE";
+ public static final String WORKER_GROUP = "workerGroup";
+ public static final String WORKER_GROUP_DEFAULT = "default";
+ public static final String WARNING_TYPE = "warningType";
+ public static final String WARNING_TYPE_DEFAULT = "NONE";
+ public static final String WARNING_GROUP_ID = "warningGroupId";
+ public static final int WARNING_GROUP_ID_DEFAULT = 0;
+ public static final String TASK_DEPEND_TYPE_DEFAULT = "TASK_POST";
+ public static final String RUN_MODE_DEFAULT = "RUN_MODE_SERIAL";
+ public static final String RUN_MODE_PARALLEL = "RUN_MODE_PARALLEL";
+ public static final String PROCESS_INSTANCE_PRIORITY = "processInstancePriority";
+ public static final String PROCESS_INSTANCE_PRIORITY_DEFAULT = "MEDIUM";
+ public static final int DRY_RUN = 0;
+ public static final String PROCESS_DEFINITION = "processDefinition";
+ public static final String PROCESS_INSTANCE_NAME = "processInstanceName";
+ public static final String LOCATIONS = "locations";
+ public static final String LOCATIONS_X = "x";
+ public static final int LOCATIONS_X_DEFAULT = 200;
+ public static final String LOCATIONS_Y = "y";
+ public static final int LOCATIONS_Y_DEFAULT = 200;
+ public static final String TASK_CODE = "taskCode";
+ public static final String TASK_DEFINITION_JSON = "taskDefinitionJson";
+ public static final String TASK_RELATION_JSON = "taskRelationJson";
+ public static final String TENANT_CODE = "tenantCode";
+ public static final String TASK_RELATION_JSON_NAME = "name";
+ public static final String PRE_TASK_CODE = "preTaskCode";
+ public static final long PRE_TASK_CODE_DEFAULT = 0;
+ public static final String PRE_TASK_VERSION = "preTaskVersion";
+ public static final int PRE_TASK_VERSION_DEFAULT = 0;
+ public static final String POST_TASK_CODE = "postTaskCode";
+ public static final String POST_TASK_VERSION = "postTaskVersion";
+ public static final int POST_TASK_VERSION_DEFAULT = 1;
+ public static final String CONDITION_TYPE = "conditionType";
+ public static final int CONDITION_TYPE_DEFAULT = 0;
+ public static final String CONDITION_PARAMS = "conditionParams";
+ public static final String TASK_DEFINITION_JSON_CODE = "code";
+ public static final String TASK_DEFINITION_JSON_NAME = "name";
+ public static final String VERSION = "version";
+ public static final int VERSION_DEFAULT = 1;
+ public static final String DESCRIPTION = "description";
+ public static final String DESCRIPTION_DEFAULT = "";
+ public static final String DELAY_TIME = "delayTime";
+ public static final int DELAY_TIME_DEFAULT = 0;
+ public static final String TASK_TYPE = "taskType";
+ public static final String TASK_TYPE_DEFAULT = "SHELL";
+ public static final String TASK_PARAMS = "taskParams";
+ public static final String RESOURCE_LIST = "resourceList";
+ public static final String LOCAL_PARAMS = "localParams";
+ public static final String LOCAL_PARAMS_PROP = "prop";
+ public static final String LOCAL_PARAMS_DIRECT = "direct";
+ public static final String LOCAL_PARAMS_DIRECT_DEFAULT = "IN";
+ public static final String LOCAL_PARAMS_TYPE = "type";
+ public static final String LOCAL_PARAMS_TYPE_DEFAULT = "VARCHAR";
+ public static final String LOCAL_PARAMS_VALUE = "value";
+ public static final String RAW_SCRIPT = "rawScript";
+ public static final String DEPENDENCE = "dependence";
+ public static final Map<String, Object> DEPENDENCE_DEFAULT = Collections.emptyMap();
+ public static final String CONDITION_RESULT = "conditionResult";
+ public static final String SUCCESS_NODE = "successNode";
+ public static final List<Object> SUCCESS_NODE_DEFAULT = Collections.emptyList();
+ public static final String FAILED_NODE = "failedNode";
+ public static final List<Object> FAILED_NODE_DEFAULT = Collections.emptyList();
+ public static final String WAIT_START_TIMEOUT = "waitStartTimeout";
+ public static final int WAIT_START_TIMEOUT_DEFAULT = 0;
+ public static final String SWITCH_RESULT = "switchResult";
+ public static final int SWITCH_RESULT_DEFAULT = 0;
+ public static final String FLAG = "flag";
+ public static final String FLAG_DEFAULT = "YES";
+ public static final String TASK_PRIORITY = "taskPriority";
+ public static final String TASK_PRIORITY_DEFAULT = "MEDIUM";
+ public static final String FAIL_RETRY_TIMES = "failRetryTimes";
+ public static final String FAIL_RETRY_INTERVAL = "failRetryInterval";
+ public static final String TIMEOUT_FLAG = "timeoutFlag";
+ public static final String TIMEOUT_FLAG_DEFAULT = "CLOSE";
+ public static final String TIMEOUT_NOTIFY_STRATEGY = "timeoutNotifyStrategy";
+ public static final String TIMEOUT_NOTIFY_STRATEGY_DEFAULT = "WARN";
+ public static final String TIMEOUT = "timeout";
+ public static final int TIMEOUT_DEFAULT = 0;
+ public static final String ENVIRONMENT_CODE = "environmentCode";
+ public static final int ENVIRONMENT_CODE_DEFAULT = -1;
+ public static final String PROCESS_DEFINITION_CODE = "processDefinitionCode";
+ public static final String START_TIME = "startTime";
+ public static final String END_TIME = "endTime";
+ public static final String CRONTAB = "crontab";
+ public static final String TIMEZONE_ID = "timezoneId";
+ public static final String TIMEZONE_ID_DEFAULT = "Asia/Shanghai";
+ public static final String SCHEDULE = "schedule";
+ public static final String SCHEDULE_ID = "id";
+ public static final String DEFAULT_FILE_SUFFIX = ".conf";
+ public static final String EXEC_TYPE_DEFAULT = "START_PROCESS";
+ public static final String EXEC_TYPE_COMPLEMENT = "COMPLEMENT_DATA";
+ public static final String DEPENDENT_MODE_DEFAULT = "OFF_MODE";
+ public static final String PROCESS_INSTANCE_ID = "processInstanceId";
+ public static final String EXECUTE_TYPE = "executeType";
+ public static final int LOG_SKIP_LINE_NUM_DEFAULT = 0;
+ public static final int LOG_LIMIT_NUM_DEFAULT = Integer.MAX_VALUE;
+
+ /**
+ * response param
+ */
+ public static final String DATA = "data";
+ public static final String DATA_TOTAL_LIST = "totalList";
+ public static final String DATA_TOTAL = "total";
+ public static final String CODE = "code";
+ public static final int CODE_SUCCESS = 0;
+ public static final String MSG = "msg";
+ public static final String LOG_MESSAGE = "message";
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/BaseListDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/BaseListDto.java
new file mode 100644
index 0000000..844e9ab
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/BaseListDto.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import lombok.Data;
+
+@Data
+public class BaseListDto {
+ protected String name;
+ protected int pageNo;
+ protected int pageSize;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ConditionResult.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ConditionResult.java
new file mode 100644
index 0000000..629b2be
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ConditionResult.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ConditionResult {
+ private List<Object> successNode;
+ private List<Object> failedNode;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListProcessDefinitionDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListProcessDefinitionDto.java
new file mode 100644
index 0000000..19f293a
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListProcessDefinitionDto.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import lombok.Data;
+
+@Data
+public class ListProcessDefinitionDto extends BaseListDto{
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListProcessInstanceDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListProcessInstanceDto.java
new file mode 100644
index 0000000..3cef3d5
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListProcessInstanceDto.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import lombok.Data;
+
+@Data
+public class ListProcessInstanceDto extends BaseListDto{
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListTaskInstanceDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListTaskInstanceDto.java
new file mode 100644
index 0000000..27e78a8
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ListTaskInstanceDto.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import lombok.Data;
+
+@Data
+public class ListTaskInstanceDto extends BaseListDto{
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/LocalParam.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/LocalParam.java
new file mode 100644
index 0000000..4596d02
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/LocalParam.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LocalParam {
+ private String prop;
+ private String direct;
+ private String type;
+ private Object value;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/LocationDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/LocationDto.java
new file mode 100644
index 0000000..33fa653
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/LocationDto.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class LocationDto {
+ private Long taskCode;
+ private int x;
+ private int y;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/OnlineCreateResourceDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/OnlineCreateResourceDto.java
new file mode 100644
index 0000000..acd909b
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/OnlineCreateResourceDto.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.google.common.collect.Maps;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Map;
+
+@Builder
+@Data
+public class OnlineCreateResourceDto {
+ private String type;
+ private int pid;
+ private String currentDir;
+ private String fileName;
+ private String suffix;
+ private String content;
+
+ public Map<String, Object> toMap() {
+ final Map<String, Object> map = Maps.newHashMap();
+ map.put("type", type);
+ map.put("pid", pid);
+ map.put("currentDir", currentDir);
+ map.put("fileName", fileName);
+ map.put("suffix", suffix);
+ map.put("content", content);
+ return map;
+ }
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProcessDefinitionDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProcessDefinitionDto.java
new file mode 100644
index 0000000..58be7eb
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProcessDefinitionDto.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import static org.apache.seatunnel.server.common.DateUtils.DEFAULT_DATETIME_FORMAT;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ProcessDefinitionDto {
+ private int id;
+ private long code;
+ private String name;
+ private String releaseState;
+ private long projectCode;
+ private String description;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date createTime;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date updateTime;
+ private String username;
+ private String projectName;
+ private String locations;
+ private String scheduleReleaseState;
+ private int timeout;
+ private int tenantId;
+ private String tenantCode;
+ private String modifyBy;
+ private int warningGroupId;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProcessInstanceDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProcessInstanceDto.java
new file mode 100644
index 0000000..9cdcafa
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProcessInstanceDto.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import static org.apache.seatunnel.server.common.DateUtils.DEFAULT_DATETIME_FORMAT;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class ProcessInstanceDto {
+ private int id;
+ private long processDefinitionCode;
+ private int processDefinitionVersion;
+ private String state;
+ private String recovery;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date startTime;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date endTime;
+ private int runTimes;
+ private String name;
+ private String host;
+ private String processDefinition;
+ private String commandType;
+ private String commandParam;
+ private String taskDependType;
+ private int maxTryTimes;
+ private String failureStrategy;
+ private String warningType;
+ private String warningGroupId;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date scheduleTime;
+ private String commandStartTime;
+ private String globalParams;
+ private String dagData;
+ private int executorId;
+ private String executorName;
+ private String tenantCode;
+ private String queue;
+ private String isSubProcess;
+ private String locations;
+ private String historyCmd;
+ private String dependenceScheduleTimes;
+ private String duration;
+ private String processInstancePriority;
+ private String workerGroup;
+ private String environmentCode;
+ private int timeout;
+ private int tenantId;
+ private String varPool;
+ private int nextProcessInstanceId;
+ private int dryRun;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date restartTime;
+ private String cmdTypeIfComplement;
+ private boolean complementData;
+ private boolean blocked;
+ private boolean processInstanceStop;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProjectDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProjectDto.java
new file mode 100644
index 0000000..edcf199
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ProjectDto.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ProjectDto {
+ private long code;
+ private String name;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ResourceDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ResourceDto.java
new file mode 100644
index 0000000..995e981
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/ResourceDto.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true, value = {"pid"})
+public class ResourceDto {
+ private int id;
+ private int pid;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/SchedulerDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/SchedulerDto.java
new file mode 100644
index 0000000..acc6600
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/SchedulerDto.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import static org.apache.seatunnel.server.common.DateUtils.DEFAULT_DATETIME_FORMAT;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SchedulerDto {
+ private int id;
+ private long processDefinitionCode;
+ private String processDefinitionName;
+ private String projectName;
+ private String definitionDescription;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date startTime;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date endTime;
+ private String timezoneId;
+ private String crontab;
+ private String failureStrategy;
+ private String warningType;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date createTime;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date updateTime;
+ private int userId;
+ private String userName;
+ private String releaseState;
+ private int warningGroupId;
+ private String processInstancePriority;
+ private String workerGroup;
+ private int environmentCode;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/StartProcessDefinitionDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/StartProcessDefinitionDto.java
new file mode 100644
index 0000000..81e6d75
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/StartProcessDefinitionDto.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.google.common.collect.Maps;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Map;
+
+@Builder
+@Data
+public class StartProcessDefinitionDto {
+ private long processDefinitionCode;
+ private String failureStrategy;
+ private String warningType;
+ private int warningGroupId;
+ private String taskDependType;
+ private String runMode;
+ private String processInstancePriority;
+ private String workerGroup;
+ private int dryRun;
+ private String scheduleTime;
+ private String execType;
+ private String dependentMode;
+ private Integer expectedParallelismNumber;
+
+ public Map<String, String> toMap() {
+ final Map<String, String> map = Maps.newHashMap();
+ map.put("processDefinitionCode", String.valueOf(processDefinitionCode));
+ map.put("failureStrategy", failureStrategy);
+ map.put("warningType", warningType);
+ map.put("warningGroupId", String.valueOf(warningGroupId));
+ map.put("taskDependType", taskDependType);
+ map.put("runMode", runMode);
+ map.put("processInstancePriority", processInstancePriority);
+ map.put("workerGroup", workerGroup);
+ map.put("dryRun", String.valueOf(dryRun));
+ map.put("scheduleTime", scheduleTime);
+ map.put("execType", execType);
+ map.put("dependentMode", dependentMode);
+ map.put("expectedParallelismNumber", String.valueOf(expectedParallelismNumber));
+ return map;
+ }
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskDefinitionDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskDefinitionDto.java
new file mode 100644
index 0000000..c0b0256
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskDefinitionDto.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TaskDefinitionDto {
+ private Long code;
+ private String name;
+ private String description;
+ private String taskType;
+ private TaskParamDto taskParams;
+ private String flag;
+ private String taskPriority;
+ private String workerGroup;
+ private int failRetryTimes;
+ private int failRetryInterval;
+ private String timeoutFlag;
+ private String timeoutNotifyStrategy;
+ private int timeout;
+ private int delayTime;
+ private int environmentCode;
+ private int version;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskDescriptionDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskDescriptionDto.java
new file mode 100644
index 0000000..1dc9716
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskDescriptionDto.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+@Builder
+public class TaskDescriptionDto {
+ private String name;
+ private String executeScript;
+ private String content;
+ private Map<String, Object> params;
+ private int retryInterval;
+ private int retryTimes;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskInstanceDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskInstanceDto.java
new file mode 100644
index 0000000..c036df9
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskInstanceDto.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import static org.apache.seatunnel.server.common.DateUtils.DEFAULT_DATETIME_FORMAT;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TaskInstanceDto {
+ private boolean taskComplete;
+ private boolean firstRun;
+ private int dryRun;
+ private String flag;
+ private long environmentCode;
+ private String processInstance;
+ private int pid;
+ private String taskParams;
+ private String duration;
+ private String taskType;
+ private long taskCode;
+ private String taskInstancePriority;
+ private String host;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date startTime;
+ private int id;
+ private String state;
+ private String workerGroup;
+ private String processInstancePriority;
+ private int processInstanceId;
+ private int executorId;
+ private String firstSubmitTime;
+ private String resources;
+ private int maxRetryTimes;
+ private int retryTimes;
+ private String executorName;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date submitTime;
+ private String name;
+ private int retryInterval;
+ @JsonFormat(pattern = DEFAULT_DATETIME_FORMAT)
+ private Date endTime;
+ private String processInstanceName;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskParamDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskParamDto.java
new file mode 100644
index 0000000..36ab04e
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskParamDto.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TaskParamDto {
+ private List<ResourceDto> resourceList;
+ private List<LocalParam> localParams;
+ private String rawScript;
+ private Map<String, Object> dependence;
+ private ConditionResult conditionResult;
+ private int waitStartTimeout;
+ private int switchResult;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskRelationDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskRelationDto.java
new file mode 100644
index 0000000..c0c80b2
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/TaskRelationDto.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TaskRelationDto {
+ private String name;
+ private long preTaskCode;
+ private int preTaskVersion;
+ private long postTaskCode;
+ private long postTaskVersion;
+ private int conditionType;
+ private String conditionParams;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/UpdateProcessDefinitionDto.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/UpdateProcessDefinitionDto.java
new file mode 100644
index 0000000..1486e44
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/dto/UpdateProcessDefinitionDto.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@Builder
+public class UpdateProcessDefinitionDto {
+ private Long processDefinitionCode;
+ private String name;
+ private Date startTime;
+ private Date endTime;
+ private String cronExpression;
+ private TaskDescriptionDto taskDescriptionDto;
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/DolphinschedulerServiceImpl.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/DolphinschedulerServiceImpl.java
new file mode 100644
index 0000000..3cca66f
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/DolphinschedulerServiceImpl.java
@@ -0,0 +1,679 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.impl;
+
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.CODE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.CODE_SUCCESS;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.CONDITION_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.CREATE_PROCESS_DEFINITION;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.CREATE_SCHEDULE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.CRONTAB;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DATA;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DATA_TOTAL;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DATA_TOTAL_LIST;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DEFAULT_FILE_SUFFIX;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DELAY_TIME_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DELETE_PROCESS_DEFINITION;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DEPENDENCE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DESCRIPTION_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.END_TIME;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.ENVIRONMENT_CODE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.ENVIRONMENT_CODE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.EXECUTE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.EXECUTE_TYPE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.FAILED_NODE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.FAILURE_STRATEGY;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.FAILURE_STRATEGY_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.FLAG_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.FULL_NAME;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.GEN_NUM;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.GEN_NUM_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.GEN_TASK_CODE_LIST;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOCAL_PARAMS_DIRECT_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOCAL_PARAMS_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOCATIONS;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOCATIONS_X_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOCATIONS_Y_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOG_DETAIL;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOG_LIMIT_NUM;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOG_LIMIT_NUM_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOG_MESSAGE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOG_SKIP_LINE_NUM;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.LOG_SKIP_LINE_NUM_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.MSG;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.ONLINE_CREATE_RESOURCE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PAGE_NO;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PAGE_NO_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PAGE_SIZE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PAGE_SIZE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.POST_TASK_VERSION_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PRE_TASK_CODE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PRE_TASK_VERSION_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_DEFINITION;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_DEFINITION_CODE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_DEFINITION_NAME;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_INSTANCE_ID;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_INSTANCE_LIST;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_INSTANCE_NAME;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_INSTANCE_PRIORITY;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_INSTANCE_PRIORITY_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.QUERY_LIST_PAGING;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.QUERY_PROCESS_DEFINITION_BY_NAME;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.QUERY_PROJECT_LIST_PAGING;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.QUERY_RESOURCE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.QUERY_SCHEDULE_LIST_PAGING;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.QUERY_TASK_LIST_PAGING;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RELEASE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RELEASE_STATE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RELEASE_STATE_OFFLINE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_ID;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_ID_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_SEPARATOR;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_TYPE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_TYPE_FILE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_TYPE_FILE_CONTENT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RESOURCE_TYPE_FILE_SUFFIX_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SCHEDULE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SCHEDULE_ID;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SCHEDULE_OFFLINE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SCHEDULE_ONLINE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SEARCH_VAL;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.START_PROCESS_INSTANCE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.START_TIME;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SUCCESS_NODE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.SWITCH_RESULT_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TASK_DEFINITION_JSON;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TASK_INSTANCE_ID;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TASK_PRIORITY_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TASK_RELATION_JSON;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TASK_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TENANT_CODE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TIMEOUT_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TIMEOUT_FLAG_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TIMEOUT_NOTIFY_STRATEGY_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TIMEZONE_ID;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TIMEZONE_ID_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TOKEN;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.UPDATE_CONTENT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.VERSION_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WAIT_START_TIMEOUT_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WARNING_GROUP_ID;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WARNING_GROUP_ID_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WARNING_TYPE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WARNING_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WORKER_GROUP;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WORKER_GROUP_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.utils.HttpUtils.createParamMap;
+import static org.apache.seatunnel.server.common.Constants.BLANK_SPACE;
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.NO_MATCHED_PROJECT;
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.UNEXPECTED_RETURN_CODE;
+
+import org.apache.seatunnel.scheduler.dolphinscheduler.ExecuteTypeEnum;
+import org.apache.seatunnel.scheduler.dolphinscheduler.IDolphinschedulerService;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ConditionResult;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListProcessInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListTaskInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.LocalParam;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.LocationDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.OnlineCreateResourceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProcessInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProjectDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ResourceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.SchedulerDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.StartProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskDescriptionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskParamDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskRelationDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.UpdateProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.utils.HttpUtils;
+import org.apache.seatunnel.server.common.DateUtils;
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.server.common.SeatunnelErrorEnum;
+import org.apache.seatunnel.server.common.SeatunnelException;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceLogDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobDto;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.jsoup.Connection;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class DolphinschedulerServiceImpl implements IDolphinschedulerService, InitializingBean {
+
+ @Value("${ds.api.prefix}")
+ private String apiPrefix;
+ @Value("${ds.api.token}")
+ private String token;
+ @Value("${ds.tenant.default}")
+ private String defaultTenantName;
+ @Value("${ds.project.default}")
+ private String defaultProjectName;
+ @Value("${ds.script.dir}")
+ private String defaultScriptDir;
+ private long defaultProjectCode;
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ final ProjectDto projectDto = queryProjectCodeByName(defaultProjectName);
+ defaultProjectCode = projectDto.getCode();
+ }
+
+ @Override
+ public ProcessDefinitionDto createOrUpdateProcessDefinition(UpdateProcessDefinitionDto dto) {
+ // gen task code
+ final List<Long> taskCodes = genTaskCodes(defaultProjectCode, GEN_NUM_DEFAULT);
+
+ // build taskDefinitionJson and taskRelationJson.
+ final Long taskCode = taskCodes.get(0);
+ List<TaskDefinitionDto> taskDefinitionJson = Collections.singletonList(buildTaskDefinitionJson(taskCode, dto.getTaskDescriptionDto()));
+ List<TaskRelationDto> taskRelationJson = buildTaskRelationJson(taskCode, dto.getTaskDescriptionDto());
+ List<LocationDto> locations = buildLocation(taskCodes);
+
+ String url = apiPrefix.concat(String.format(CREATE_PROCESS_DEFINITION, defaultProjectCode));
+ Connection.Method method = Connection.Method.POST;
+ if (Objects.nonNull(dto.getProcessDefinitionCode())) {
+ method = Connection.Method.PUT;
+ url = url.concat(String.valueOf(dto.getProcessDefinitionCode()));
+ // offline process
+ updateProcessDefinitionState(dto.getProcessDefinitionCode(), dto.getName(), RELEASE_STATE_OFFLINE);
+ }
+
+ final Map<String, String> paramMap = createParamMap(LOCATIONS, locations,
+ TASK_DEFINITION_JSON, this.objectToString(taskDefinitionJson),
+ TASK_RELATION_JSON, this.objectToString(taskRelationJson),
+ TENANT_CODE, defaultTenantName,
+ PROCESS_DEFINITION_NAME, dto.getName());
+
+ final Map result = HttpUtils.builder()
+ .withUrl(url)
+ .withMethod(method)
+ .withData(paramMap)
+ .withRequestBody(this.objectToString(null))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+
+ checkResult(result, false);
+ final Map<String, Object> map = MapUtils.getMap(result, DATA);
+ return mapToPojo(map, ProcessDefinitionDto.class);
+ }
+
+ @Override
+ public PageData<ProcessDefinitionDto> listProcessDefinition(ListProcessDefinitionDto dto) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(QUERY_LIST_PAGING, defaultProjectCode)))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(SEARCH_VAL, dto.getName(), PAGE_NO, dto.getPageNo(), PAGE_SIZE, dto.getPageSize()))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ final Map map = MapUtils.getMap(result, DATA);
+ final int total = MapUtils.getIntValue(map, DATA_TOTAL);
+ final List<Map<String, Object>> processDefinitionList = (List<Map<String, Object>>) map.get(DATA_TOTAL_LIST);
+
+ if (CollectionUtils.isEmpty(processDefinitionList)) {
+ return new PageData<>(total, Collections.emptyList());
+ }
+ final List<ProcessDefinitionDto> data = processDefinitionList.stream().map(m -> this.mapToPojo(m, ProcessDefinitionDto.class)).collect(Collectors.toList());
+
+ return new PageData<>(total, data);
+ }
+
+ @Override
+ public ProcessDefinitionDto fetchProcessDefinitionByName(String processDefinitionName) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(QUERY_PROCESS_DEFINITION_BY_NAME, defaultProjectCode)))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(PROCESS_DEFINITION_NAME, processDefinitionName))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ final Map<String, Object> map = (Map<String, Object>) MapUtils.getMap(result, DATA).get(PROCESS_DEFINITION);
+ return this.mapToPojo(map, ProcessDefinitionDto.class);
+ }
+
+ @Override
+ public void startProcessDefinition(StartProcessDefinitionDto dto) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(START_PROCESS_INSTANCE, defaultProjectCode)))
+ .withMethod(Connection.Method.POST)
+ .withData(dto.toMap())
+ .withRequestBody(this.objectToString(null))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ @Override
+ public void updateProcessDefinitionState(long processDefinitionCode, String processDefinitionName, String state) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(RELEASE, defaultProjectCode, processDefinitionCode)))
+ .withMethod(Connection.Method.POST)
+ .withData(createParamMap(PROCESS_DEFINITION_NAME, processDefinitionName, RELEASE_STATE, state))
+ .withRequestBody(this.objectToString(null))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ @Override
+ public SchedulerDto createOrUpdateSchedule(JobDto dto) {
+ final Map<String, Object> map = Maps.newHashMap();
+ map.put(FAILURE_STRATEGY, FAILURE_STRATEGY_DEFAULT);
+ map.put(WARNING_TYPE, WARNING_TYPE_DEFAULT);
+ map.put(PROCESS_INSTANCE_PRIORITY, PROCESS_INSTANCE_PRIORITY_DEFAULT);
+ map.put(WARNING_GROUP_ID, WARNING_GROUP_ID_DEFAULT);
+ map.put(WORKER_GROUP, WORKER_GROUP_DEFAULT);
+ map.put(ENVIRONMENT_CODE, ENVIRONMENT_CODE_DEFAULT);
+ map.put(PROCESS_DEFINITION_CODE, dto.getJobId());
+
+ final Map<String, Object> schedule = Maps.newHashMap();
+ schedule.put(START_TIME, DateUtils.format(dto.getSchedulerConfigDto().getStartTime()));
+ schedule.put(END_TIME, DateUtils.format(dto.getSchedulerConfigDto().getEndTime()));
+ schedule.put(CRONTAB, dto.getSchedulerConfigDto().getTriggerExpression());
+ schedule.put(TIMEZONE_ID, TIMEZONE_ID_DEFAULT);
+
+ map.put(SCHEDULE, this.objectToString(schedule));
+
+ String url = String.format(CREATE_SCHEDULE, defaultProjectCode);
+
+ final List<SchedulerDto> schedulerDtos = listSchedule(dto.getJobId());
+ boolean flag = false;
+ if (!CollectionUtils.isEmpty(schedulerDtos)) {
+ url = url.concat(String.valueOf(schedulerDtos.get(0).getId()));
+ flag = true;
+ }
+
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(url))
+ .withData(translate(map))
+ .withMethod(flag ? Connection.Method.PUT : Connection.Method.POST)
+ .withRequestBody(this.objectToString(null))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ if (flag){
+ schedulerDtos.clear();
+ schedulerDtos.addAll(listSchedule(dto.getJobId()));
+ return schedulerDtos.get(0);
+ }
+
+ Map<String, Object> resultMap = MapUtils.getMap(result, DATA);
+ return this.mapToPojo(resultMap, SchedulerDto.class);
+ }
+
+ @Override
+ public List<SchedulerDto> listSchedule(long processDefinitionCode) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(QUERY_SCHEDULE_LIST_PAGING, defaultProjectCode)))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(PROCESS_DEFINITION_CODE, processDefinitionCode, PAGE_NO, PAGE_NO_DEFAULT, PAGE_SIZE, PAGE_SIZE_DEFAULT))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ final List<Map<String, Object>> scheduleList = (List<Map<String, Object>>) MapUtils.getMap(result, DATA).get(DATA_TOTAL_LIST);
+ if (CollectionUtils.isEmpty(scheduleList)) {
+ return Collections.emptyList();
+ }
+ return scheduleList.stream().map(m -> this.mapToPojo(m, SchedulerDto.class)).collect(Collectors.toList());
+ }
+
+ @Override
+ public void scheduleOnline(int scheduleId) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(SCHEDULE_ONLINE, defaultProjectCode, scheduleId)))
+ .withMethod(Connection.Method.POST)
+ .withData(createParamMap(SCHEDULE_ID, scheduleId))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ @Override
+ public void scheduleOffline(int scheduleId) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(SCHEDULE_OFFLINE, defaultProjectCode, scheduleId)))
+ .withMethod(Connection.Method.POST)
+ .withData(createParamMap(SCHEDULE_ID, scheduleId))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ @Override
+ public List<Long> genTaskCodes(long projectCode, int num) {
+ final String url = String.format(GEN_TASK_CODE_LIST, projectCode);
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(url))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(GEN_NUM, num))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ return (List<Long>) result.get(DATA);
+ }
+
+ @Override
+ public ResourceDto createOrUpdateScriptContent(String resourceName, String content) {
+ // check resource exists
+ final String fullName = defaultScriptDir.concat(RESOURCE_SEPARATOR.concat(resourceName));
+ final ResourceDto parentResourceDto = getResourceDto(defaultScriptDir, RESOURCE_TYPE_FILE);
+ if (Objects.isNull(parentResourceDto)) {
+ throw new SeatunnelException(SeatunnelErrorEnum.NO_MATCHED_SCRIPT_SAVE_DIR, defaultScriptDir);
+ }
+ final ResourceDto dto = getResourceDto(fullName.concat(DEFAULT_FILE_SUFFIX), RESOURCE_TYPE_FILE);
+ if (Objects.isNull(dto)) {
+ final OnlineCreateResourceDto createDto = OnlineCreateResourceDto.builder()
+ .type(RESOURCE_TYPE_FILE)
+ .pid(parentResourceDto.getId())
+ .fileName(resourceName)
+ .currentDir(defaultScriptDir)
+ .suffix(RESOURCE_TYPE_FILE_SUFFIX_DEFAULT)
+ .content(content)
+ .build();
+ onlineCreateResource(createDto);
+ return getResourceDto(fullName.concat(DEFAULT_FILE_SUFFIX), RESOURCE_TYPE_FILE);
+ } else {
+ updateContent(dto.getId(), content);
+ return dto;
+ }
+ }
+
+ @Override
+ public PageData<TaskInstanceDto> listTaskInstance(ListTaskInstanceDto dto) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(QUERY_TASK_LIST_PAGING, defaultProjectCode)))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(PROCESS_INSTANCE_NAME, dto.getName(), PAGE_NO, dto.getPageNo(), PAGE_SIZE, dto.getPageSize()))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+
+ checkResult(result, false);
+ final Map map = MapUtils.getMap(result, DATA);
+ final List<Map<String, Object>> taskInstanceList = (List<Map<String, Object>>) map.get(DATA_TOTAL_LIST);
+ final int total = MapUtils.getIntValue(map, DATA_TOTAL);
+ if (CollectionUtils.isEmpty(taskInstanceList)) {
+ return PageData.empty();
+ }
+
+ final List<TaskInstanceDto> data = taskInstanceList.stream().map(m -> this.mapToPojo(m, TaskInstanceDto.class)).collect(Collectors.toList());
+ return new PageData<>(total, data);
+ }
+
+ @Override
+ public void deleteProcessDefinition(long code) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(DELETE_PROCESS_DEFINITION, defaultProjectCode, code)))
+ .withMethod(Connection.Method.DELETE)
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ @Override
+ public PageData<ProcessInstanceDto> listProcessInstance(ListProcessInstanceDto dto) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(PROCESS_INSTANCE_LIST, defaultProjectCode)))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(SEARCH_VAL, dto.getName(), PAGE_NO, dto.getPageNo(), PAGE_SIZE, dto.getPageSize()))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+
+ final Map map = MapUtils.getMap(result, DATA);
+ final List<Map<String, Object>> processInstanceList = (List<Map<String, Object>>) map.get(DATA_TOTAL_LIST);
+ final int total = MapUtils.getIntValue(map, DATA_TOTAL);
+ if (CollectionUtils.isEmpty(processInstanceList)) {
+ return PageData.empty();
+ }
+
+ final List<ProcessInstanceDto> data = processInstanceList.stream().map(m -> this.mapToPojo(m, ProcessInstanceDto.class)).collect(Collectors.toList());
+ return new PageData<>(total, data);
+ }
+
+ @Override
+ public void killProcessInstance(long processInstanceId) {
+ execute(processInstanceId, ExecuteTypeEnum.STOP);
+ }
+
+ @Override
+ public InstanceLogDto queryInstanceLog(long instanceId) {
+
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(LOG_DETAIL))
+ .withData(createParamMap(TASK_INSTANCE_ID, instanceId, LOG_SKIP_LINE_NUM, LOG_SKIP_LINE_NUM_DEFAULT, LOG_LIMIT_NUM, LOG_LIMIT_NUM_DEFAULT))
+ .withMethod(Connection.Method.GET)
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ final Map map = MapUtils.getMap(result, DATA);
+ final String logContent = MapUtils.getString(map, LOG_MESSAGE);
+
+ return InstanceLogDto.builder()
+ .logContent(logContent)
+ .build();
+ }
+
+ private ProjectDto queryProjectCodeByName(String projectName) throws IOException {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(QUERY_PROJECT_LIST_PAGING))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(SEARCH_VAL, projectName, PAGE_NO, PAGE_NO_DEFAULT, PAGE_SIZE, PAGE_SIZE_DEFAULT))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+
+ final List<Map<String, Object>> projectList = (List<Map<String, Object>>) MapUtils.getMap(result, DATA).get(DATA_TOTAL_LIST);
+ final ProjectDto projectDto = projectList.stream().map(m -> this.mapToPojo(m, ProjectDto.class)).filter(p -> p.getName().equalsIgnoreCase(projectName)).findAny().orElse(null);
+ if (Objects.isNull(projectDto)) {
+ throw new SeatunnelException(NO_MATCHED_PROJECT, projectName);
+ }
+ return projectDto;
+ }
+
+ private void execute(long processInstanceId, ExecuteTypeEnum executeType) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(EXECUTE, defaultProjectCode)))
+ .withMethod(Connection.Method.POST)
+ .withRequestBody(this.objectToString(null))
+ .withData(createParamMap(PROCESS_INSTANCE_ID, processInstanceId, EXECUTE_TYPE, executeType.name()))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ private TaskDefinitionDto buildTaskDefinitionJson(Long taskCode, TaskDescriptionDto taskDescriptionDto) {
+ final ResourceDto resourceDto = createOrUpdateScriptContent(taskDescriptionDto.getName(), taskDescriptionDto.getContent());
+ final TaskDefinitionDto taskDefinitionDto = new TaskDefinitionDto();
+ taskDefinitionDto.setCode(taskCode);
+ taskDefinitionDto.setName(taskDescriptionDto.getName());
+ taskDefinitionDto.setDescription(DESCRIPTION_DEFAULT);
+ taskDefinitionDto.setTaskType(TASK_TYPE_DEFAULT);
+
+ final TaskParamDto taskParamDto = new TaskParamDto();
+
+ taskParamDto.setResourceList(Collections.singletonList(resourceDto));
+
+ final List<LocalParam> localParams = getLocalParams(taskDescriptionDto);
+ taskParamDto.setLocalParams(localParams);
+ taskParamDto.setRawScript(taskDescriptionDto.getExecuteScript());
+ taskParamDto.setDependence(DEPENDENCE_DEFAULT);
+
+ final ConditionResult conditionResult = new ConditionResult();
+ conditionResult.setSuccessNode(SUCCESS_NODE_DEFAULT);
+ conditionResult.setFailedNode(FAILED_NODE_DEFAULT);
+
+ taskParamDto.setConditionResult(conditionResult);
+ taskParamDto.setWaitStartTimeout(WAIT_START_TIMEOUT_DEFAULT);
+ taskParamDto.setSwitchResult(SWITCH_RESULT_DEFAULT);
+
+ taskDefinitionDto.setTaskParams(taskParamDto);
+ taskDefinitionDto.setFlag(FLAG_DEFAULT);
+ taskDefinitionDto.setTaskPriority(TASK_PRIORITY_DEFAULT);
+ taskDefinitionDto.setWorkerGroup(WORKER_GROUP_DEFAULT);
+ taskDefinitionDto.setFailRetryTimes(taskDescriptionDto.getRetryTimes());
+ taskDefinitionDto.setFailRetryInterval(taskDescriptionDto.getRetryInterval());
+ taskDefinitionDto.setTimeoutFlag(TIMEOUT_FLAG_DEFAULT);
+ taskDefinitionDto.setTimeoutNotifyStrategy(TIMEOUT_NOTIFY_STRATEGY_DEFAULT);
+ taskDefinitionDto.setTimeout(TIMEOUT_DEFAULT);
+ taskDefinitionDto.setDelayTime(DELAY_TIME_DEFAULT);
+ taskDefinitionDto.setEnvironmentCode(ENVIRONMENT_CODE_DEFAULT);
+ taskDefinitionDto.setVersion(VERSION_DEFAULT);
+ return taskDefinitionDto;
+ }
+
+ private List<LocalParam> getLocalParams(TaskDescriptionDto taskDescriptionDto) {
+ final Map<String, Object> params = taskDescriptionDto.getParams();
+ if (CollectionUtils.isEmpty(params)) {
+ return Collections.emptyList();
+ }
+ final List<LocalParam> localParams = Lists.newArrayListWithCapacity(params.size());
+ params.forEach((k, v) -> {
+ final LocalParam localParam = new LocalParam();
+ localParam.setProp(k);
+ localParam.setDirect(LOCAL_PARAMS_DIRECT_DEFAULT);
+ localParam.setType(LOCAL_PARAMS_TYPE_DEFAULT);
+ localParam.setValue(v);
+ localParams.add(localParam);
+ });
+ return localParams;
+ }
+
+ private List<TaskRelationDto> buildTaskRelationJson(Long taskCode, TaskDescriptionDto taskDescriptionDto) {
+
+ final TaskRelationDto taskRelationDto = new TaskRelationDto();
+ taskRelationDto.setName(BLANK_SPACE);
+ taskRelationDto.setPreTaskCode(PRE_TASK_CODE_DEFAULT);
+ taskRelationDto.setPreTaskVersion(PRE_TASK_VERSION_DEFAULT);
+ taskRelationDto.setPostTaskCode(taskCode);
+ taskRelationDto.setPostTaskVersion(POST_TASK_VERSION_DEFAULT);
+ taskRelationDto.setConditionType(CONDITION_TYPE_DEFAULT);
+ taskRelationDto.setConditionParams(null);
+ return Collections.singletonList(taskRelationDto);
+ }
+
+ private List<LocationDto> buildLocation(List<Long> taskCode) {
+ final List<LocationDto> locations = Lists.newArrayListWithCapacity(taskCode.size());
+ for (int i = 0; i < taskCode.size(); i++) {
+ final LocationDto locationDto = new LocationDto();
+ locationDto.setTaskCode(taskCode.get(i));
+ locationDto.setX(LOCATIONS_X_DEFAULT * i);
+ locationDto.setY(LOCATIONS_Y_DEFAULT * i);
+ locations.add(locationDto);
+ }
+ return locations;
+ }
+
+ private void updateContent(int id, String content) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(UPDATE_CONTENT, id)))
+ .withMethod(Connection.Method.PUT)
+ .withData(createParamMap(RESOURCE_ID, id, RESOURCE_TYPE_FILE_CONTENT, content))
+ .withRequestBody(this.objectToString(null))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ private void onlineCreateResource(OnlineCreateResourceDto createDto) {
+ final Map<String, Object> map = createDto.toMap();
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(ONLINE_CREATE_RESOURCE))
+ .withMethod(Connection.Method.POST)
+ .withData(translate(map))
+ .withRequestBody(this.objectToString(null))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ checkResult(result, false);
+ }
+
+ private ResourceDto getResourceDto(String fullName, String fileType) {
+ final Map result = HttpUtils.builder()
+ .withUrl(apiPrefix.concat(String.format(QUERY_RESOURCE, RESOURCE_ID_DEFAULT)))
+ .withMethod(Connection.Method.GET)
+ .withData(createParamMap(FULL_NAME, fullName, RESOURCE_TYPE, RESOURCE_TYPE_FILE))
+ .withToken(TOKEN, token)
+ .execute(Map.class);
+ final int code = checkResult(result, true);
+ if (code != CODE_SUCCESS) {
+ return null;
+ }
+ final Map<String, Object> map = MapUtils.getMap(result, DATA);
+ return this.mapToPojo(map, ResourceDto.class);
+ }
+
+ private int checkResult(Map result, boolean ignore) {
+ final int intValue = MapUtils.getIntValue(result, CODE, -1);
+ if (!ignore && CODE_SUCCESS != intValue) {
+ final String msg = MapUtils.getString(result, MSG);
+ throw new SeatunnelException(UNEXPECTED_RETURN_CODE, intValue, msg);
+ }
+ return intValue;
+ }
+
+ private Map<String, String> translate(Map<String, Object> origin) {
+ final HashMap<String, String> map = Maps.newHashMapWithExpectedSize(origin.size());
+ origin.forEach((k, v) -> map.put(k, String.valueOf(v)));
+ return map;
+ }
+
+ private <T> T mapToPojo(Map map, Class<T> pojo) {
+ try {
+ return MAPPER.readValue(MAPPER.writeValueAsString(map), pojo);
+ } catch (JsonProcessingException e) {
+ log.error("Map translate to Pojo failed.", e);
+ throw new SeatunnelException(SeatunnelErrorEnum.JSON_TRANSFORM_FAILED);
+ }
+ }
+
+ private String objectToString(Object o) {
+ try {
+ return MAPPER.writeValueAsString(o);
+ } catch (JsonProcessingException e) {
+ log.error("Map translate to Pojo failed.", e);
+ throw new SeatunnelException(SeatunnelErrorEnum.JSON_TRANSFORM_FAILED);
+ }
+ }
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/InstanceServiceImpl.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/InstanceServiceImpl.java
new file mode 100644
index 0000000..42a27ef
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/InstanceServiceImpl.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.impl;
+
+import org.apache.seatunnel.scheduler.dolphinscheduler.IDolphinschedulerService;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListProcessInstanceDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProcessInstanceDto;
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.spi.scheduler.IInstanceService;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceListDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceLogDto;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class InstanceServiceImpl implements IInstanceService {
+
+ @Resource
+ private IDolphinschedulerService iDolphinschedulerService;
+
+ @Override
+ public PageData<InstanceDto> list(InstanceListDto dto) {
+
+ final ListProcessInstanceDto listDto = new ListProcessInstanceDto();
+ listDto.setName(dto.getName());
+ listDto.setPageNo(dto.getPageNo());
+ listDto.setPageSize(dto.getPageSize());
+
+ // use list process instance instead of list task instance.
+ final PageData<ProcessInstanceDto> instancePageData = iDolphinschedulerService.listProcessInstance(listDto);
+
+ final List<InstanceDto> data = instancePageData.getData().stream().map(t -> InstanceDto.builder()
+ .instanceId(t.getId())
+ .jobId(t.getProcessDefinitionCode())
+ .instanceName(t.getName())
+ .status(t.getState())
+ .startTime(t.getStartTime())
+ .endTime(t.getEndTime())
+ .submitTime(t.getScheduleTime())
+ .executionDuration(t.getDuration())
+ .retryTimes(t.getRunTimes())
+ .build()).collect(Collectors.toList());
+ return new PageData<>(instancePageData.getTotalCount(), data);
+ }
+
+ @Override
+ public InstanceLogDto queryInstanceLog(long instanceId) {
+ return iDolphinschedulerService.queryInstanceLog(instanceId);
+ }
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/JobServiceImpl.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/JobServiceImpl.java
new file mode 100644
index 0000000..5cdab9b
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/impl/JobServiceImpl.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.impl;
+
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DEPENDENT_MODE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.DRY_RUN;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.EXEC_TYPE_COMPLEMENT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.EXEC_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.FAILURE_STRATEGY_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PAGE_NO_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PAGE_SIZE_MIN;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.PROCESS_INSTANCE_PRIORITY_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RELEASE_STATE_OFFLINE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RELEASE_STATE_ONLINE;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RUN_MODE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.RUN_MODE_PARALLEL;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.TASK_DEPEND_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WARNING_GROUP_ID_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WARNING_TYPE_DEFAULT;
+import static org.apache.seatunnel.scheduler.dolphinscheduler.constants.DolphinschedulerConstants.WORKER_GROUP_DEFAULT;
+import static org.apache.seatunnel.server.common.Constants.COMMA;
+import static org.apache.seatunnel.server.common.DateUtils.DEFAULT_DATETIME_FORMAT;
+
+import org.apache.seatunnel.scheduler.dolphinscheduler.IDolphinschedulerService;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ListProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.ProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.SchedulerDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.StartProcessDefinitionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.TaskDescriptionDto;
+import org.apache.seatunnel.scheduler.dolphinscheduler.dto.UpdateProcessDefinitionDto;
+import org.apache.seatunnel.server.common.DateUtils;
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.server.common.SeatunnelErrorEnum;
+import org.apache.seatunnel.server.common.SeatunnelException;
+import org.apache.seatunnel.spi.scheduler.IInstanceService;
+import org.apache.seatunnel.spi.scheduler.IJobService;
+import org.apache.seatunnel.spi.scheduler.dto.ComplementDataDto;
+import org.apache.seatunnel.spi.scheduler.dto.ExecuteDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceListDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobListDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobSimpleInfoDto;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class JobServiceImpl implements IJobService {
+ @Resource
+ private IDolphinschedulerService iDolphinschedulerService;
+
+ @Resource
+ private IInstanceService iInstanceService;
+
+ @Value("${maxWaitingTimes:10}")
+ private long maxWaitingTimes;
+ @Value("${waitingSleepTime:100}")
+ private long waitingSleepTime;
+
+ @Override
+ public long submitJob(JobDto dto) {
+ // one process == one seatunnel script == one job
+
+ final ProcessDefinitionDto processDefinition = getProcessDefinitionDto(dto);
+
+ dto.setJobId(processDefinition.getCode());
+ iDolphinschedulerService.updateProcessDefinitionState(processDefinition.getCode(), processDefinition.getName(), RELEASE_STATE_ONLINE);
+ final SchedulerDto schedulerDto = iDolphinschedulerService.createOrUpdateSchedule(dto);
+ iDolphinschedulerService.scheduleOnline(schedulerDto.getId());
+
+ return processDefinition.getCode();
+ }
+
+ @Override
+ public void offlineJob(JobDto dto) {
+ iDolphinschedulerService.updateProcessDefinitionState(dto.getJobId(), dto.getJobName(), RELEASE_STATE_OFFLINE);
+ }
+
+ @Override
+ public PageData<JobSimpleInfoDto> list(JobListDto dto) {
+ final ListProcessDefinitionDto listDto = new ListProcessDefinitionDto();
+ listDto.setName(dto.getName());
+ listDto.setPageNo(dto.getPageNo());
+ listDto.setPageSize(dto.getPageSize());
+
+ final PageData<ProcessDefinitionDto> processPageData = iDolphinschedulerService.listProcessDefinition(listDto);
+ final List<JobSimpleInfoDto> data = processPageData.getData().stream().map(p -> JobSimpleInfoDto.builder()
+ .jobId(p.getCode())
+ .jobStatus(p.getReleaseState())
+ .createTime(p.getCreateTime())
+ .updateTime(p.getUpdateTime())
+ .creatorName(p.getUsername())
+ .menderName(p.getUsername())
+ .build())
+ .collect(Collectors.toList());
+ return new PageData<>(processPageData.getTotalCount(), data);
+ }
+
+ @Override
+ @SuppressWarnings("magicnumber")
+ public InstanceDto execute(ExecuteDto dto) {
+ ProcessDefinitionDto processDefinition = null;
+ final JobDto jobDto = dto.getJobDto();
+ if (Objects.isNull(jobDto.getJobId())) {
+ // need to create a temporary process definition and execute it.
+ processDefinition = getProcessDefinitionDto(jobDto);
+ jobDto.setJobId(processDefinition.getCode());
+ iDolphinschedulerService.updateProcessDefinitionState(processDefinition.getCode(), processDefinition.getName(), RELEASE_STATE_ONLINE);
+ }
+
+ final ComplementDataDto complementDataDto = dto.getComplementDataDto();
+ String execType;
+ String runMode = RUN_MODE_DEFAULT;
+
+ Date startTime = new Date();
+ Date endTime = new Date();
+ int parallelismNum = 1;
+ if (Objects.isNull(complementDataDto)) {
+ execType = EXEC_TYPE_DEFAULT;
+ } else {
+ execType = EXEC_TYPE_COMPLEMENT;
+ if (Objects.nonNull(complementDataDto.getParallelismNum())) {
+ runMode = RUN_MODE_PARALLEL;
+ }
+ startTime = complementDataDto.getStartTime();
+ endTime = complementDataDto.getEndTime();
+ parallelismNum = complementDataDto.getParallelismNum();
+ }
+
+ final StartProcessDefinitionDto startProcessDefinitionDto = StartProcessDefinitionDto.builder()
+ .processDefinitionCode(jobDto.getJobId())
+ .failureStrategy(FAILURE_STRATEGY_DEFAULT)
+ .warningType(WARNING_TYPE_DEFAULT)
+ .warningGroupId(WARNING_GROUP_ID_DEFAULT)
+ .taskDependType(TASK_DEPEND_TYPE_DEFAULT)
+ .runMode(runMode)
+ .processInstancePriority(PROCESS_INSTANCE_PRIORITY_DEFAULT)
+ .workerGroup(WORKER_GROUP_DEFAULT)
+ .dryRun(DRY_RUN)
+ .scheduleTime(DateUtils.format(startTime, DEFAULT_DATETIME_FORMAT).concat(COMMA).concat(DateUtils.format(endTime, DEFAULT_DATETIME_FORMAT)))
+ .execType(execType)
+ .dependentMode(DEPENDENT_MODE_DEFAULT)
+ .expectedParallelismNumber(parallelismNum)
+ .build();
+ iDolphinschedulerService.startProcessDefinition(startProcessDefinitionDto);
+
+ if (Objects.nonNull(processDefinition)){
+
+ final long code = processDefinition.getCode();
+ final String name = processDefinition.getName();
+
+ InstanceDto instanceDto = null;
+ // waiting dolphinscheduler generate instance.
+ for (int i = 0; i < maxWaitingTimes; i++) {
+ // get instance by process definition name
+ final InstanceListDto instanceListDto = InstanceListDto.builder()
+ .pageNo(PAGE_NO_DEFAULT)
+ .pageSize(PAGE_SIZE_MIN)
+ .name(processDefinition.getName())
+ .build();
+ final PageData<InstanceDto> instancePageData = iInstanceService.list(instanceListDto);
+ if (!CollectionUtils.isEmpty(instancePageData.getData())) {
+ instanceDto = instancePageData.getData().get(0);
+ break;
+ }
+ try {
+ Thread.sleep(waitingSleepTime);
+ } catch (InterruptedException e) {
+ log.error("waiting for getting instance failed", e);
+ throw new SeatunnelException(SeatunnelErrorEnum.GET_INSTANCE_FAILED);
+ }
+ }
+
+ CompletableFuture.runAsync(() -> {
+ // clear temporary process definition
+ iDolphinschedulerService.updateProcessDefinitionState(code, name, RELEASE_STATE_OFFLINE);
+ }).whenComplete((_return, e) -> {
+ if (Objects.nonNull(e)) {
+ log.error("clear temporary process definition failed, process definition code is [{}], name is [{}]",
+ code, name, e);
+ }
+ });
+ return instanceDto;
+
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void kill(Long instanceId) {
+ iDolphinschedulerService.killProcessInstance(instanceId);
+ }
+
+ private ProcessDefinitionDto getProcessDefinitionDto(JobDto dto) {
+ final TaskDescriptionDto taskDescriptionDto = TaskDescriptionDto.builder()
+ .name(dto.getJobName())
+ .executeScript(dto.getExecutorScript())
+ .content(dto.getJobContent())
+ .params(dto.getParams())
+ .retryInterval(dto.getSchedulerConfigDto().getRetryInterval())
+ .retryTimes(dto.getSchedulerConfigDto().getRetryTimes())
+ .build();
+
+ final UpdateProcessDefinitionDto processDto = UpdateProcessDefinitionDto.builder()
+ .name(dto.getJobName())
+ .startTime(dto.getSchedulerConfigDto().getStartTime())
+ .endTime(dto.getSchedulerConfigDto().getEndTime())
+ .cronExpression(dto.getSchedulerConfigDto().getTriggerExpression())
+ .taskDescriptionDto(taskDescriptionDto)
+ .processDefinitionCode(dto.getJobId())
+ .build();
+
+ return iDolphinschedulerService.createOrUpdateProcessDefinition(processDto);
+ }
+}
diff --git a/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/utils/HttpUtils.java b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/utils/HttpUtils.java
new file mode 100644
index 0000000..67512f7
--- /dev/null
+++ b/seatunnel-server/seatunnel-scheduler/seatunnel-scheduler-dolphinscheduler/src/main/java/org/apache/seatunnel/scheduler/dolphinscheduler/utils/HttpUtils.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.scheduler.dolphinscheduler.utils;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.HTTP_REQUEST_FAILED;
+import static com.google.common.base.Preconditions.checkState;
+
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Connection;
+import org.jsoup.Jsoup;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+@Slf4j
+public class HttpUtils {
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ @SuppressWarnings("MagicNumber")
+ public static Map<String, String> createParamMap(Object... elements) {
+ if (elements == null || elements.length == 0 || elements.length % 2 == 1) {
+ throw new IllegalArgumentException("params length must be even!");
+ }
+ Map<String, String> paramMap = Maps.newHashMapWithExpectedSize(elements.length / 2);
+ for (int i = 0; i < elements.length / 2; i++) {
+ Object key = elements[2 * i];
+ Object value = elements[2 * i + 1];
+ if (key == null) {
+ continue;
+ }
+
+ paramMap.put(key.toString(), value == null ? "" : value.toString());
+ }
+
+ return paramMap;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @SuppressWarnings("MagicNumber")
+ public static class Builder {
+ private Connection connection;
+ private String url;
+ private Optional<Map<String, String>> data = Optional.empty();
+ private Optional<String> requestBody = Optional.empty();
+ private Optional<Integer> maxBodySize = Optional.of(2147483647);
+ private Optional<String> postDataCharset = Optional.of("UTF-8");
+ private Optional<Boolean> ignoreContentType = Optional.of(true);
+ private Optional<Integer> timeout = Optional.of(30000);
+ private Optional<Map<String, String>> headers;
+ private Optional<Connection.Method> method = Optional.empty();
+
+ private Optional<Type> type;
+
+ public Builder() {
+ HashMap<String, String> defaultMap = Maps.newHashMap();
+ defaultMap.put("Content-Type", "application/json; charset=UTF-8");
+ headers = Optional.of(defaultMap);
+ }
+
+ public Builder withUrl(String url) {
+ this.url = url;
+ return this;
+ }
+
+ public Builder withData(Map<String, String> data) {
+ this.data = Optional.ofNullable(data);
+ return this;
+ }
+
+ public Builder withRequestBody(String requestBody) {
+ this.requestBody = Optional.ofNullable(requestBody);
+ return this;
+ }
+
+ public Builder withMaxBodySize(int maxBodySize) {
+ this.maxBodySize = Optional.of(maxBodySize);
+ return this;
+ }
+
+ public Builder withPostDataCharset(String postDataCharset) {
+ this.postDataCharset = Optional.ofNullable(postDataCharset);
+ return this;
+ }
+
+ public Builder withIgnoreContentType(boolean ignoreContentType) {
+ this.ignoreContentType = Optional.of(ignoreContentType);
+ return this;
+ }
+
+ public Builder withTimeout(int timeout) {
+ this.timeout = Optional.of(timeout);
+ return this;
+ }
+
+ public Builder withHeaders(Map<String, String> headers) {
+ this.headers = Optional.ofNullable(headers);
+ return this;
+ }
+
+ public Builder withMethod(Connection.Method method) {
+ this.method = Optional.ofNullable(method);
+ return this;
+ }
+
+ public Builder withToken(String tokenKey, String tokenValue) {
+ this.headers.ifPresent(map -> map.put(tokenKey, tokenValue));
+ return this;
+ }
+
+ private Connection build() {
+ checkState(!Strings.isNullOrEmpty(url), "request url is empty");
+ connection = Jsoup.connect(url);
+ data.ifPresent(connection::data);
+ requestBody.ifPresent(connection::requestBody);
+ maxBodySize.ifPresent(connection::maxBodySize);
+ postDataCharset.ifPresent(connection::postDataCharset);
+ ignoreContentType.ifPresent(connection::ignoreContentType);
+ timeout.ifPresent(connection::timeout);
+ headers.ifPresent(connection::headers);
+ method.ifPresent(connection::method);
+
+ return connection;
+ }
+
+ public <T> T execute(Class<T> type) {
+ this.build();
+ try {
+ Connection.Response response = connection.execute();
+ return MAPPER.readValue(response.body(), type);
+ } catch (IOException e) {
+ log.error("Request url {} failed", this.url, e);
+ throw new SeatunnelException(HTTP_REQUEST_FAILED, this.url);
+ }
+ }
+
+ public void execute() throws IOException {
+ this.build();
+ try {
+ connection.execute();
+ } catch (IOException e) {
+ log.error("Request url {} failed", this.url, e);
+ throw new SeatunnelException(HTTP_REQUEST_FAILED, this.url);
+ }
+ }
+ }
+}
diff --git a/seatunnel-server/seatunnel-server-common/pom.xml b/seatunnel-server/seatunnel-server-common/pom.xml
new file mode 100644
index 0000000..e170fdf
--- /dev/null
+++ b/seatunnel-server/seatunnel-server-common/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>seatunnel-server</artifactId>
+ <groupId>org.apache.seatunnel</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>seatunnel-server-common</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/Constants.java b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/Constants.java
new file mode 100644
index 0000000..f55aa89
--- /dev/null
+++ b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/Constants.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.server.common;
+
+public class Constants {
+ public static final String BLANK_SPACE = " ";
+ public static final String COMMA = ",";
+ public static final String UNDERLINE = "_";
+ public static final String TOKEN = "token";
+ public static final String USER_ID = "id";
+
+ public static final String OPTIONS = "OPTIONS";
+}
diff --git a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/DateUtils.java b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/DateUtils.java
new file mode 100644
index 0000000..69a7f6d
--- /dev/null
+++ b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/DateUtils.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.server.common;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+@Slf4j
+public class DateUtils {
+ public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+ public static final String DEFAULT_DATETIME_FORMAT_WITH_TIMEZONE = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZ";
+
+ /**
+ * parse Date to String Date, use default datetime format 'yyyy-MM-dd HH:mm:ss'
+ * @param date which need been format to String date
+ * @return String date
+ */
+ public static String format(Date date) {
+ return format(date2LocalDateTime(date), DEFAULT_DATETIME_FORMAT);
+ }
+
+ public static String format(Date date, String format) {
+ return format(date2LocalDateTime(date), format);
+ }
+
+ public static String format(LocalDateTime localDateTime, String format) {
+ return localDateTime.format(DateTimeFormatter.ofPattern(format));
+ }
+
+ private static LocalDateTime date2LocalDateTime(Date date) {
+ return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
+ }
+
+ /**
+ * parse String date to Date, use default datetime format 'yyyy-MM-dd HH:mm:ss'
+ * @param date which need been parse to Date
+ * @return Date
+ */
+ public static Date parse(String date) {
+ LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT));
+ return localDateTime2Date(localDateTime);
+ }
+
+ public static Date parse(String date, String format) {
+ LocalDateTime localDateTime = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(format));
+ return localDateTime2Date(localDateTime);
+ }
+
+ private static Date localDateTime2Date(LocalDateTime localDateTime) {
+ Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
+ return Date.from(instant);
+ }
+}
diff --git a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/PageData.java b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/PageData.java
new file mode 100644
index 0000000..85cc070
--- /dev/null
+++ b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/PageData.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.server.common;
+
+import lombok.Data;
+
+import java.util.Collections;
+import java.util.List;
+
+@Data
+public class PageData<T> {
+ private int totalCount;
+ private List<T> data;
+
+ public PageData(int totalCount, List<T> data) {
+ this.totalCount = totalCount;
+ this.data = data;
+ }
+
+ public static <T> PageData<T> empty() {
+ return new PageData<>(0, Collections.emptyList());
+ }
+
+ public List<T> getData() {
+ if (data == null || data.size() == 0) {
+ return Collections.emptyList();
+ }
+ return data;
+ }
+}
diff --git a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java
new file mode 100644
index 0000000..9e9f494
--- /dev/null
+++ b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelErrorEnum.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.server.common;
+
+public enum SeatunnelErrorEnum {
+
+ SCRIPT_ALREADY_EXIST(10001, "script already exist", "You already have a script with the same name : '%s'"),
+ NO_SUCH_SCRIPT(10002, "no such script", "No such script. Maybe deleted by others."),
+ USER_ALREADY_EXISTS(10003, "user already exist", "The same username [%s] is exist."),
+ NO_SUCH_USER(10004, "no such user", "No such user. Maybe deleted by others."),
+ SCHEDULER_CONFIG_NOT_EXIST(10005, "scheduler config not exist", "This script's scheduler config not exist, please check your config."),
+ JSON_TRANSFORM_FAILED(10006, "json transform failed", "Json transform failed, it may be a bug."),
+
+ USERNAME_PASSWORD_NO_MATCHED(10007, "username and password no matched", "The user name and password do not match, please check your input"),
+
+ TOKEN_ILLEGAL(10008, "token illegal", "The token is expired or invalid, please login again."),
+
+ /**
+ * request dolphinscheduler failed
+ */
+ UNEXPECTED_RETURN_CODE(20000, "Unexpected return code", "Unexpected return code : [%s], error msg is [%s]"),
+ QUERY_PROJECT_CODE_FAILED(20001, "query project code failed", "Request ds for querying project code failed"),
+ NO_MATCHED_PROJECT(20002, "no matched project", "No matched project [%s], please check your configuration"),
+ NO_MATCHED_SCRIPT_SAVE_DIR(20003, "no matched script save dir", "No matched script save dir [%s], please check your configuration"),
+ GET_INSTANCE_FAILED(20004, "get instance failed", "Get instance failed"),
+
+ NO_SUCH_ELEMENT(99995, "no such element", "No such element."),
+ UNSUPPORTED_OPERATION(99996, "unsupported operation", "This operation [%s] is not supported now."),
+ HTTP_REQUEST_FAILED(99997, "http request failed", "Http request failed, url is %s"),
+ ILLEGAL_STATE(99998, "illegal state", "%s"),
+ UNKNOWN(99999, "unknown exception", "Unknown exception")
+ ;
+
+ private final int code;
+ private final String msg;
+ private final String template;
+
+ SeatunnelErrorEnum(int code, String msg, String template) {
+ this.code = code;
+ this.msg = msg;
+ this.template = template;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public String getTemplate() {
+ return template;
+ }
+}
diff --git a/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelException.java b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelException.java
new file mode 100644
index 0000000..49d5a8c
--- /dev/null
+++ b/seatunnel-server/seatunnel-server-common/src/main/java/org/apache/seatunnel/server/common/SeatunnelException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.server.common;
+
+public class SeatunnelException extends RuntimeException{
+ private SeatunnelErrorEnum errorEnum;
+
+ public SeatunnelException(SeatunnelErrorEnum e) {
+ super(e.getMsg());
+ this.errorEnum = e;
+ }
+
+ public SeatunnelException(SeatunnelErrorEnum e, Object... msg) {
+ super(String.format(e.getTemplate(), msg));
+ this.errorEnum = e;
+ }
+
+ public static SeatunnelException newInstance(SeatunnelErrorEnum e, Object... msg) {
+ return new SeatunnelException(e, msg);
+
+ }
+
+ public static SeatunnelException newInstance(SeatunnelErrorEnum e) {
+ return new SeatunnelException(e);
+
+ }
+
+ public SeatunnelErrorEnum getErrorEnum() {
+ return errorEnum;
+ }
+}
diff --git a/seatunnel-server/seatunnel-spi/pom.xml b/seatunnel-server/seatunnel-spi/pom.xml
new file mode 100644
index 0000000..318c16c
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>seatunnel-server</artifactId>
+ <groupId>org.apache.seatunnel</groupId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>seatunnel-spi</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.seatunnel</groupId>
+ <artifactId>seatunnel-server-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/IInstanceService.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/IInstanceService.java
new file mode 100644
index 0000000..dad0ee4
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/IInstanceService.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler;
+
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceListDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceLogDto;
+
+public interface IInstanceService {
+ PageData<InstanceDto> list(InstanceListDto dto);
+
+ InstanceLogDto queryInstanceLog(long instanceId);
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/IJobService.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/IJobService.java
new file mode 100644
index 0000000..7a62912
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/IJobService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler;
+
+import org.apache.seatunnel.server.common.PageData;
+import org.apache.seatunnel.spi.scheduler.dto.ExecuteDto;
+import org.apache.seatunnel.spi.scheduler.dto.InstanceDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobListDto;
+import org.apache.seatunnel.spi.scheduler.dto.JobSimpleInfoDto;
+
+public interface IJobService {
+
+ long submitJob(JobDto dto);
+
+ void offlineJob(JobDto dto);
+
+ PageData<JobSimpleInfoDto> list(JobListDto dto);
+
+ InstanceDto execute(ExecuteDto dto);
+
+ void kill(Long instanceId);
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/constants/SchedulerConstant.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/constants/SchedulerConstant.java
new file mode 100644
index 0000000..1d8d030
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/constants/SchedulerConstant.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.constants;
+
+public class SchedulerConstant {
+ public static final int RETRY_INTERVAL_DEFAULT = 0;
+ public static final int RETRY_TIMES_DEFAULT = 0;
+ public static final String NEVER_TRIGGER_EXPRESSION = "* * * ? * * 1970";
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/ComplementDataDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/ComplementDataDto.java
new file mode 100644
index 0000000..f1f10dc
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/ComplementDataDto.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@Builder
+public class ComplementDataDto {
+ private Date startTime;
+ private Date endTime;
+ private Integer parallelismNum;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/ExecuteDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/ExecuteDto.java
new file mode 100644
index 0000000..ae547c3
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/ExecuteDto.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import org.apache.seatunnel.spi.scheduler.enums.ExecuteTypeEnum;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class ExecuteDto {
+ private JobDto jobDto;
+ private ExecuteTypeEnum executeTypeEnum;
+ private ComplementDataDto complementDataDto;
+
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceDto.java
new file mode 100644
index 0000000..2b71dcf
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceDto.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@Builder
+public class InstanceDto {
+ private long instanceId;
+ private long jobId;
+ private String instanceName;
+ private Date submitTime;
+ private Date startTime;
+ private Date endTime;
+ private String status;
+ private String executionDuration;
+ private long retryTimes;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceListDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceListDto.java
new file mode 100644
index 0000000..0b05302
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceListDto.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class InstanceListDto {
+ private String name;
+ private int pageNo;
+ private int pageSize;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceLogDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceLogDto.java
new file mode 100644
index 0000000..9a16b11
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/InstanceLogDto.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Builder
+@Data
+public class InstanceLogDto {
+ private String logContent;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobDto.java
new file mode 100644
index 0000000..3f30194
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobDto.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+@Builder
+public class JobDto {
+ private Long jobId;
+ private String jobName;
+ private String executorScript;
+ private String jobContent;
+ private Integer operatorId;
+ private Map<String, Object> params;
+ private SchedulerConfigDto schedulerConfigDto;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobListDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobListDto.java
new file mode 100644
index 0000000..5e5b1fc
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobListDto.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class JobListDto {
+ private String name;
+ private Integer pageNo;
+ private Integer pageSize;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobSimpleInfoDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobSimpleInfoDto.java
new file mode 100644
index 0000000..28e88e9
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/JobSimpleInfoDto.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@Builder
+@Data
+public class JobSimpleInfoDto {
+ private long jobId;
+ private String jobStatus;
+ private String creatorName;
+ private String menderName;
+ private Date createTime;
+ private Date updateTime;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/SchedulerConfigDto.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/SchedulerConfigDto.java
new file mode 100644
index 0000000..aa71ac6
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/dto/SchedulerConfigDto.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@Builder
+public class SchedulerConfigDto {
+ private int retryTimes;
+ private int retryInterval;
+ private Date startTime;
+ private Date endTime;
+ private String triggerExpression;
+}
diff --git a/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/enums/ExecuteTypeEnum.java b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/enums/ExecuteTypeEnum.java
new file mode 100644
index 0000000..e8769ad
--- /dev/null
+++ b/seatunnel-server/seatunnel-spi/src/main/java/org/apache/seatunnel/spi/scheduler/enums/ExecuteTypeEnum.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.seatunnel.spi.scheduler.enums;
+
+import static org.apache.seatunnel.server.common.SeatunnelErrorEnum.NO_SUCH_ELEMENT;
+
+import org.apache.seatunnel.server.common.SeatunnelException;
+
+public enum ExecuteTypeEnum {
+ TEMPORARY,
+ MANUAL,
+ SCHEDULER,
+ RERUN,
+ ;
+
+ public static ExecuteTypeEnum parse(int executeType) {
+ for (ExecuteTypeEnum value : values()) {
+ if (value.ordinal() == executeType) {
+ return value;
+ }
+ }
+ throw new SeatunnelException(NO_SUCH_ELEMENT);
+ }
+}
diff --git a/seatunnel-ui/.env.development b/seatunnel-ui/.env.development
new file mode 100644
index 0000000..c73a1a7
--- /dev/null
+++ b/seatunnel-ui/.env.development
@@ -0,0 +1,18 @@
+ # Licensed to the Apache Software Foundation (ASF) under one or more
+ # contributor license agreements. See the NOTICE file distributed with
+ # this work for additional information regarding copyright ownership.
+ # The ASF licenses this file to You under the Apache License, Version 2.0
+ # (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+NODE_ENV=development
+
+VITE_APP_DEV_WEB_URL=''
diff --git a/seatunnel-ui/.env.production b/seatunnel-ui/.env.production
new file mode 100644
index 0000000..74bc29d
--- /dev/null
+++ b/seatunnel-ui/.env.production
@@ -0,0 +1,18 @@
+ # Licensed to the Apache Software Foundation (ASF) under one or more
+ # contributor license agreements. See the NOTICE file distributed with
+ # this work for additional information regarding copyright ownership.
+ # The ASF licenses this file to You under the Apache License, Version 2.0
+ # (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+NODE_ENV=production
+
+VITE_APP_PROD_WEB_URL=''
diff --git a/seatunnel-ui/.eslintignore b/seatunnel-ui/.eslintignore
new file mode 100644
index 0000000..adb3fad
--- /dev/null
+++ b/seatunnel-ui/.eslintignore
@@ -0,0 +1,18 @@
+ # Licensed to the Apache Software Foundation (ASF) under one or more
+ # contributor license agreements. See the NOTICE file distributed with
+ # this work for additional information regarding copyright ownership.
+ # The ASF licenses this file to You under the Apache License, Version 2.0
+ # (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+node_modules
+dist
+public
diff --git a/seatunnel-ui/.eslintrc.js b/seatunnel-ui/.eslintrc.js
new file mode 100644
index 0000000..b772b7c
--- /dev/null
+++ b/seatunnel-ui/.eslintrc.js
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+ parser: 'vue-eslint-parser',
+ parserOptions: {
+ parser: '@typescript-eslint/parser',
+ ecmaVersion: 2021,
+ sourceType: 'module',
+ ecmaFeatures: {
+ jsx: true
+ }
+ },
+ extends: [
+ 'plugin:vue/vue3-recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:prettier/recommended',
+ 'prettier'
+ ],
+ rules: {
+ '@typescript-eslint/ban-ts-ignore': 'off',
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-var-requires': 'off',
+ '@typescript-eslint/no-empty-function': 'off',
+ '@typescript-eslint/no-empty-interface': 'off',
+ 'vue/custom-event-name-casing': 'off',
+ 'no-use-before-define': 'off',
+ '@typescript-eslint/no-use-before-define': 'off',
+ '@typescript-eslint/ban-ts-comment': 'off',
+ '@typescript-eslint/ban-types': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/no-unused-vars': [
+ 'error',
+ {
+ argsIgnorePattern: '^(unused|ignored).*$',
+ varsIgnorePattern: '^(unused|ignored).*$'
+ }
+ ],
+ 'no-unused-vars': [
+ 'error',
+ {
+ argsIgnorePattern: '^(unused|ignored).*$',
+ varsIgnorePattern: '^(unused|ignored).*$'
+ }
+ ],
+ 'space-before-function-paren': 'off',
+ quotes: ['error', 'single'],
+ 'comma-dangle': ['error', 'never'],
+ 'vue/multi-word-component-names': 'off',
+ 'vue/component-definition-name-casing': 'off',
+ 'vue/require-valid-default-prop': 'off',
+ 'no-console': 'error',
+ 'vue/no-setup-props-destructure': 'off'
+ }
+}
diff --git a/seatunnel-ui/.gitignore b/seatunnel-ui/.gitignore
new file mode 100644
index 0000000..87ae732
--- /dev/null
+++ b/seatunnel-ui/.gitignore
@@ -0,0 +1,29 @@
+ # Licensed to the Apache Software Foundation (ASF) under one or more
+ # contributor license agreements. See the NOTICE file distributed with
+ # this work for additional information regarding copyright ownership.
+ # The ASF licenses this file to You under the Apache License, Version 2.0
+ # (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+.vscode
+.idea
+.DS_Store
+
+*.local
+*.swp
+*.tgz
+*.tsbuildinfo
+
+node_modules
+dist
+dist-ssr
+
+.pnpm-debug.log
diff --git a/seatunnel-ui/.prettierignore b/seatunnel-ui/.prettierignore
new file mode 100644
index 0000000..adb3fad
--- /dev/null
+++ b/seatunnel-ui/.prettierignore
@@ -0,0 +1,18 @@
+ # Licensed to the Apache Software Foundation (ASF) under one or more
+ # contributor license agreements. See the NOTICE file distributed with
+ # this work for additional information regarding copyright ownership.
+ # The ASF licenses this file to You under the Apache License, Version 2.0
+ # (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+node_modules
+dist
+public
diff --git a/seatunnel-ui/.prettierrc.js b/seatunnel-ui/.prettierrc.js
new file mode 100644
index 0000000..59732ff
--- /dev/null
+++ b/seatunnel-ui/.prettierrc.js
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+ useTabs: false,
+ semi: false,
+ vueIndentScriptAndStyle: true,
+ singleQuote: true,
+ quoteProps: 'as-needed',
+ jsxBracketSameLine: false,
+ jsxSingleQuote: true,
+ arrowParens: 'always',
+ htmlWhitespaceSensitivity: 'strict',
+ endOfLine: 'lf',
+ trailingComma: 'none'
+}
diff --git a/seatunnel-ui/README.md b/seatunnel-ui/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/seatunnel-ui/README.md
diff --git a/seatunnel-ui/index.html b/seatunnel-ui/index.html
new file mode 100644
index 0000000..9c457be
--- /dev/null
+++ b/seatunnel-ui/index.html
@@ -0,0 +1,30 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>SeaTunnel Admin</title>
+ </head>
+ <body>
+ <div id="app"></div>
+ <script type="module" src="/src/main.ts"></script>
+ </body>
+</html>
diff --git a/seatunnel-ui/package.json b/seatunnel-ui/package.json
new file mode 100644
index 0000000..afa6db6
--- /dev/null
+++ b/seatunnel-ui/package.json
@@ -0,0 +1,54 @@
+{
+ "name": "seatunnel-ui",
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "vite",
+ "build:prod": "vue-tsc --noEmit && vite build --mode production",
+ "preview": "vite preview",
+ "lint": "eslint src --fix --ext .ts,.tsx,.vue",
+ "prettier": "prettier --write \"src/**/*.{vue,ts,tsx}\""
+ },
+ "dependencies": {
+ "@vueuse/core": "^9.2.0",
+ "autoprefixer": "^10.4.8",
+ "axios": "^0.27.2",
+ "date-fns": "^2.29.2",
+ "date-fns-tz": "^1.3.7",
+ "echarts": "^5.3.3",
+ "lodash": "^4.17.21",
+ "monaco-editor": "^0.34.0",
+ "naive-ui": "2.30.7",
+ "nprogress": "^0.2.0",
+ "pinia": "^2.0.22",
+ "pinia-plugin-persistedstate": "^2.1.1",
+ "postcss": "^8.4.16",
+ "tailwindcss": "^3.1.8",
+ "vfonts": "^0.0.3",
+ "vue": "^3.2.38",
+ "vue-i18n": "^9.2.2",
+ "vue-router": "^4.1.5"
+ },
+ "devDependencies": {
+ "@types/lodash": "^4.14.184",
+ "@types/node": "^18.7.15",
+ "@types/nprogress": "^0.2.0",
+ "@typescript-eslint/eslint-plugin": "^5.36.2",
+ "@typescript-eslint/parser": "^5.36.2",
+ "@vicons/antd": "^0.12.0",
+ "@vitejs/plugin-vue": "^3.1.0",
+ "@vitejs/plugin-vue-jsx": "^2.0.1",
+ "dart-sass": "^1.25.0",
+ "eslint": "^8.23.0",
+ "eslint-config-prettier": "^8.5.0",
+ "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-vue": "^9.4.0",
+ "prettier": "^2.7.1",
+ "sass": "^1.54.8",
+ "sass-loader": "^13.0.2",
+ "typescript": "^4.8.2",
+ "typescript-plugin-css-modules": "^3.4.0",
+ "vite": "^3.1.0",
+ "vite-plugin-compression": "^0.5.1",
+ "vue-tsc": "^0.40.9"
+ }
+}
diff --git a/seatunnel-ui/pnpm-lock.yaml b/seatunnel-ui/pnpm-lock.yaml
new file mode 100644
index 0000000..8ad56e5
--- /dev/null
+++ b/seatunnel-ui/pnpm-lock.yaml
@@ -0,0 +1,3190 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+lockfileVersion: 5.4
+
+specifiers:
+ '@types/lodash': ^4.14.184
+ '@types/node': ^18.7.15
+ '@types/nprogress': ^0.2.0
+ '@typescript-eslint/eslint-plugin': ^5.36.2
+ '@typescript-eslint/parser': ^5.36.2
+ '@vicons/antd': ^0.12.0
+ '@vitejs/plugin-vue': ^3.1.0
+ '@vitejs/plugin-vue-jsx': ^2.0.1
+ '@vueuse/core': ^9.2.0
+ autoprefixer: ^10.4.8
+ axios: ^0.27.2
+ dart-sass: ^1.25.0
+ date-fns: ^2.29.2
+ date-fns-tz: ^1.3.7
+ echarts: ^5.3.3
+ eslint: ^8.23.0
+ eslint-config-prettier: ^8.5.0
+ eslint-plugin-prettier: ^4.2.1
+ eslint-plugin-vue: ^9.4.0
+ lodash: ^4.17.21
+ monaco-editor: ^0.34.0
+ naive-ui: 2.30.7
+ nprogress: ^0.2.0
+ pinia: ^2.0.22
+ pinia-plugin-persistedstate: ^2.1.1
+ postcss: ^8.4.16
+ prettier: ^2.7.1
+ sass: ^1.54.8
+ sass-loader: ^13.0.2
+ tailwindcss: ^3.1.8
+ typescript: ^4.8.2
+ typescript-plugin-css-modules: ^3.4.0
+ vfonts: ^0.0.3
+ vite: ^3.1.0
+ vite-plugin-compression: ^0.5.1
+ vue: ^3.2.38
+ vue-i18n: ^9.2.2
+ vue-router: ^4.1.5
+ vue-tsc: ^0.40.9
+
+dependencies:
+ '@vueuse/core': 9.2.0_vue@3.2.38
+ autoprefixer: 10.4.8_postcss@8.4.16
+ axios: 0.27.2
+ date-fns: 2.29.2
+ date-fns-tz: 1.3.7_date-fns@2.29.2
+ echarts: 5.3.3
+ lodash: 4.17.21
+ monaco-editor: 0.34.0
+ naive-ui: 2.30.7_vue@3.2.38
+ nprogress: 0.2.0
+ pinia: 2.0.22_pj7ch6rmow6odq73xb5hfvge3q
+ pinia-plugin-persistedstate: 2.1.1_pinia@2.0.22
+ postcss: 8.4.16
+ tailwindcss: 3.1.8
+ vfonts: 0.0.3
+ vue: 3.2.38
+ vue-i18n: 9.2.2_vue@3.2.38
+ vue-router: 4.1.5_vue@3.2.38
+
+devDependencies:
+ '@types/lodash': 4.14.184
+ '@types/node': 18.7.15
+ '@types/nprogress': 0.2.0
+ '@typescript-eslint/eslint-plugin': 5.36.2_iurrlxgqcgk5svigzxakafpeuu
+ '@typescript-eslint/parser': 5.36.2_yqf6kl63nyoq5megxukfnom5rm
+ '@vicons/antd': 0.12.0
+ '@vitejs/plugin-vue': 3.1.0_vite@3.1.0+vue@3.2.38
+ '@vitejs/plugin-vue-jsx': 2.0.1_vite@3.1.0+vue@3.2.38
+ dart-sass: 1.25.0
+ eslint: 8.23.0
+ eslint-config-prettier: 8.5.0_eslint@8.23.0
+ eslint-plugin-prettier: 4.2.1_tgumt6uwl2md3n6uqnggd6wvce
+ eslint-plugin-vue: 9.4.0_eslint@8.23.0
+ prettier: 2.7.1
+ sass: 1.54.8
+ sass-loader: 13.0.2_sass@1.54.8
+ typescript: 4.8.2
+ typescript-plugin-css-modules: 3.4.0_typescript@4.8.2
+ vite: 3.1.0_sass@1.54.8
+ vite-plugin-compression: 0.5.1_vite@3.1.0
+ vue-tsc: 0.40.9_typescript@4.8.2
+
+packages:
+
+ /@ampproject/remapping/2.2.0:
+ resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/gen-mapping': 0.1.1
+ '@jridgewell/trace-mapping': 0.3.15
+ dev: true
+
+ /@babel/code-frame/7.18.6:
+ resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/highlight': 7.18.6
+ dev: true
+
+ /@babel/compat-data/7.19.0:
+ resolution: {integrity: sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/core/7.19.0:
+ resolution: {integrity: sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@ampproject/remapping': 2.2.0
+ '@babel/code-frame': 7.18.6
+ '@babel/generator': 7.19.0
+ '@babel/helper-compilation-targets': 7.19.0_@babel+core@7.19.0
+ '@babel/helper-module-transforms': 7.19.0
+ '@babel/helpers': 7.19.0
+ '@babel/parser': 7.19.0
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.19.0
+ '@babel/types': 7.19.0
+ convert-source-map: 1.8.0
+ debug: 4.3.4
+ gensync: 1.0.0-beta.2
+ json5: 2.2.1
+ semver: 6.3.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/generator/7.19.0:
+ resolution: {integrity: sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ '@jridgewell/gen-mapping': 0.3.2
+ jsesc: 2.5.2
+ dev: true
+
+ /@babel/helper-annotate-as-pure/7.18.6:
+ resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-compilation-targets/7.19.0_@babel+core@7.19.0:
+ resolution: {integrity: sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/compat-data': 7.19.0
+ '@babel/core': 7.19.0
+ '@babel/helper-validator-option': 7.18.6
+ browserslist: 4.21.3
+ semver: 6.3.0
+ dev: true
+
+ /@babel/helper-create-class-features-plugin/7.19.0_@babel+core@7.19.0:
+ resolution: {integrity: sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/core': 7.19.0
+ '@babel/helper-annotate-as-pure': 7.18.6
+ '@babel/helper-environment-visitor': 7.18.9
+ '@babel/helper-function-name': 7.19.0
+ '@babel/helper-member-expression-to-functions': 7.18.9
+ '@babel/helper-optimise-call-expression': 7.18.6
+ '@babel/helper-replace-supers': 7.18.9
+ '@babel/helper-split-export-declaration': 7.18.6
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/helper-environment-visitor/7.18.9:
+ resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-function-name/7.19.0:
+ resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.18.10
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-hoist-variables/7.18.6:
+ resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-member-expression-to-functions/7.18.9:
+ resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-module-imports/7.18.6:
+ resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-module-transforms/7.19.0:
+ resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-environment-visitor': 7.18.9
+ '@babel/helper-module-imports': 7.18.6
+ '@babel/helper-simple-access': 7.18.6
+ '@babel/helper-split-export-declaration': 7.18.6
+ '@babel/helper-validator-identifier': 7.18.6
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.19.0
+ '@babel/types': 7.19.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/helper-optimise-call-expression/7.18.6:
+ resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-plugin-utils/7.19.0:
+ resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helper-replace-supers/7.18.9:
+ resolution: {integrity: sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-environment-visitor': 7.18.9
+ '@babel/helper-member-expression-to-functions': 7.18.9
+ '@babel/helper-optimise-call-expression': 7.18.6
+ '@babel/traverse': 7.19.0
+ '@babel/types': 7.19.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/helper-simple-access/7.18.6:
+ resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-split-export-declaration/7.18.6:
+ resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/helper-string-parser/7.18.10:
+ resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/helper-validator-identifier/7.18.6:
+ resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/helper-validator-option/7.18.6:
+ resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /@babel/helpers/7.19.0:
+ resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.19.0
+ '@babel/types': 7.19.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/highlight/7.18.6:
+ resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-validator-identifier': 7.18.6
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ dev: true
+
+ /@babel/parser/7.19.0:
+ resolution: {integrity: sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+ dependencies:
+ '@babel/types': 7.19.0
+
+ /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.19.0:
+ resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.19.0
+ '@babel/helper-plugin-utils': 7.19.0
+ dev: true
+
+ /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.0:
+ resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.19.0
+ '@babel/helper-plugin-utils': 7.19.0
+ dev: true
+
+ /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.19.0:
+ resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.19.0
+ '@babel/helper-plugin-utils': 7.19.0
+ dev: true
+
+ /@babel/plugin-transform-typescript/7.19.0_@babel+core@7.19.0:
+ resolution: {integrity: sha512-DOOIywxPpkQHXijXv+s9MDAyZcLp12oYRl3CMWZ6u7TjSoCBq/KqHR/nNFR3+i2xqheZxoF0H2XyL7B6xeSRuA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+ dependencies:
+ '@babel/core': 7.19.0
+ '@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.19.0
+ '@babel/helper-plugin-utils': 7.19.0
+ '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.19.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/template/7.18.10:
+ resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.18.6
+ '@babel/parser': 7.19.0
+ '@babel/types': 7.19.0
+ dev: true
+
+ /@babel/traverse/7.19.0:
+ resolution: {integrity: sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.18.6
+ '@babel/generator': 7.19.0
+ '@babel/helper-environment-visitor': 7.18.9
+ '@babel/helper-function-name': 7.19.0
+ '@babel/helper-hoist-variables': 7.18.6
+ '@babel/helper-split-export-declaration': 7.18.6
+ '@babel/parser': 7.19.0
+ '@babel/types': 7.19.0
+ debug: 4.3.4
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@babel/types/7.19.0:
+ resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.18.10
+ '@babel/helper-validator-identifier': 7.18.6
+ to-fast-properties: 2.0.0
+
+ /@css-render/plugin-bem/0.15.11_css-render@0.15.11:
+ resolution: {integrity: sha512-Bn8qadYPIz5DhZ4obTGHOJzeziQH6kY0+Fk5AEvwuuy378SLwwvXuuoechLjBHcgKkPCM03Oo4dDSGP/6NMdyw==}
+ peerDependencies:
+ css-render: ~0.15.11
+ dependencies:
+ css-render: 0.15.11
+ dev: false
+
+ /@css-render/vue3-ssr/0.15.11_vue@3.2.38:
+ resolution: {integrity: sha512-n+SuqLPbY30FUTM8slX75OaEG+c8XlTOFrAklekX2XQGvBbz9XdBE6hTEgGlV5kPcTMqTJeCG7Vzhs9/29VC7w==}
+ peerDependencies:
+ vue: ^3.0.11
+ dependencies:
+ vue: 3.2.38
+ dev: false
+
+ /@emotion/hash/0.8.0:
+ resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
+ dev: false
+
+ /@esbuild/linux-loong64/0.15.7:
+ resolution: {integrity: sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@eslint/eslintrc/1.3.1:
+ resolution: {integrity: sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 9.4.0
+ globals: 13.17.0
+ ignore: 5.2.0
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@humanwhocodes/config-array/0.10.4:
+ resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 1.2.1
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@humanwhocodes/gitignore-to-minimatch/1.0.2:
+ resolution: {integrity: sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==}
+ dev: true
+
+ /@humanwhocodes/module-importer/1.0.1:
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+ dev: true
+
+ /@humanwhocodes/object-schema/1.2.1:
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+ dev: true
+
+ /@intlify/core-base/9.2.2:
+ resolution: {integrity: sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==}
+ engines: {node: '>= 14'}
+ dependencies:
+ '@intlify/devtools-if': 9.2.2
+ '@intlify/message-compiler': 9.2.2
+ '@intlify/shared': 9.2.2
+ '@intlify/vue-devtools': 9.2.2
+ dev: false
+
+ /@intlify/devtools-if/9.2.2:
+ resolution: {integrity: sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==}
+ engines: {node: '>= 14'}
+ dependencies:
+ '@intlify/shared': 9.2.2
+ dev: false
+
+ /@intlify/message-compiler/9.2.2:
+ resolution: {integrity: sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==}
+ engines: {node: '>= 14'}
+ dependencies:
+ '@intlify/shared': 9.2.2
+ source-map: 0.6.1
+ dev: false
+
+ /@intlify/shared/9.2.2:
+ resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==}
+ engines: {node: '>= 14'}
+ dev: false
+
+ /@intlify/vue-devtools/9.2.2:
+ resolution: {integrity: sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==}
+ engines: {node: '>= 14'}
+ dependencies:
+ '@intlify/core-base': 9.2.2
+ '@intlify/shared': 9.2.2
+ dev: false
+
+ /@jridgewell/gen-mapping/0.1.1:
+ resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.1.2
+ '@jridgewell/sourcemap-codec': 1.4.14
+ dev: true
+
+ /@jridgewell/gen-mapping/0.3.2:
+ resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.1.2
+ '@jridgewell/sourcemap-codec': 1.4.14
+ '@jridgewell/trace-mapping': 0.3.15
+ dev: true
+
+ /@jridgewell/resolve-uri/3.1.0:
+ resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/set-array/1.1.2:
+ resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/sourcemap-codec/1.4.14:
+ resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
+ dev: true
+
+ /@jridgewell/trace-mapping/0.3.15:
+ resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.0
+ '@jridgewell/sourcemap-codec': 1.4.14
+ dev: true
+
+ /@juggle/resize-observer/3.4.0:
+ resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
+ dev: false
+
+ /@nodelib/fs.scandir/2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ /@nodelib/fs.stat/2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ /@nodelib/fs.walk/1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.13.0
+
+ /@types/json-schema/7.0.11:
+ resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
+ dev: true
+
+ /@types/json5/0.0.29:
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ dev: true
+
+ /@types/lodash-es/4.17.6:
+ resolution: {integrity: sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==}
+ dependencies:
+ '@types/lodash': 4.14.184
+ dev: false
+
+ /@types/lodash/4.14.184:
+ resolution: {integrity: sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==}
+
+ /@types/node/17.0.45:
+ resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
+ dev: false
+
+ /@types/node/18.7.15:
+ resolution: {integrity: sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ==}
+ dev: true
+
+ /@types/nprogress/0.2.0:
+ resolution: {integrity: sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==}
+ dev: true
+
+ /@types/web-bluetooth/0.0.15:
+ resolution: {integrity: sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA==}
+ dev: false
+
+ /@typescript-eslint/eslint-plugin/5.36.2_iurrlxgqcgk5svigzxakafpeuu:
+ resolution: {integrity: sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^5.0.0
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 5.36.2_yqf6kl63nyoq5megxukfnom5rm
+ '@typescript-eslint/scope-manager': 5.36.2
+ '@typescript-eslint/type-utils': 5.36.2_yqf6kl63nyoq5megxukfnom5rm
+ '@typescript-eslint/utils': 5.36.2_yqf6kl63nyoq5megxukfnom5rm
+ debug: 4.3.4
+ eslint: 8.23.0
+ functional-red-black-tree: 1.0.1
+ ignore: 5.2.0
+ regexpp: 3.2.0
+ semver: 7.3.7
+ tsutils: 3.21.0_typescript@4.8.2
+ typescript: 4.8.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/parser/5.36.2_yqf6kl63nyoq5megxukfnom5rm:
+ resolution: {integrity: sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 5.36.2
+ '@typescript-eslint/types': 5.36.2
+ '@typescript-eslint/typescript-estree': 5.36.2_typescript@4.8.2
+ debug: 4.3.4
+ eslint: 8.23.0
+ typescript: 4.8.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/scope-manager/5.36.2:
+ resolution: {integrity: sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.36.2
+ '@typescript-eslint/visitor-keys': 5.36.2
+ dev: true
+
+ /@typescript-eslint/type-utils/5.36.2_yqf6kl63nyoq5megxukfnom5rm:
+ resolution: {integrity: sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '*'
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/typescript-estree': 5.36.2_typescript@4.8.2
+ '@typescript-eslint/utils': 5.36.2_yqf6kl63nyoq5megxukfnom5rm
+ debug: 4.3.4
+ eslint: 8.23.0
+ tsutils: 3.21.0_typescript@4.8.2
+ typescript: 4.8.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/types/5.36.2:
+ resolution: {integrity: sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /@typescript-eslint/typescript-estree/5.36.2_typescript@4.8.2:
+ resolution: {integrity: sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 5.36.2
+ '@typescript-eslint/visitor-keys': 5.36.2
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.3.7
+ tsutils: 3.21.0_typescript@4.8.2
+ typescript: 4.8.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@typescript-eslint/utils/5.36.2_yqf6kl63nyoq5megxukfnom5rm:
+ resolution: {integrity: sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ '@types/json-schema': 7.0.11
+ '@typescript-eslint/scope-manager': 5.36.2
+ '@typescript-eslint/types': 5.36.2
+ '@typescript-eslint/typescript-estree': 5.36.2_typescript@4.8.2
+ eslint: 8.23.0
+ eslint-scope: 5.1.1
+ eslint-utils: 3.0.0_eslint@8.23.0
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+ dev: true
+
+ /@typescript-eslint/visitor-keys/5.36.2:
+ resolution: {integrity: sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.36.2
+ eslint-visitor-keys: 3.3.0
+ dev: true
+
+ /@vicons/antd/0.12.0:
+ resolution: {integrity: sha512-C0p6aO1EmGG1QHrqgUWQS1No20934OdWSRQshM5NIDK5H1On6tC26U0hT6Rmp40KfUsvhvX5YW8BoWJdNFifPg==}
+ dev: true
+
+ /@vitejs/plugin-vue-jsx/2.0.1_vite@3.1.0+vue@3.2.38:
+ resolution: {integrity: sha512-lmiR1k9+lrF7LMczO0pxtQ8mOn6XeppJDHxnpxkJQpT5SiKz4SKhKdeNstXaTNuR8qZhUo5X0pJlcocn72Y4Jg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^3.0.0
+ vue: ^3.0.0
+ dependencies:
+ '@babel/core': 7.19.0
+ '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.19.0
+ '@babel/plugin-transform-typescript': 7.19.0_@babel+core@7.19.0
+ '@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.19.0
+ vite: 3.1.0_sass@1.54.8
+ vue: 3.2.38
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@vitejs/plugin-vue/3.1.0_vite@3.1.0+vue@3.2.38:
+ resolution: {integrity: sha512-fmxtHPjSOEIRg6vHYDaem+97iwCUg/uSIaTzp98lhELt2ISOQuDo2hbkBdXod0g15IhfPMQmAxh4heUks2zvDA==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ peerDependencies:
+ vite: ^3.0.0
+ vue: ^3.2.25
+ dependencies:
+ vite: 3.1.0_sass@1.54.8
+ vue: 3.2.38
+ dev: true
+
+ /@volar/code-gen/0.40.9:
+ resolution: {integrity: sha512-SlLwXi1XzZG9ta4MQ6a2cdbtVYA4ibZFIK1Eb51Ii05m1AvrYvdOsLXOOC6ezRK2bws9dPEKbW0eYYnCoMjM3w==}
+ dependencies:
+ '@volar/source-map': 0.40.9
+ dev: true
+
+ /@volar/source-map/0.40.9:
+ resolution: {integrity: sha512-hJcedV2DXVfsu2fBKRuXX4s3WgQYIVtzQSGbfba5/+krY5joZzegnccJJPj/3TIo6P+1/p9CFi10xxP16JUGwQ==}
+ dependencies:
+ '@vue/reactivity': 3.2.38
+ dev: true
+
+ /@volar/typescript-faster/0.40.9:
+ resolution: {integrity: sha512-27kVrBwXX/qRLnD/MqsXUYRiYDLjfgwDsdMXKN7Nq7acMvYWmImY9k71x6hyDb/97iKvHFmgxbBlgN3SDcTcxg==}
+ dependencies:
+ semver: 7.3.7
+ dev: true
+
+ /@volar/vue-language-core/0.40.9:
+ resolution: {integrity: sha512-Vmx2l7IOl2NCg1RT+CYJowUG2MiAZOZ9OkBVPWZN+GYFcE6W90UDbGJyO64zSqlw/fYO0ERPRvxSBX0IULiigQ==}
+ dependencies:
+ '@volar/code-gen': 0.40.9
+ '@volar/source-map': 0.40.9
+ '@vue/compiler-core': 3.2.38
+ '@vue/compiler-dom': 3.2.38
+ '@vue/compiler-sfc': 3.2.38
+ '@vue/reactivity': 3.2.38
+ '@vue/shared': 3.2.38
+ dev: true
+
+ /@volar/vue-typescript/0.40.9:
+ resolution: {integrity: sha512-2k+7B5WGGOWIr0vBNpe7PzkOCRnrbkRpBLpeQJ7TSprnE4oi3OzVDcxDBXIGhW1+ccMJcBcASv2LrvVALbQKZA==}
+ dependencies:
+ '@volar/code-gen': 0.40.9
+ '@volar/typescript-faster': 0.40.9
+ '@volar/vue-language-core': 0.40.9
+ dev: true
+
+ /@vue/babel-helper-vue-transform-on/1.0.2:
+ resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==}
+ dev: true
+
+ /@vue/babel-plugin-jsx/1.1.1_@babel+core@7.19.0:
+ resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==}
+ dependencies:
+ '@babel/helper-module-imports': 7.18.6
+ '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.0
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.19.0
+ '@babel/types': 7.19.0
+ '@vue/babel-helper-vue-transform-on': 1.0.2
+ camelcase: 6.3.0
+ html-tags: 3.2.0
+ svg-tags: 1.0.0
+ transitivePeerDependencies:
+ - '@babel/core'
+ - supports-color
+ dev: true
+
+ /@vue/compiler-core/3.2.38:
+ resolution: {integrity: sha512-/FsvnSu7Z+lkd/8KXMa4yYNUiqQrI22135gfsQYVGuh5tqEgOB0XqrUdb/KnCLa5+TmQLPwvyUnKMyCpu+SX3Q==}
+ dependencies:
+ '@babel/parser': 7.19.0
+ '@vue/shared': 3.2.38
+ estree-walker: 2.0.2
+ source-map: 0.6.1
+
+ /@vue/compiler-dom/3.2.38:
+ resolution: {integrity: sha512-zqX4FgUbw56kzHlgYuEEJR8mefFiiyR3u96498+zWPsLeh1WKvgIReoNE+U7gG8bCUdvsrJ0JRmev0Ky6n2O0g==}
+ dependencies:
+ '@vue/compiler-core': 3.2.38
+ '@vue/shared': 3.2.38
+
+ /@vue/compiler-sfc/3.2.38:
+ resolution: {integrity: sha512-KZjrW32KloMYtTcHAFuw3CqsyWc5X6seb8KbkANSWt3Cz9p2qA8c1GJpSkksFP9ABb6an0FLCFl46ZFXx3kKpg==}
+ dependencies:
+ '@babel/parser': 7.19.0
+ '@vue/compiler-core': 3.2.38
+ '@vue/compiler-dom': 3.2.38
+ '@vue/compiler-ssr': 3.2.38
+ '@vue/reactivity-transform': 3.2.38
+ '@vue/shared': 3.2.38
+ estree-walker: 2.0.2
+ magic-string: 0.25.9
+ postcss: 8.4.16
+ source-map: 0.6.1
+
+ /@vue/compiler-ssr/3.2.38:
+ resolution: {integrity: sha512-bm9jOeyv1H3UskNm4S6IfueKjUNFmi2kRweFIGnqaGkkRePjwEcfCVqyS3roe7HvF4ugsEkhf4+kIvDhip6XzQ==}
+ dependencies:
+ '@vue/compiler-dom': 3.2.38
+ '@vue/shared': 3.2.38
+
+ /@vue/devtools-api/6.2.1:
+ resolution: {integrity: sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==}
+ dev: false
+
+ /@vue/reactivity-transform/3.2.38:
+ resolution: {integrity: sha512-3SD3Jmi1yXrDwiNJqQ6fs1x61WsDLqVk4NyKVz78mkaIRh6d3IqtRnptgRfXn+Fzf+m6B1KxBYWq1APj6h4qeA==}
+ dependencies:
+ '@babel/parser': 7.19.0
+ '@vue/compiler-core': 3.2.38
+ '@vue/shared': 3.2.38
+ estree-walker: 2.0.2
+ magic-string: 0.25.9
+
+ /@vue/reactivity/3.2.38:
+ resolution: {integrity: sha512-6L4myYcH9HG2M25co7/BSo0skKFHpAN8PhkNPM4xRVkyGl1K5M3Jx4rp5bsYhvYze2K4+l+pioN4e6ZwFLUVtw==}
+ dependencies:
+ '@vue/shared': 3.2.38
+
+ /@vue/runtime-core/3.2.38:
+ resolution: {integrity: sha512-kk0qiSiXUU/IKxZw31824rxmFzrLr3TL6ZcbrxWTKivadoKupdlzbQM4SlGo4MU6Zzrqv4fzyUasTU1jDoEnzg==}
+ dependencies:
+ '@vue/reactivity': 3.2.38
+ '@vue/shared': 3.2.38
+
+ /@vue/runtime-dom/3.2.38:
+ resolution: {integrity: sha512-4PKAb/ck2TjxdMSzMsnHViOrrwpudk4/A56uZjhzvusoEU9xqa5dygksbzYepdZeB5NqtRw5fRhWIiQlRVK45A==}
+ dependencies:
+ '@vue/runtime-core': 3.2.38
+ '@vue/shared': 3.2.38
+ csstype: 2.6.20
+
+ /@vue/server-renderer/3.2.38_vue@3.2.38:
+ resolution: {integrity: sha512-pg+JanpbOZ5kEfOZzO2bt02YHd+ELhYP8zPeLU1H0e7lg079NtuuSB8fjLdn58c4Ou8UQ6C1/P+528nXnLPAhA==}
+ peerDependencies:
+ vue: 3.2.38
+ dependencies:
+ '@vue/compiler-ssr': 3.2.38
+ '@vue/shared': 3.2.38
+ vue: 3.2.38
+
+ /@vue/shared/3.2.38:
+ resolution: {integrity: sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==}
+
+ /@vueuse/core/9.2.0_vue@3.2.38:
+ resolution: {integrity: sha512-/MZ6qpz6uSyaXrtoeBWQzAKRG3N7CvfVWvQxiM3ei3Xe5ydOjjtVbo7lGl9p8dECV93j7W8s63A8H0kFLpLyxg==}
+ dependencies:
+ '@types/web-bluetooth': 0.0.15
+ '@vueuse/metadata': 9.2.0
+ '@vueuse/shared': 9.2.0_vue@3.2.38
+ vue-demi: 0.13.11_vue@3.2.38
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: false
+
+ /@vueuse/metadata/9.2.0:
+ resolution: {integrity: sha512-exN4KE6iquxDCdt72BgEhb3tlOpECtD61AUdXnUqBTIUCl70x1Ar/QXo3bYcvxmdMS2/peQyfeTzBjRTpvL5xw==}
+ dev: false
+
+ /@vueuse/shared/9.2.0_vue@3.2.38:
+ resolution: {integrity: sha512-NnRp/noSWuXW0dKhZK5D0YLrDi0nmZ18UeEgwXQq7Ul5TTP93lcNnKjrHtd68j2xFB/l59yPGFlCryL692bnrA==}
+ dependencies:
+ vue-demi: 0.13.11_vue@3.2.38
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+ dev: false
+
+ /acorn-jsx/5.3.2_acorn@8.8.0:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 8.8.0
+ dev: true
+
+ /acorn-node/1.8.2:
+ resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
+ dependencies:
+ acorn: 7.4.1
+ acorn-walk: 7.2.0
+ xtend: 4.0.2
+ dev: false
+
+ /acorn-walk/7.2.0:
+ resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
+ engines: {node: '>=0.4.0'}
+ dev: false
+
+ /acorn/7.4.1:
+ resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: false
+
+ /acorn/8.8.0:
+ resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: true
+
+ /ajv/6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+ dev: true
+
+ /ansi-regex/5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /ansi-styles/3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+ dependencies:
+ color-convert: 1.9.3
+ dev: true
+
+ /ansi-styles/4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+ dev: true
+
+ /anymatch/3.1.2:
+ resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ /arg/5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+ dev: false
+
+ /argparse/2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ dev: true
+
+ /array-union/2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /async-validator/4.2.5:
+ resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+ dev: false
+
+ /asynckit/0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+ dev: false
+
+ /atob/2.1.2:
+ resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
+ engines: {node: '>= 4.5.0'}
+ hasBin: true
+ dev: true
+
+ /autoprefixer/10.4.8_postcss@8.4.16:
+ resolution: {integrity: sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+ dependencies:
+ browserslist: 4.21.3
+ caniuse-lite: 1.0.30001390
+ fraction.js: 4.2.0
+ normalize-range: 0.1.2
+ picocolors: 1.0.0
+ postcss: 8.4.16
+ postcss-value-parser: 4.2.0
+ dev: false
+
+ /axios/0.27.2:
+ resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
+ dependencies:
+ follow-redirects: 1.15.1
+ form-data: 4.0.0
+ transitivePeerDependencies:
+ - debug
+ dev: false
+
+ /balanced-match/1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ dev: true
+
+ /big.js/3.2.0:
+ resolution: {integrity: sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==}
+ dev: true
+
+ /binary-extensions/2.2.0:
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+ engines: {node: '>=8'}
+
+ /boolbase/1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+ dev: true
+
+ /brace-expansion/1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+ dev: true
+
+ /braces/3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+
+ /browserslist/4.21.3:
+ resolution: {integrity: sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+ dependencies:
+ caniuse-lite: 1.0.30001390
+ electron-to-chromium: 1.4.242
+ node-releases: 2.0.6
+ update-browserslist-db: 1.0.7_browserslist@4.21.3
+
+ /callsites/3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /camelcase-css/2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+ dev: false
+
+ /camelcase/6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /caniuse-lite/1.0.30001390:
+ resolution: {integrity: sha512-sS4CaUM+/+vqQUlCvCJ2WtDlV81aWtHhqeEVkLokVJJa3ViN4zDxAGfq9R8i1m90uGHxo99cy10Od+lvn3hf0g==}
+
+ /chalk/2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+ dev: true
+
+ /chalk/4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+ dev: true
+
+ /chokidar/3.5.3:
+ resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ engines: {node: '>= 8.10.0'}
+ dependencies:
+ anymatch: 3.1.2
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.2
+
+ /color-convert/1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+ dependencies:
+ color-name: 1.1.3
+ dev: true
+
+ /color-convert/2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+ dependencies:
+ color-name: 1.1.4
+ dev: true
+
+ /color-name/1.1.3:
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+ dev: true
+
+ /color-name/1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ /combined-stream/1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ delayed-stream: 1.0.0
+ dev: false
+
+ /concat-map/0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ dev: true
+
+ /convert-source-map/1.8.0:
+ resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
+ dependencies:
+ safe-buffer: 5.1.2
+ dev: true
+
+ /copy-anything/2.0.6:
+ resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
+ dependencies:
+ is-what: 3.14.1
+ dev: true
+
+ /cross-spawn/7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+ dev: true
+
+ /css-parse/2.0.0:
+ resolution: {integrity: sha512-UNIFik2RgSbiTwIW1IsFwXWn6vs+bYdq83LKTSOsx7NJR7WII9dxewkHLltfTLVppoUApHV0118a4RZRI9FLwA==}
+ dependencies:
+ css: 2.2.4
+ dev: true
+
+ /css-render/0.15.11:
+ resolution: {integrity: sha512-hnLrHPUndVUTF5nmNPRey6hpixK02IPUGdEsm2xRjvJuewToyrVFx9Nmai8rgfVzhTFo5SJVh2PHAtzaIV8JKw==}
+ dependencies:
+ '@emotion/hash': 0.8.0
+ '@types/node': 17.0.45
+ csstype: 3.0.11
+ dev: false
+
+ /css-selector-tokenizer/0.7.3:
+ resolution: {integrity: sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg==}
+ dependencies:
+ cssesc: 3.0.0
+ fastparse: 1.1.2
+ dev: true
+
+ /css/2.2.4:
+ resolution: {integrity: sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==}
+ dependencies:
+ inherits: 2.0.4
+ source-map: 0.6.1
+ source-map-resolve: 0.5.3
+ urix: 0.1.0
+ dev: true
+
+ /cssesc/3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ /csstype/2.6.20:
+ resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==}
+
+ /csstype/3.0.11:
+ resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==}
+ dev: false
+
+ /dart-sass/1.25.0:
+ resolution: {integrity: sha512-syNOAstJXAmvD3RifcDk3fiPMyYE2fY8so6w9gf2/wNlKpG0zyH+oiXubEYVOy1WAWkzOc72pbAxwx+3OU4JJA==}
+ engines: {node: '>=8.9.0'}
+ deprecated: This package has been renamed to 'sass'.
+ hasBin: true
+ dependencies:
+ chokidar: 3.5.3
+ dev: true
+
+ /date-fns-tz/1.3.7_date-fns@2.29.2:
+ resolution: {integrity: sha512-1t1b8zyJo+UI8aR+g3iqr5fkUHWpd58VBx8J/ZSQ+w7YrGlw80Ag4sA86qkfCXRBLmMc4I2US+aPMd4uKvwj5g==}
+ peerDependencies:
+ date-fns: '>=2.0.0'
+ dependencies:
+ date-fns: 2.29.2
+ dev: false
+
+ /date-fns/2.29.2:
+ resolution: {integrity: sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA==}
+ engines: {node: '>=0.11'}
+ dev: false
+
+ /debug/3.1.0:
+ resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.0.0
+ dev: true
+
+ /debug/3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ dev: true
+ optional: true
+
+ /debug/4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+ dev: true
+
+ /decode-uri-component/0.2.0:
+ resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==}
+ engines: {node: '>=0.10'}
+ dev: true
+
+ /deep-is/0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+ dev: true
+
+ /defined/1.0.0:
+ resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==}
+ dev: false
+
+ /delayed-stream/1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+ dev: false
+
+ /detective/5.2.1:
+ resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==}
+ engines: {node: '>=0.8.0'}
+ hasBin: true
+ dependencies:
+ acorn-node: 1.8.2
+ defined: 1.0.0
+ minimist: 1.2.6
+ dev: false
+
+ /didyoumean/1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+ dev: false
+
+ /dir-glob/3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+ dev: true
+
+ /dlv/1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+ dev: false
+
+ /doctrine/3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: true
+
+ /dotenv/10.0.0:
+ resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /echarts/5.3.3:
+ resolution: {integrity: sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==}
+ dependencies:
+ tslib: 2.3.0
+ zrender: 5.3.2
+ dev: false
+
+ /electron-to-chromium/1.4.242:
+ resolution: {integrity: sha512-nPdgMWtjjWGCtreW/2adkrB2jyHjClo9PtVhR6rW+oxa4E4Wom642Tn+5LslHP3XPL5MCpkn5/UEY60EXylNeQ==}
+
+ /emojis-list/2.1.0:
+ resolution: {integrity: sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==}
+ engines: {node: '>= 0.10'}
+ dev: true
+
+ /errno/0.1.8:
+ resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ prr: 1.0.1
+ dev: true
+ optional: true
+
+ /esbuild-android-64/0.15.7:
+ resolution: {integrity: sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-android-arm64/0.15.7:
+ resolution: {integrity: sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-darwin-64/0.15.7:
+ resolution: {integrity: sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-darwin-arm64/0.15.7:
+ resolution: {integrity: sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-freebsd-64/0.15.7:
+ resolution: {integrity: sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-freebsd-arm64/0.15.7:
+ resolution: {integrity: sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-32/0.15.7:
+ resolution: {integrity: sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-64/0.15.7:
+ resolution: {integrity: sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-arm/0.15.7:
+ resolution: {integrity: sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-arm64/0.15.7:
+ resolution: {integrity: sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-mips64le/0.15.7:
+ resolution: {integrity: sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-ppc64le/0.15.7:
+ resolution: {integrity: sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-riscv64/0.15.7:
+ resolution: {integrity: sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-linux-s390x/0.15.7:
+ resolution: {integrity: sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-netbsd-64/0.15.7:
+ resolution: {integrity: sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-openbsd-64/0.15.7:
+ resolution: {integrity: sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-sunos-64/0.15.7:
+ resolution: {integrity: sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-windows-32/0.15.7:
+ resolution: {integrity: sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-windows-64/0.15.7:
+ resolution: {integrity: sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild-windows-arm64/0.15.7:
+ resolution: {integrity: sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /esbuild/0.15.7:
+ resolution: {integrity: sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/linux-loong64': 0.15.7
+ esbuild-android-64: 0.15.7
+ esbuild-android-arm64: 0.15.7
+ esbuild-darwin-64: 0.15.7
+ esbuild-darwin-arm64: 0.15.7
+ esbuild-freebsd-64: 0.15.7
+ esbuild-freebsd-arm64: 0.15.7
+ esbuild-linux-32: 0.15.7
+ esbuild-linux-64: 0.15.7
+ esbuild-linux-arm: 0.15.7
+ esbuild-linux-arm64: 0.15.7
+ esbuild-linux-mips64le: 0.15.7
+ esbuild-linux-ppc64le: 0.15.7
+ esbuild-linux-riscv64: 0.15.7
+ esbuild-linux-s390x: 0.15.7
+ esbuild-netbsd-64: 0.15.7
+ esbuild-openbsd-64: 0.15.7
+ esbuild-sunos-64: 0.15.7
+ esbuild-windows-32: 0.15.7
+ esbuild-windows-64: 0.15.7
+ esbuild-windows-arm64: 0.15.7
+ dev: true
+
+ /escalade/3.1.1:
+ resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+ engines: {node: '>=6'}
+
+ /escape-string-regexp/1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+ dev: true
+
+ /escape-string-regexp/4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /eslint-config-prettier/8.5.0_eslint@8.23.0:
+ resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
+ hasBin: true
+ peerDependencies:
+ eslint: '>=7.0.0'
+ dependencies:
+ eslint: 8.23.0
+ dev: true
+
+ /eslint-plugin-prettier/4.2.1_tgumt6uwl2md3n6uqnggd6wvce:
+ resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ eslint: '>=7.28.0'
+ eslint-config-prettier: '*'
+ prettier: '>=2.0.0'
+ peerDependenciesMeta:
+ eslint-config-prettier:
+ optional: true
+ dependencies:
+ eslint: 8.23.0
+ eslint-config-prettier: 8.5.0_eslint@8.23.0
+ prettier: 2.7.1
+ prettier-linter-helpers: 1.0.0
+ dev: true
+
+ /eslint-plugin-vue/9.4.0_eslint@8.23.0:
+ resolution: {integrity: sha512-Nzz2QIJ8FG+rtJaqT/7/ru5ie2XgT9KCudkbN0y3uFYhQ41nuHEaboLAiqwMcK006hZPQv/rVMRhUIwEGhIvfQ==}
+ engines: {node: ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ eslint: 8.23.0
+ eslint-utils: 3.0.0_eslint@8.23.0
+ natural-compare: 1.4.0
+ nth-check: 2.1.1
+ postcss-selector-parser: 6.0.10
+ semver: 7.3.7
+ vue-eslint-parser: 9.0.3_eslint@8.23.0
+ xml-name-validator: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /eslint-scope/5.1.1:
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+ engines: {node: '>=8.0.0'}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 4.3.0
+ dev: true
+
+ /eslint-scope/7.1.1:
+ resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+ dev: true
+
+ /eslint-utils/3.0.0_eslint@8.23.0:
+ resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
+ engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
+ peerDependencies:
+ eslint: '>=5'
+ dependencies:
+ eslint: 8.23.0
+ eslint-visitor-keys: 2.1.0
+ dev: true
+
+ /eslint-visitor-keys/2.1.0:
+ resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /eslint-visitor-keys/3.3.0:
+ resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: true
+
+ /eslint/8.23.0:
+ resolution: {integrity: sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ hasBin: true
+ dependencies:
+ '@eslint/eslintrc': 1.3.1
+ '@humanwhocodes/config-array': 0.10.4
+ '@humanwhocodes/gitignore-to-minimatch': 1.0.2
+ '@humanwhocodes/module-importer': 1.0.1
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ doctrine: 3.0.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 7.1.1
+ eslint-utils: 3.0.0_eslint@8.23.0
+ eslint-visitor-keys: 3.3.0
+ espree: 9.4.0
+ esquery: 1.4.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ functional-red-black-tree: 1.0.1
+ glob-parent: 6.0.2
+ globals: 13.17.0
+ globby: 11.1.0
+ grapheme-splitter: 1.0.4
+ ignore: 5.2.0
+ import-fresh: 3.3.0
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ js-yaml: 4.1.0
+ json-stable-stringify-without-jsonify: 1.0.1
+ levn: 0.4.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.2
+ natural-compare: 1.4.0
+ optionator: 0.9.1
+ regexpp: 3.2.0
+ strip-ansi: 6.0.1
+ strip-json-comments: 3.1.1
+ text-table: 0.2.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /espree/9.4.0:
+ resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ acorn: 8.8.0
+ acorn-jsx: 5.3.2_acorn@8.8.0
+ eslint-visitor-keys: 3.3.0
+ dev: true
+
+ /esquery/1.4.0:
+ resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /esrecurse/4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ estraverse: 5.3.0
+ dev: true
+
+ /estraverse/4.3.0:
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+ engines: {node: '>=4.0'}
+ dev: true
+
+ /estraverse/5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+ dev: true
+
+ /estree-walker/2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ /esutils/2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /evtd/0.2.4:
+ resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==}
+ dev: false
+
+ /fast-deep-equal/3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+ dev: true
+
+ /fast-diff/1.2.0:
+ resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
+ dev: true
+
+ /fast-glob/3.2.11:
+ resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+
+ /fast-json-stable-stringify/2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+ dev: true
+
+ /fast-levenshtein/2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+ dev: true
+
+ /fastparse/1.1.2:
+ resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==}
+ dev: true
+
+ /fastq/1.13.0:
+ resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
+ dependencies:
+ reusify: 1.0.4
+
+ /file-entry-cache/6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.0.4
+ dev: true
+
+ /fill-range/7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+
+ /find-up/5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+ dev: true
+
+ /flat-cache/3.0.4:
+ resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flatted: 3.2.7
+ rimraf: 3.0.2
+ dev: true
+
+ /flatted/3.2.7:
+ resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
+ dev: true
+
+ /follow-redirects/1.15.1:
+ resolution: {integrity: sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+ dev: false
+
+ /form-data/4.0.0:
+ resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+ engines: {node: '>= 6'}
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+ dev: false
+
+ /fraction.js/4.2.0:
+ resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
+ dev: false
+
+ /fs-extra/10.1.0:
+ resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ graceful-fs: 4.2.10
+ jsonfile: 6.1.0
+ universalify: 2.0.0
+ dev: true
+
+ /fs.realpath/1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+ dev: true
+
+ /fsevents/2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
+ /function-bind/1.1.1:
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+
+ /functional-red-black-tree/1.0.1:
+ resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
+ dev: true
+
+ /generic-names/1.0.3:
+ resolution: {integrity: sha512-b6OHfQuKasIKM9b6YPkX+KUj/TLBTx3B/1aT1T5F12FEuEqyFMdr59OMS53aoaSw8eVtapdqieX6lbg5opaOhA==}
+ dependencies:
+ loader-utils: 0.2.17
+ dev: true
+
+ /gensync/1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+ dev: true
+
+ /glob-parent/5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+
+ /glob-parent/6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+ dependencies:
+ is-glob: 4.0.3
+
+ /glob/7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+ dev: true
+
+ /globals/11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /globals/13.17.0:
+ resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+ dev: true
+
+ /globby/11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.2.11
+ ignore: 5.2.0
+ merge2: 1.4.1
+ slash: 3.0.0
+ dev: true
+
+ /graceful-fs/4.2.10:
+ resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
+ dev: true
+
+ /grapheme-splitter/1.0.4:
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
+ dev: true
+
+ /has-flag/3.0.0:
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /has-flag/4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /has/1.0.3:
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+ engines: {node: '>= 0.4.0'}
+ dependencies:
+ function-bind: 1.1.1
+
+ /highlight.js/11.6.0:
+ resolution: {integrity: sha512-ig1eqDzJaB0pqEvlPVIpSSyMaO92bH1N2rJpLMN/nX396wTpDA4Eq0uK+7I/2XG17pFaaKE0kjV/XPeGt7Evjw==}
+ engines: {node: '>=12.0.0'}
+ dev: false
+
+ /html-tags/3.2.0:
+ resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /iconv-lite/0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ safer-buffer: 2.1.2
+ dev: true
+ optional: true
+
+ /icss-utils/3.0.1:
+ resolution: {integrity: sha512-ANhVLoEfe0KoC9+z4yiTaXOneB49K6JIXdS+yAgH0NERELpdIT7kkj2XxUPuHafeHnn8umXnECSpsfk1RTaUew==}
+ dependencies:
+ postcss: 6.0.23
+ dev: true
+
+ /icss-utils/5.1.0_postcss@8.4.16:
+ resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
+ engines: {node: ^10 || ^12 || >= 14}
+ peerDependencies:
+ postcss: ^8.1.0
+ dependencies:
+ postcss: 8.4.16
+ dev: true
+
+ /ignore/5.2.0:
+ resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
+ engines: {node: '>= 4'}
+ dev: true
+
+ /image-size/0.5.5:
+ resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
+ engines: {node: '>=0.10.0'}
+ hasBin: true
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /immutable/4.1.0:
+ resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==}
+ dev: true
+
+ /import-fresh/3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+ dev: true
+
+ /imurmurhash/0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+ dev: true
+
+ /inflight/1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+ dev: true
+
+ /inherits/2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ dev: true
+
+ /is-binary-path/2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+ dependencies:
+ binary-extensions: 2.2.0
+
+ /is-core-module/2.10.0:
+ resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
+ dependencies:
+ has: 1.0.3
+
+ /is-extglob/2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ /is-glob/4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+
+ /is-number/7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ /is-what/3.14.1:
+ resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
+ dev: true
+
+ /isexe/2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ dev: true
+
+ /js-tokens/4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ dev: true
+
+ /js-yaml/4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+ dependencies:
+ argparse: 2.0.1
+ dev: true
+
+ /jsesc/2.5.2:
+ resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+ engines: {node: '>=4'}
+ hasBin: true
+ dev: true
+
+ /json-schema-traverse/0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ dev: true
+
+ /json-stable-stringify-without-jsonify/1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+ dev: true
+
+ /json5/0.5.1:
+ resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==}
+ hasBin: true
+ dev: true
+
+ /json5/1.0.1:
+ resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.6
+ dev: true
+
+ /json5/2.2.1:
+ resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
+ engines: {node: '>=6'}
+ hasBin: true
+ dev: true
+
+ /jsonfile/6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+ dependencies:
+ universalify: 2.0.0
+ optionalDependencies:
+ graceful-fs: 4.2.10
+ dev: true
+
+ /klona/2.0.5:
+ resolution: {integrity: sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /less/4.1.3:
+ resolution: {integrity: sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==}
+ engines: {node: '>=6'}
+ hasBin: true
+ dependencies:
+ copy-anything: 2.0.6
+ parse-node-version: 1.0.1
+ tslib: 2.4.0
+ optionalDependencies:
+ errno: 0.1.8
+ graceful-fs: 4.2.10
+ image-size: 0.5.5
+ make-dir: 2.1.0
+ mime: 1.6.0
+ needle: 3.1.0
+ source-map: 0.6.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /levn/0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ dev: true
+
+ /lilconfig/2.0.6:
+ resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
+ engines: {node: '>=10'}
+
+ /loader-utils/0.2.17:
+ resolution: {integrity: sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==}
+ dependencies:
+ big.js: 3.2.0
+ emojis-list: 2.1.0
+ json5: 0.5.1
+ object-assign: 4.1.1
+ dev: true
+
+ /locate-path/6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-locate: 5.0.0
+ dev: true
+
+ /lodash-es/4.17.21:
+ resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+ dev: false
+
+ /lodash.camelcase/4.3.0:
+ resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
+ dev: true
+
+ /lodash.merge/4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ dev: true
+
+ /lodash/4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+ /lru-cache/6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+ dev: true
+
+ /magic-string/0.25.9:
+ resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
+ dependencies:
+ sourcemap-codec: 1.4.8
+
+ /make-dir/2.1.0:
+ resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
+ engines: {node: '>=6'}
+ requiresBuild: true
+ dependencies:
+ pify: 4.0.1
+ semver: 5.7.1
+ dev: true
+ optional: true
+
+ /merge2/1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ /micromatch/4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+
+ /mime-db/1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /mime-types/2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ mime-db: 1.52.0
+ dev: false
+
+ /mime/1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /minimatch/3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+ dev: true
+
+ /minimist/1.2.6:
+ resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
+
+ /mkdirp/1.0.4:
+ resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dev: true
+
+ /monaco-editor/0.34.0:
+ resolution: {integrity: sha512-VF+S5zG8wxfinLKLrWcl4WUizMx+LeJrG4PM/M78OhcwocpV0jiyhX/pG6Q9jIOhrb/ckYi6nHnaR5OojlOZCQ==}
+ dev: false
+
+ /ms/2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+ dev: true
+
+ /ms/2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+ dev: true
+
+ /ms/2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ dev: true
+ optional: true
+
+ /naive-ui/2.30.7_vue@3.2.38:
+ resolution: {integrity: sha512-5F/dcSP5nnbOGuwZl0TJ6PciuyAatEllcTC+Q/aaxJS/N2iEpysonyWNMruBCQn2vHoASTK5i/KqaHdxM9aL1Q==}
+ peerDependencies:
+ vue: ^3.0.0
+ dependencies:
+ '@css-render/plugin-bem': 0.15.11_css-render@0.15.11
+ '@css-render/vue3-ssr': 0.15.11_vue@3.2.38
+ '@types/lodash': 4.14.184
+ '@types/lodash-es': 4.17.6
+ async-validator: 4.2.5
+ css-render: 0.15.11
+ date-fns: 2.29.2
+ date-fns-tz: 1.3.7_date-fns@2.29.2
+ evtd: 0.2.4
+ highlight.js: 11.6.0
+ lodash: 4.17.21
+ lodash-es: 4.17.21
+ seemly: 0.3.6
+ treemate: 0.3.11
+ vdirs: 0.1.8_vue@3.2.38
+ vooks: 0.2.12_vue@3.2.38
+ vue: 3.2.38
+ vueuc: 0.4.48_vue@3.2.38
+ dev: false
+
+ /nanoid/3.3.4:
+ resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ /natural-compare/1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ dev: true
+
+ /needle/3.1.0:
+ resolution: {integrity: sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==}
+ engines: {node: '>= 4.4.x'}
+ hasBin: true
+ requiresBuild: true
+ dependencies:
+ debug: 3.2.7
+ iconv-lite: 0.6.3
+ sax: 1.2.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+ optional: true
+
+ /neo-async/2.6.2:
+ resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+ dev: true
+
+ /node-releases/2.0.6:
+ resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
+
+ /normalize-path/3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ /normalize-range/0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /nprogress/0.2.0:
+ resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==}
+ dev: false
+
+ /nth-check/2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+ dependencies:
+ boolbase: 1.0.0
+ dev: true
+
+ /object-assign/4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /object-hash/3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+ dev: false
+
+ /once/1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+ dev: true
+
+ /optionator/0.9.1:
+ resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.3
+ dev: true
+
+ /p-limit/3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ yocto-queue: 0.1.0
+ dev: true
+
+ /p-locate/5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+ dependencies:
+ p-limit: 3.1.0
+ dev: true
+
+ /parent-module/1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+ dev: true
+
+ /parse-node-version/1.0.1:
+ resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
+ engines: {node: '>= 0.10'}
+ dev: true
+
+ /path-exists/4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-is-absolute/1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /path-key/3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /path-parse/1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ /path-type/4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /picocolors/1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+
+ /picomatch/2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ /pify/2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /pify/4.0.1:
+ resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
+ engines: {node: '>=6'}
+ dev: true
+ optional: true
+
+ /pinia-plugin-persistedstate/2.1.1_pinia@2.0.22:
+ resolution: {integrity: sha512-HUgsU5IRtM75eAQiIqzT3p1oPEuYH1/B2ipTMU++yE+FV0LkHaBswdKXs0RMWYCmugO8s62oxLTh/N1dLNp+5A==}
+ peerDependencies:
+ pinia: ^2.0.0
+ peerDependenciesMeta:
+ pinia:
+ optional: true
+ dependencies:
+ pinia: 2.0.22_pj7ch6rmow6odq73xb5hfvge3q
+ dev: false
+
+ /pinia/2.0.22_pj7ch6rmow6odq73xb5hfvge3q:
+ resolution: {integrity: sha512-u+b8/BC+tmvo3ACbYO2w5NfxHWFOjvvw9DQnyT0dW8aUMCPRQT5QnfZ5R5W2MzZBMTeZRMQI7V/QFbafmM9QHw==}
+ peerDependencies:
+ '@vue/composition-api': ^1.4.0
+ typescript: '>=4.4.4'
+ vue: ^2.6.14 || ^3.2.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+ typescript:
+ optional: true
+ dependencies:
+ '@vue/devtools-api': 6.2.1
+ typescript: 4.8.2
+ vue: 3.2.38
+ vue-demi: 0.13.11_vue@3.2.38
+ dev: false
+
+ /postcss-filter-plugins/3.0.1:
+ resolution: {integrity: sha512-tRKbW4wWBEkSSFuJtamV2wkiV9rj6Yy7P3Y13+zaynlPEEZt8EgYKn3y/RBpMeIhNmHXFlSdzofml65hD5OafA==}
+ dependencies:
+ postcss: 6.0.23
+ dev: true
+
+ /postcss-icss-keyframes/0.2.1:
+ resolution: {integrity: sha512-4m+hLY5TVqoTM198KKnzdNudyu1OvtqwD+8kVZ9PNiEO4+IfHYoyVvEXsOHjV8nZ1k6xowf+nY4HlUfZhOFvvw==}
+ dependencies:
+ icss-utils: 3.0.1
+ postcss: 6.0.23
+ postcss-value-parser: 3.3.1
+ dev: true
+
+ /postcss-icss-selectors/2.0.3:
+ resolution: {integrity: sha512-dxFtq+wscbU9faJaH8kIi98vvCPDbt+qg1g9GoG0os1PY3UvgY1Y2G06iZrZb1iVC9cyFfafwSY1IS+IQpRQ4w==}
+ dependencies:
+ css-selector-tokenizer: 0.7.3
+ generic-names: 1.0.3
+ icss-utils: 3.0.1
+ lodash: 4.17.21
+ postcss: 6.0.23
+ dev: true
+
+ /postcss-import/14.1.0_postcss@8.4.16:
+ resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+ dependencies:
+ postcss: 8.4.16
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.1
+ dev: false
+
+ /postcss-js/4.0.0_postcss@8.4.16:
+ resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.3.3
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.16
+ dev: false
+
+ /postcss-load-config/3.1.4_postcss@8.4.16:
+ resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
+ engines: {node: '>= 10'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+ dependencies:
+ lilconfig: 2.0.6
+ postcss: 8.4.16
+ yaml: 1.10.2
+
+ /postcss-nested/5.0.6_postcss@8.4.16:
+ resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+ dependencies:
+ postcss: 8.4.16
+ postcss-selector-parser: 6.0.10
+ dev: false
+
+ /postcss-selector-parser/6.0.10:
+ resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
+ engines: {node: '>=4'}
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ /postcss-value-parser/3.3.1:
+ resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==}
+ dev: true
+
+ /postcss-value-parser/4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+ dev: false
+
+ /postcss/6.0.23:
+ resolution: {integrity: sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==}
+ engines: {node: '>=4.0.0'}
+ dependencies:
+ chalk: 2.4.2
+ source-map: 0.6.1
+ supports-color: 5.5.0
+ dev: true
+
+ /postcss/8.4.16:
+ resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.4
+ picocolors: 1.0.0
+ source-map-js: 1.0.2
+
+ /prelude-ls/1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
+ /prettier-linter-helpers/1.0.0:
+ resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ fast-diff: 1.2.0
+ dev: true
+
+ /prettier/2.7.1:
+ resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ dev: true
+
+ /prr/1.0.1:
+ resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+ dev: true
+ optional: true
+
+ /punycode/2.1.1:
+ resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /queue-microtask/1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ /quick-lru/5.1.1:
+ resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
+ engines: {node: '>=10'}
+ dev: false
+
+ /read-cache/1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+ dependencies:
+ pify: 2.3.0
+ dev: false
+
+ /readdirp/3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+ dependencies:
+ picomatch: 2.3.1
+
+ /regexpp/3.2.0:
+ resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /reserved-words/0.1.2:
+ resolution: {integrity: sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==}
+ dev: true
+
+ /resolve-from/4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /resolve-url/0.2.1:
+ resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==}
+ deprecated: https://github.com/lydell/resolve-url#deprecated
+ dev: true
+
+ /resolve/1.22.1:
+ resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.10.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ /reusify/1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ /rimraf/3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+ dev: true
+
+ /rollup/2.78.1:
+ resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==}
+ engines: {node: '>=10.0.0'}
+ hasBin: true
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: true
+
+ /run-parallel/1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+
+ /safe-buffer/5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+ dev: true
+
+ /safer-buffer/2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ dev: true
+
+ /sass-loader/13.0.2_sass@1.54.8:
+ resolution: {integrity: sha512-BbiqbVmbfJaWVeOOAu2o7DhYWtcNmTfvroVgFXa6k2hHheMxNAeDHLNoDy/Q5aoaVlz0LH+MbMktKwm9vN/j8Q==}
+ engines: {node: '>= 14.15.0'}
+ peerDependencies:
+ fibers: '>= 3.1.0'
+ node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
+ sass: ^1.3.0
+ sass-embedded: '*'
+ webpack: ^5.0.0
+ peerDependenciesMeta:
+ fibers:
+ optional: true
+ node-sass:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ dependencies:
+ klona: 2.0.5
+ neo-async: 2.6.2
+ sass: 1.54.8
+ dev: true
+
+ /sass/1.54.8:
+ resolution: {integrity: sha512-ib4JhLRRgbg6QVy6bsv5uJxnJMTS2soVcCp9Y88Extyy13A8vV0G1fAwujOzmNkFQbR3LvedudAMbtuNRPbQww==}
+ engines: {node: '>=12.0.0'}
+ hasBin: true
+ dependencies:
+ chokidar: 3.5.3
+ immutable: 4.1.0
+ source-map-js: 1.0.2
+ dev: true
+
+ /sax/1.2.4:
+ resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
+ dev: true
+
+ /seemly/0.3.6:
+ resolution: {integrity: sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw==}
+ dev: false
+
+ /semver/5.7.1:
+ resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
+ hasBin: true
+ dev: true
+ optional: true
+
+ /semver/6.3.0:
+ resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
+ hasBin: true
+ dev: true
+
+ /semver/7.3.7:
+ resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
+ /shebang-command/2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+ dev: true
+
+ /shebang-regex/3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /slash/3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /source-map-js/1.0.2:
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+ engines: {node: '>=0.10.0'}
+
+ /source-map-resolve/0.5.3:
+ resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==}
+ deprecated: See https://github.com/lydell/source-map-resolve#deprecated
+ dependencies:
+ atob: 2.1.2
+ decode-uri-component: 0.2.0
+ resolve-url: 0.2.1
+ source-map-url: 0.4.1
+ urix: 0.1.0
+ dev: true
+
+ /source-map-url/0.4.1:
+ resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==}
+ deprecated: See https://github.com/lydell/source-map-url#deprecated
+ dev: true
+
+ /source-map/0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ /source-map/0.7.4:
+ resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /sourcemap-codec/1.4.8:
+ resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
+
+ /strip-ansi/6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+ dev: true
+
+ /strip-bom/3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /strip-json-comments/3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /stylus/0.54.8:
+ resolution: {integrity: sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==}
+ hasBin: true
+ dependencies:
+ css-parse: 2.0.0
+ debug: 3.1.0
+ glob: 7.2.3
+ mkdirp: 1.0.4
+ safer-buffer: 2.1.2
+ sax: 1.2.4
+ semver: 6.3.0
+ source-map: 0.7.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /supports-color/5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+ dependencies:
+ has-flag: 3.0.0
+ dev: true
+
+ /supports-color/7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+ dependencies:
+ has-flag: 4.0.0
+ dev: true
+
+ /supports-preserve-symlinks-flag/1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ /svg-tags/1.0.0:
+ resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
+ dev: true
+
+ /tailwindcss/3.1.8:
+ resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==}
+ engines: {node: '>=12.13.0'}
+ hasBin: true
+ dependencies:
+ arg: 5.0.2
+ chokidar: 3.5.3
+ color-name: 1.1.4
+ detective: 5.2.1
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.2.11
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ lilconfig: 2.0.6
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.0.0
+ postcss: 8.4.16
+ postcss-import: 14.1.0_postcss@8.4.16
+ postcss-js: 4.0.0_postcss@8.4.16
+ postcss-load-config: 3.1.4_postcss@8.4.16
+ postcss-nested: 5.0.6_postcss@8.4.16
+ postcss-selector-parser: 6.0.10
+ postcss-value-parser: 4.2.0
+ quick-lru: 5.1.1
+ resolve: 1.22.1
+ transitivePeerDependencies:
+ - ts-node
+ dev: false
+
+ /text-table/0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ dev: true
+
+ /to-fast-properties/2.0.0:
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+ engines: {node: '>=4'}
+
+ /to-regex-range/5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+
+ /treemate/0.3.11:
+ resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==}
+ dev: false
+
+ /tsconfig-paths/3.14.1:
+ resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==}
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.1
+ minimist: 1.2.6
+ strip-bom: 3.0.0
+ dev: true
+
+ /tslib/1.14.1:
+ resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
+ dev: true
+
+ /tslib/2.3.0:
+ resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
+ dev: false
+
+ /tslib/2.4.0:
+ resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
+ dev: true
+
+ /tsutils/3.21.0_typescript@4.8.2:
+ resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
+ engines: {node: '>= 6'}
+ peerDependencies:
+ typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
+ dependencies:
+ tslib: 1.14.1
+ typescript: 4.8.2
+ dev: true
+
+ /type-check/0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ dev: true
+
+ /type-fest/0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /typescript-plugin-css-modules/3.4.0_typescript@4.8.2:
+ resolution: {integrity: sha512-2MdjfSg4MGex1csCWRUwKD+MpgnvcvLLr9bSAMemU/QYGqBsXdez0cc06H/fFhLtRoKJjXg6PSTur3Gy1Umhpw==}
+ peerDependencies:
+ typescript: '>=3.0.0'
+ dependencies:
+ dotenv: 10.0.0
+ icss-utils: 5.1.0_postcss@8.4.16
+ less: 4.1.3
+ lodash.camelcase: 4.3.0
+ postcss: 8.4.16
+ postcss-filter-plugins: 3.0.1
+ postcss-icss-keyframes: 0.2.1
+ postcss-icss-selectors: 2.0.3
+ postcss-load-config: 3.1.4_postcss@8.4.16
+ reserved-words: 0.1.2
+ sass: 1.54.8
+ stylus: 0.54.8
+ tsconfig-paths: 3.14.1
+ typescript: 4.8.2
+ transitivePeerDependencies:
+ - supports-color
+ - ts-node
+ dev: true
+
+ /typescript/4.8.2:
+ resolution: {integrity: sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==}
+ engines: {node: '>=4.2.0'}
+ hasBin: true
+
+ /universalify/2.0.0:
+ resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
+ engines: {node: '>= 10.0.0'}
+ dev: true
+
+ /update-browserslist-db/1.0.7_browserslist@4.21.3:
+ resolution: {integrity: sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+ dependencies:
+ browserslist: 4.21.3
+ escalade: 3.1.1
+ picocolors: 1.0.0
+
+ /uri-js/4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.1.1
+ dev: true
+
+ /urix/0.1.0:
+ resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==}
+ deprecated: Please see https://github.com/lydell/urix#deprecated
+ dev: true
+
+ /util-deprecate/1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ /vdirs/0.1.8_vue@3.2.38:
+ resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==}
+ peerDependencies:
+ vue: ^3.0.11
+ dependencies:
+ evtd: 0.2.4
+ vue: 3.2.38
+ dev: false
+
+ /vfonts/0.0.3:
+ resolution: {integrity: sha512-nguyw8L6Un8eelg1vQ31vIU2ESxqid7EYmy8V+MDeMaHBqaRSkg3dTBToC1PR00D89UzS/SLkfYPnx0Wf23IQQ==}
+ dev: false
+
+ /vite-plugin-compression/0.5.1_vite@3.1.0:
+ resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
+ peerDependencies:
+ vite: '>=2.0.0'
+ dependencies:
+ chalk: 4.1.2
+ debug: 4.3.4
+ fs-extra: 10.1.0
+ vite: 3.1.0_sass@1.54.8
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /vite/3.1.0_sass@1.54.8:
+ resolution: {integrity: sha512-YBg3dUicDpDWFCGttmvMbVyS9ydjntwEjwXRj2KBFwSB8SxmGcudo1yb8FW5+M/G86aS8x828ujnzUVdsLjs9g==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ peerDependencies:
+ less: '*'
+ sass: '*'
+ stylus: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ less:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ terser:
+ optional: true
+ dependencies:
+ esbuild: 0.15.7
+ postcss: 8.4.16
+ resolve: 1.22.1
+ rollup: 2.78.1
+ sass: 1.54.8
+ optionalDependencies:
+ fsevents: 2.3.2
+ dev: true
+
+ /vooks/0.2.12_vue@3.2.38:
+ resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==}
+ peerDependencies:
+ vue: ^3.0.0
+ dependencies:
+ evtd: 0.2.4
+ vue: 3.2.38
+ dev: false
+
+ /vue-demi/0.13.11_vue@3.2.38:
+ resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+ dependencies:
+ vue: 3.2.38
+ dev: false
+
+ /vue-eslint-parser/9.0.3_eslint@8.23.0:
+ resolution: {integrity: sha512-yL+ZDb+9T0ELG4VIFo/2anAOz8SvBdlqEnQnvJ3M7Scq56DvtjY0VY88bByRZB0D4J0u8olBcfrXTVONXsh4og==}
+ engines: {node: ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: '>=6.0.0'
+ dependencies:
+ debug: 4.3.4
+ eslint: 8.23.0
+ eslint-scope: 7.1.1
+ eslint-visitor-keys: 3.3.0
+ espree: 9.4.0
+ esquery: 1.4.0
+ lodash: 4.17.21
+ semver: 7.3.7
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /vue-i18n/9.2.2_vue@3.2.38:
+ resolution: {integrity: sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ vue: ^3.0.0
+ dependencies:
+ '@intlify/core-base': 9.2.2
+ '@intlify/shared': 9.2.2
+ '@intlify/vue-devtools': 9.2.2
+ '@vue/devtools-api': 6.2.1
+ vue: 3.2.38
+ dev: false
+
+ /vue-router/4.1.5_vue@3.2.38:
+ resolution: {integrity: sha512-IsvoF5D2GQ/EGTs/Th4NQms9gd2NSqV+yylxIyp/OYp8xOwxmU8Kj/74E9DTSYAyH5LX7idVUngN3JSj1X4xcQ==}
+ peerDependencies:
+ vue: ^3.2.0
+ dependencies:
+ '@vue/devtools-api': 6.2.1
+ vue: 3.2.38
+ dev: false
+
+ /vue-tsc/0.40.9_typescript@4.8.2:
+ resolution: {integrity: sha512-GnfwngCgbUvFgs+vaPesrJB76yoX1W/DSQZqoQ+pArjZ9+EFCFkqMpihE1D8W5p/tgTCAAPr/3Sfz/jtTiYGaA==}
+ hasBin: true
+ peerDependencies:
+ typescript: '*'
+ dependencies:
+ '@volar/vue-language-core': 0.40.9
+ '@volar/vue-typescript': 0.40.9
+ typescript: 4.8.2
+ dev: true
+
+ /vue/3.2.38:
+ resolution: {integrity: sha512-hHrScEFSmDAWL0cwO4B6WO7D3sALZPbfuThDsGBebthrNlDxdJZpGR3WB87VbjpPh96mep1+KzukYEhpHDFa8Q==}
+ dependencies:
+ '@vue/compiler-dom': 3.2.38
+ '@vue/compiler-sfc': 3.2.38
+ '@vue/runtime-dom': 3.2.38
+ '@vue/server-renderer': 3.2.38_vue@3.2.38
+ '@vue/shared': 3.2.38
+
+ /vueuc/0.4.48_vue@3.2.38:
+ resolution: {integrity: sha512-dQTBLxCzfaPuzD3c4/dIxAULtnyY+xwdotCRFUDgf0DJiwuR3tI+txJ9K8uJKmaHwc1JDUVqhRAj9Jd/pvInWg==}
+ peerDependencies:
+ vue: ^3.0.11
+ dependencies:
+ '@css-render/vue3-ssr': 0.15.11_vue@3.2.38
+ '@juggle/resize-observer': 3.4.0
+ css-render: 0.15.11
+ evtd: 0.2.4
+ seemly: 0.3.6
+ vdirs: 0.1.8_vue@3.2.38
+ vooks: 0.2.12_vue@3.2.38
+ vue: 3.2.38
+ dev: false
+
+ /which/2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+ dev: true
+
+ /word-wrap/1.2.3:
+ resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /wrappy/1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ dev: true
+
+ /xml-name-validator/4.0.0:
+ resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
+ engines: {node: '>=12'}
+ dev: true
+
+ /xtend/4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+ dev: false
+
+ /yallist/4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ dev: true
+
+ /yaml/1.10.2:
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
+ engines: {node: '>= 6'}
+
+ /yocto-queue/0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+ dev: true
+
+ /zrender/5.3.2:
+ resolution: {integrity: sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==}
+ dependencies:
+ tslib: 2.3.0
+ dev: false
diff --git a/seatunnel-ui/postcss.config.js b/seatunnel-ui/postcss.config.js
new file mode 100644
index 0000000..6ae9aea
--- /dev/null
+++ b/seatunnel-ui/postcss.config.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {}
+ }
+}
\ No newline at end of file
diff --git a/seatunnel-ui/src/App.tsx b/seatunnel-ui/src/App.tsx
new file mode 100644
index 0000000..4c3e60b
--- /dev/null
+++ b/seatunnel-ui/src/App.tsx
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, computed } from 'vue'
+import {
+ NConfigProvider,
+ NMessageProvider,
+ darkTheme,
+ dateZhCN,
+ dateEnUS,
+ zhCN,
+ enUS
+} from 'naive-ui'
+import { useThemeStore } from '@/store/theme'
+import { useLocalesStore } from '@/store/locale'
+import themeList from '@/themes'
+import type { GlobalThemeOverrides } from 'naive-ui'
+
+const App = defineComponent({
+ setup() {
+ const themeStore = useThemeStore()
+ const currentTheme = computed(() =>
+ themeStore.darkTheme ? darkTheme : undefined
+ )
+ const localesStore = useLocalesStore()
+
+ return {
+ currentTheme,
+ localesStore
+ }
+ },
+ render() {
+ const themeOverrides: GlobalThemeOverrides =
+ themeList[this.currentTheme ? 'dark' : 'light']
+
+ return (
+ <NConfigProvider
+ theme={this.currentTheme}
+ theme-overrides={themeOverrides}
+ date-locale={
+ String(this.localesStore.getLocales) === 'zh_CN' ? dateZhCN : dateEnUS
+ }
+ locale={String(this.localesStore.getLocales) === 'zh_CN' ? zhCN : enUS}
+ >
+ <NMessageProvider>
+ <router-view />
+ </NMessageProvider>
+ </NConfigProvider>
+ )
+ }
+})
+
+export default App
diff --git a/seatunnel-ui/src/components/chart/index.ts b/seatunnel-ui/src/components/chart/index.ts
new file mode 100644
index 0000000..944c5ba
--- /dev/null
+++ b/seatunnel-ui/src/components/chart/index.ts
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { getCurrentInstance, onMounted, onBeforeUnmount, watch } from 'vue'
+import { useThemeStore } from '@/store/theme'
+import { throttle } from 'echarts'
+import { useI18n } from 'vue-i18n'
+import type { Ref } from 'vue'
+import type { ECharts } from 'echarts'
+import type { ECBasicOption } from 'echarts/types/dist/shared'
+
+function initChart<Opt extends ECBasicOption>(
+ domRef: Ref<HTMLDivElement | null>,
+ option: Opt
+): ECharts | null {
+ let chart: ECharts | null = null
+ const themeStore = useThemeStore()
+ const { locale } = useI18n()
+ const globalProperties =
+ getCurrentInstance()?.appContext.config.globalProperties
+
+ option['backgroundColor'] = ''
+
+ const init = () => {
+ chart?.dispose()
+ chart = globalProperties?.echarts.init(
+ domRef.value,
+ themeStore.darkTheme ? 'macarons' : 'dark-bold'
+ )
+ chart && chart.setOption(option)
+ }
+
+ const resize = throttle(() => {
+ chart && chart.resize()
+ }, 20)
+
+ watch(
+ () => themeStore.darkTheme,
+ () => {
+ init()
+ }
+ )
+
+ watch(
+ () => locale.value,
+ () => {
+ init()
+ }
+ )
+
+ watch(
+ () => option,
+ () => {
+ init()
+ },
+ {
+ deep: true
+ }
+ )
+
+ onMounted(() => {
+ init()
+ addEventListener('resize', resize)
+ })
+
+ onBeforeUnmount(() => {
+ removeEventListener('resize', resize)
+ })
+
+ return chart
+}
+
+export default initChart
diff --git a/seatunnel-ui/src/components/log/index.tsx b/seatunnel-ui/src/components/log/index.tsx
new file mode 100644
index 0000000..db6ceb2
--- /dev/null
+++ b/seatunnel-ui/src/components/log/index.tsx
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { NButton, NInput, NInputGroup, NLog, NSpace } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+
+const Log = defineComponent({
+ setup() {
+ const { t } = useI18n()
+
+ return { t }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NInputGroup>
+ <NInput placeholder={this.t('log.please_select_log')} />
+ <NButton ghost>{this.t('log.search')}</NButton>
+ </NInputGroup>
+ <NLog rows={30} log={'test'} class={['py-5', 'px-3', 'bg-gray-50']} />
+ </NSpace>
+ )
+ }
+})
+
+export default Log
diff --git a/seatunnel-ui/src/components/modal/index.tsx b/seatunnel-ui/src/components/modal/index.tsx
new file mode 100644
index 0000000..4bf22cb
--- /dev/null
+++ b/seatunnel-ui/src/components/modal/index.tsx
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, PropType, renderSlot } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NModal, NCard, NButton, NSpace } from 'naive-ui'
+
+const props = {
+ show: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ title: {
+ type: String as PropType<string>,
+ required: true
+ },
+ cancelText: {
+ type: String as PropType<string>
+ },
+ cancelShow: {
+ type: Boolean as PropType<boolean>,
+ default: true
+ },
+ confirmText: {
+ type: String as PropType<string>
+ },
+ confirmClassName: {
+ type: String as PropType<string>,
+ default: ''
+ },
+ cancelClassName: {
+ type: String as PropType<string>,
+ default: ''
+ },
+ confirmDisabled: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ confirmLoading: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ }
+}
+
+const Modal = defineComponent({
+ name: 'Modal',
+ props,
+ emits: ['cancel', 'confirm'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+
+ const onCancel = () => {
+ ctx.emit('cancel')
+ }
+
+ const onConfirm = () => {
+ ctx.emit('confirm')
+ }
+
+ return { t, onCancel, onConfirm }
+ },
+ render() {
+ const { $slots, t, onCancel, onConfirm, confirmDisabled, confirmLoading } =
+ this
+
+ return (
+ <NModal
+ v-model={[this.show, 'show']}
+ mask-closable={false}
+ style={{ width: '600px' }}
+ >
+ <NCard title={this.title} contentStyle={{ overflowY: 'auto' }}>
+ {{
+ default: () => renderSlot($slots, 'default'),
+ footer: () => (
+ <NSpace justify='end'>
+ {this.cancelShow && (
+ <NButton quaternary size='small' onClick={onCancel}>
+ {this.cancelText || t('modal.cancel')}
+ </NButton>
+ )}
+ <NButton
+ size='small'
+ onClick={onConfirm}
+ disabled={confirmDisabled}
+ loading={confirmLoading}
+ >
+ {this.confirmText || t('modal.confirm')}
+ </NButton>
+ </NSpace>
+ )
+ }}
+ </NCard>
+ </NModal>
+ )
+ }
+})
+
+export default Modal
diff --git a/seatunnel-ui/src/components/monaco-editor/index.tsx b/seatunnel-ui/src/components/monaco-editor/index.tsx
new file mode 100644
index 0000000..a67dcb3
--- /dev/null
+++ b/seatunnel-ui/src/components/monaco-editor/index.tsx
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ defineComponent,
+ onMounted,
+ onUnmounted,
+ PropType,
+ ref,
+ watch
+} from 'vue'
+import { useFormItem } from 'naive-ui/es/_mixins'
+import { call } from 'naive-ui/es/_utils'
+import { useThemeStore } from '@/store/theme'
+import * as monaco from 'monaco-editor'
+import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
+import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
+import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
+import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
+import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
+import type { MaybeArray, OnUpdateValue, OnUpdateValueImpl } from './types'
+
+const props = {
+ value: {
+ type: String as PropType<string>,
+ default: ''
+ },
+ defaultValue: {
+ type: String as PropType<string>
+ },
+ 'onUpdate:value': [Function, Array] as PropType<MaybeArray<OnUpdateValue>>,
+ onUpdateValue: [Function, Array] as PropType<MaybeArray<OnUpdateValue>>,
+ language: {
+ type: String as PropType<string>,
+ default: 'shell'
+ },
+ readOnly: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ options: {
+ type: Object,
+ default: () => {}
+ }
+}
+
+// @ts-ignore
+window.MonacoEnvironment = {
+ getWorker(_: any, label: string) {
+ if (label === 'json') {
+ return new jsonWorker()
+ }
+ if (['css', 'scss', 'less'].includes(label)) {
+ return new cssWorker()
+ }
+ if (['html', 'handlebars', 'razor'].includes(label)) {
+ return new htmlWorker()
+ }
+ if (['typescript', 'javascript'].includes(label)) {
+ return new tsWorker()
+ }
+ return new editorWorker()
+ }
+}
+
+export default defineComponent({
+ name: 'MonacoEditor',
+ props,
+ emits: ['change', 'focus', 'blur'],
+ setup(props, ctx) {
+ let editor = null as monaco.editor.IStandaloneCodeEditor | null
+ const themeStore = useThemeStore()
+ const monacoEditorThemeRef = ref(themeStore.darkTheme ? 'vs-dark' : 'vs')
+ const editorRef = ref()
+ const getValue = () => editor?.getValue()
+ const formItem = useFormItem({})
+
+ const initMonacoEditor = () => {
+ const dom = editorRef.value
+ if (dom) {
+ editor = monaco.editor.create(dom, {
+ ...props.options,
+ readOnly: formItem.mergedDisabledRef.value || props.options?.readOnly,
+ value: props.defaultValue ?? props.value,
+ language: props.language,
+ automaticLayout: true,
+ theme: monacoEditorThemeRef.value
+ })
+ editor.onDidChangeModelContent(() => {
+ const { onUpdateValue, 'onUpdate:value': _onUpdateValue } = props
+ const value = editor?.getValue() || ''
+
+ if (onUpdateValue) call(onUpdateValue as OnUpdateValueImpl, value)
+ if (_onUpdateValue) call(_onUpdateValue as OnUpdateValueImpl, value)
+ ctx.emit('change', value)
+
+ formItem.nTriggerFormChange()
+ formItem.nTriggerFormInput()
+ })
+ editor.onDidBlurEditorWidget(() => {
+ ctx.emit('blur')
+ formItem.nTriggerFormBlur()
+ })
+ editor.onDidFocusEditorWidget(() => {
+ ctx.emit('focus')
+ formItem.nTriggerFormFocus()
+ })
+ }
+ }
+
+ onMounted(() => initMonacoEditor())
+
+ onUnmounted(() => {
+ editor?.dispose()
+ })
+
+ watch(
+ () => props.value,
+ (val) => {
+ if (val !== getValue()) {
+ editor?.setValue(val)
+ }
+ }
+ )
+
+ watch(
+ () => formItem.mergedDisabledRef.value,
+ (value) => {
+ editor?.updateOptions({ readOnly: value })
+ }
+ )
+
+ watch(
+ () => themeStore.darkTheme,
+ () => {
+ editor?.dispose()
+ monacoEditorThemeRef.value = themeStore.darkTheme ? 'vs-dark' : 'vs'
+ initMonacoEditor()
+ }
+ )
+
+ ctx.expose({ getValue })
+
+ return { editorRef }
+ },
+ render() {
+ return (
+ <div
+ ref='editorRef'
+ style={{
+ height: '300px',
+ width: '100%',
+ border: '1px solid #eee'
+ }}
+ />
+ )
+ }
+})
diff --git a/seatunnel-ui/src/components/monaco-editor/types.ts b/seatunnel-ui/src/components/monaco-editor/types.ts
new file mode 100644
index 0000000..830c07a
--- /dev/null
+++ b/seatunnel-ui/src/components/monaco-editor/types.ts
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import type { MaybeArray } from 'naive-ui/es/_utils'
+
+type OnUpdateValue = <T extends string>(value: T) => void
+type OnUpdateValueImpl = (value: string) => void
+
+export { MaybeArray, OnUpdateValue, OnUpdateValueImpl }
diff --git a/seatunnel-ui/src/env.d.ts b/seatunnel-ui/src/env.d.ts
new file mode 100644
index 0000000..5189373
--- /dev/null
+++ b/seatunnel-ui/src/env.d.ts
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { DefineComponent } from 'vue'
+
+declare module '*.vue' {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
+
+declare global {
+ interface Window {
+ $message: any
+ }
+}
+
+declare module '*.png'
+declare module '*.jpg'
+declare module '*.jpeg'
diff --git a/seatunnel-ui/src/index.css b/seatunnel-ui/src/index.css
new file mode 100644
index 0000000..4b0aa3d
--- /dev/null
+++ b/seatunnel-ui/src/index.css
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+@tailwind screens;
+@tailwind fonts;
+@tailwind colors;
\ No newline at end of file
diff --git a/seatunnel-ui/src/layouts/dashboard/header/index.tsx b/seatunnel-ui/src/layouts/dashboard/header/index.tsx
new file mode 100644
index 0000000..f732f54
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/index.tsx
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { NSpace } from 'naive-ui'
+import Logo from './logo'
+import Menu from './menu'
+import Setting from './setting'
+import User from './user'
+
+const Header = defineComponent({
+ setup() {},
+ render() {
+ return (
+ <NSpace justify='space-between' class='h-16 border-b border-gray-200'>
+ <NSpace>
+ <Logo />
+ <Menu />
+ </NSpace>
+ <NSpace>
+ <Setting />
+ <User />
+ </NSpace>
+ </NSpace>
+ )
+ }
+})
+
+export default Header
diff --git a/seatunnel-ui/src/layouts/dashboard/header/logo/index.tsx b/seatunnel-ui/src/layouts/dashboard/header/logo/index.tsx
new file mode 100644
index 0000000..361345c
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/logo/index.tsx
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { NSpace } from 'naive-ui'
+
+const Logo = defineComponent({
+ setup() {},
+ render() {
+ return (
+ <NSpace justify='center' align='center' class='h-16 w-48'>
+ <h2 class='text-2xl font-bold'>SeaTunnel</h2>
+ </NSpace>
+ )
+ }
+})
+
+export default Logo
diff --git a/seatunnel-ui/src/layouts/dashboard/header/menu/index.tsx b/seatunnel-ui/src/layouts/dashboard/header/menu/index.tsx
new file mode 100644
index 0000000..2b54ab3
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/menu/index.tsx
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, toRefs } from 'vue'
+import { NMenu, NSpace } from 'naive-ui'
+import { useRouter } from 'vue-router'
+import { useMenu } from './use-menu'
+
+const Menu = defineComponent({
+ setup() {
+ const { state } = useMenu()
+ const router = useRouter()
+
+ const handleMenuClick = (key: string) => {
+ router.push({ path: `/${key}` })
+ }
+
+ return {
+ ...toRefs(state),
+ handleMenuClick
+ }
+ },
+ render() {
+ return (
+ <NSpace align='center' class='h-16'>
+ <NMenu
+ mode='horizontal'
+ options={this.menuOptions}
+ onUpdateValue={this.handleMenuClick}
+ />
+ </NSpace>
+ )
+ }
+})
+
+export default Menu
diff --git a/seatunnel-ui/src/layouts/dashboard/header/menu/use-menu.ts b/seatunnel-ui/src/layouts/dashboard/header/menu/use-menu.ts
new file mode 100644
index 0000000..f3dae99
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/menu/use-menu.ts
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive, h } from 'vue'
+import { NEllipsis } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+
+export function useMenu() {
+ const { t } = useI18n()
+
+ const menuOptions = [
+ {
+ label: () => h(NEllipsis, null, { default: () => t('menu.data_pipes') }),
+ key: 'data-pipes'
+ },
+ {
+ label: () => h(NEllipsis, null, { default: () => t('menu.jobs') }),
+ key: 'jobs'
+ },
+ {
+ label: () => h(NEllipsis, null, { default: () => t('menu.tasks') }),
+ key: 'tasks'
+ }
+ ]
+
+ const state = reactive({
+ menuOptions
+ })
+
+ return { state }
+}
diff --git a/seatunnel-ui/src/layouts/dashboard/header/setting/index.tsx b/seatunnel-ui/src/layouts/dashboard/header/setting/index.tsx
new file mode 100644
index 0000000..291740d
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/setting/index.tsx
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, toRefs } from 'vue'
+import { NIcon, NSpace, NDropdown } from 'naive-ui'
+import { SettingOutlined } from '@vicons/antd'
+import { useSettingDropdown } from './use-setting-dropdown'
+
+const Setting = defineComponent({
+ setup() {
+ const { state, handleSelect } = useSettingDropdown()
+
+ return { ...toRefs(state), handleSelect }
+ },
+ render() {
+ return (
+ <NSpace
+ align='center'
+ justify='center'
+ class='h-16 w-12'
+ style={{ cursor: 'pointer' }}
+ >
+ <NDropdown
+ trigger='click'
+ options={this.dropdownOptions}
+ onSelect={this.handleSelect}
+ >
+ <NIcon size='20'>
+ <SettingOutlined />
+ </NIcon>
+ </NDropdown>
+ </NSpace>
+ )
+ }
+})
+
+export default Setting
diff --git a/seatunnel-ui/src/layouts/dashboard/header/setting/use-setting-dropdown.ts b/seatunnel-ui/src/layouts/dashboard/header/setting/use-setting-dropdown.ts
new file mode 100644
index 0000000..157f04c
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/setting/use-setting-dropdown.ts
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { useI18n } from 'vue-i18n'
+import { reactive, h } from 'vue'
+import { useRouter } from 'vue-router'
+import type { Router } from 'vue-router'
+
+export function useSettingDropdown() {
+ const { t } = useI18n()
+ const router: Router = useRouter()
+
+ const dropdownOptions = [
+ {
+ key: 'header',
+ type: 'render',
+ render: () =>
+ h('h3', { class: ['py-1.5', 'px-3', 'font-medium'] }, t('menu.manage'))
+ },
+ {
+ key: 'header-divider',
+ type: 'divider'
+ },
+ { key: 'user-manage', label: t('menu.user_manage') }
+ ]
+
+ const state = reactive({
+ dropdownOptions
+ })
+
+ const handleSelect = (key: string) => {
+ if (key === 'user-manage') {
+ router.push({ path: '/user-manage' })
+ }
+ }
+
+ return { state, handleSelect }
+}
diff --git a/seatunnel-ui/src/layouts/dashboard/header/user/index.tsx b/seatunnel-ui/src/layouts/dashboard/header/user/index.tsx
new file mode 100644
index 0000000..582b744
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/user/index.tsx
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, toRefs } from 'vue'
+import { NSpace, NDropdown } from 'naive-ui'
+import { useUserDropdown } from './use-user-dropdown'
+
+const User = defineComponent({
+ setup() {
+ const { state, handleSelect } = useUserDropdown()
+
+ return { ...toRefs(state), handleSelect }
+ },
+ render() {
+ return (
+ <NSpace
+ justify='center'
+ align='center'
+ class='h-16 w-12 mr-2'
+ style={{ cursor: 'pointer' }}
+ >
+ <NDropdown
+ trigger='click'
+ options={this.dropdownOptions}
+ onSelect={this.handleSelect}
+ >
+ <img
+ class='h-10 w-10 rounded-full'
+ src='https://avatars.githubusercontent.com/u/19239641?s=64&v=4'
+ alt=''
+ />
+ </NDropdown>
+ </NSpace>
+ )
+ }
+})
+
+export default User
diff --git a/seatunnel-ui/src/layouts/dashboard/header/user/use-user-dropdown.ts b/seatunnel-ui/src/layouts/dashboard/header/user/use-user-dropdown.ts
new file mode 100644
index 0000000..0c88b32
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/header/user/use-user-dropdown.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useRouter } from 'vue-router'
+import { userLogout } from '@/service/user'
+import { useUserStore } from '@/store/user'
+import type { Router } from 'vue-router'
+
+export function useUserDropdown() {
+ const router: Router = useRouter()
+ const { t } = useI18n()
+ const userStore = useUserStore()
+
+ const dropdownOptions = [
+ { key: 'help', label: t('menu.help') },
+ { key: 'logout', label: t('menu.logout') }
+ ]
+
+ const state = reactive({
+ dropdownOptions
+ })
+
+ const handleSelect = (key: string) => {
+ if (key === 'help') {
+ window.open('http://seatunnel.incubator.apache.org/versions/')
+ } else if (key === 'logout') {
+ userLogout().then(() => {
+ userStore.setUserInfo({})
+ router.push({ path: '/login' })
+ })
+ }
+ }
+
+ return { state, handleSelect }
+}
diff --git a/seatunnel-ui/src/layouts/dashboard/index.tsx b/seatunnel-ui/src/layouts/dashboard/index.tsx
new file mode 100644
index 0000000..2a0c245
--- /dev/null
+++ b/seatunnel-ui/src/layouts/dashboard/index.tsx
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { NLayout, NLayoutHeader, NLayoutContent, useMessage } from 'naive-ui'
+import Header from './header'
+
+const Dashboard = defineComponent({
+ setup() {
+ window.$message = useMessage()
+ },
+ render() {
+ return (
+ <NLayout>
+ <NLayoutHeader>
+ <Header />
+ </NLayoutHeader>
+ <NLayoutContent>
+ <router-view class='px-32 py-12' />
+ </NLayoutContent>
+ </NLayout>
+ )
+ }
+})
+
+export default Dashboard
diff --git a/seatunnel-ui/src/locales/en_US/data-pipes.ts b/seatunnel-ui/src/locales/en_US/data-pipes.ts
new file mode 100644
index 0000000..3bf6339
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/data-pipes.ts
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ data_pipes: 'Data Pipes',
+ create: 'Create',
+ name: 'Name',
+ state: 'State',
+ executed_time: 'Executed Time',
+ modification_time: 'Modification Time',
+ operation: 'Operation',
+ succeed: 'Succeed',
+ running: 'Running',
+ failed: 'Failed',
+ killed: 'Killed',
+ un_start: 'Un Start',
+ execute: 'Execute',
+ edit: 'Edit',
+ publish: 'Publish',
+ delete: 'Delete',
+ save: 'Save',
+ cancel: 'Cancel',
+ script: 'Script',
+ kill: 'Kill',
+ stop: 'Stop',
+ configuration: 'Configuration',
+ run_log: 'Run Log',
+ add: 'Add',
+ key: 'Key',
+ value: 'Value',
+ engine_parameter: 'Engine Parameter',
+ self_defined_parameter: 'Self Defined Parameter',
+ name_tips: 'Required fields,number, letter case, 100 characters',
+ overview: 'Overview',
+ input_metrics: 'Input Metrics',
+ historical_run_logs: 'Historical Run Logs',
+ bytes_per_second: 'Bytes Per Second',
+ total_bytes: 'Total Bytes',
+ record_per_second: 'Record Per Second',
+ total_records: 'Total Records',
+ output_metrics: 'Output Metrics',
+ end_time: 'End Time',
+ execute_time: 'Execute Time',
+ data_pipes_delete_tips:
+ 'Whether to delete the data Pipe,It cannot be restored after being deleted.',
+ data_pipes_publish_tips: 'Whether to Publish the data pipe.',
+ model_validate_tips: 'Required Fields'
+}
diff --git a/seatunnel-ui/src/locales/en_US/index.ts b/seatunnel-ui/src/locales/en_US/index.ts
new file mode 100644
index 0000000..4c71c78
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/index.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import login from '@/locales/en_US/login'
+import menu from '@/locales/en_US/menu'
+import modal from '@/locales/en_US/modal'
+import user_manage from '@/locales/en_US/user-manage'
+import data_pipes from '@/locales/en_US/data-pipes'
+import log from '@/locales/en_US/log'
+import jobs from '@/locales/en_US/jobs'
+import tasks from '@/locales/en_US/tasks'
+
+export default {
+ login,
+ menu,
+ modal,
+ user_manage,
+ data_pipes,
+ log,
+ jobs,
+ tasks
+}
diff --git a/seatunnel-ui/src/locales/en_US/jobs.ts b/seatunnel-ui/src/locales/en_US/jobs.ts
new file mode 100644
index 0000000..07cae2a
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/jobs.ts
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ jobs: 'Jobs',
+ search: 'Search',
+ data_pipe_name: 'Data Pipe Name',
+ plan: 'Plan',
+ create_date: 'Create Date',
+ publish: 'Publish',
+ operation: 'Operation',
+ executed_immediately: 'Executed Immediately',
+ stop_plan: 'Stop Plan'
+}
diff --git a/seatunnel-ui/src/locales/en_US/log.ts b/seatunnel-ui/src/locales/en_US/log.ts
new file mode 100644
index 0000000..8f1d47d
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/log.ts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ please_select_log: 'Please select log',
+ search: 'Search'
+}
diff --git a/seatunnel-ui/src/locales/en_US/login.ts b/seatunnel-ui/src/locales/en_US/login.ts
new file mode 100644
index 0000000..1261d10
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/login.ts
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ login_to_sea_tunnel: 'Login To SeaTunnel',
+ login: 'Login',
+ username: 'Username',
+ password: 'Password',
+ username_tips: 'Please input username',
+ password_tips: 'Please input password'
+}
diff --git a/seatunnel-ui/src/locales/en_US/menu.ts b/seatunnel-ui/src/locales/en_US/menu.ts
new file mode 100644
index 0000000..722579a
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/menu.ts
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ data_pipes: 'Data Pipes',
+ jobs: 'Jobs',
+ manage: 'Manage',
+ user_manage: 'User Manage',
+ help: 'Help',
+ logout: 'Logout',
+ tasks: 'Tasks'
+}
diff --git a/seatunnel-ui/src/locales/en_US/modal.ts b/seatunnel-ui/src/locales/en_US/modal.ts
new file mode 100644
index 0000000..3c17d1d
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/modal.ts
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ cancel: 'Cancel',
+ confirm: 'Confirm'
+}
diff --git a/seatunnel-ui/src/locales/en_US/tasks.ts b/seatunnel-ui/src/locales/en_US/tasks.ts
new file mode 100644
index 0000000..4031ae0
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/tasks.ts
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ tasks: 'Tasks',
+ search: 'Search',
+ tasks_name: 'Tasks Name',
+ success: 'Success',
+ fail: 'Fail',
+ running: 'Running',
+ task_name: 'Task Name',
+ state: 'State',
+ run_frequency: 'Run Frequency',
+ once: 'Once',
+ crontab: 'Crontab',
+ next_run: 'Next Run',
+ last_run: 'Last Run',
+ last_total_bytes: 'Last Total Bytes',
+ last_total_records: 'Last Total Records',
+ rerun: 'Rerun',
+ kill: 'Kill',
+ view_log: 'View Log'
+}
diff --git a/seatunnel-ui/src/locales/en_US/user-manage.ts b/seatunnel-ui/src/locales/en_US/user-manage.ts
new file mode 100644
index 0000000..e3b9561
--- /dev/null
+++ b/seatunnel-ui/src/locales/en_US/user-manage.ts
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {
+ user_manage: 'User Manage',
+ create: 'Create',
+ username: 'Username',
+ status: 'Status',
+ create_time: 'Create Time',
+ update_time: 'Update Time',
+ operation: 'Operation',
+ enable: 'Enable',
+ disable: 'Disable',
+ edit: 'Edit',
+ delete: 'Delete',
+ active: 'Active',
+ inactive: 'Inactive',
+ password: 'Password',
+ model_validate_tips: 'Required Fields',
+ username_tips: 'Required fields, number, letter case, 50 characters',
+ password_tips: 'Required fields, number, letter case, 6 characters',
+ user_delete_tips:
+ 'Whether to delete the user? It cannot be restored after being deleted.'
+}
diff --git a/seatunnel-ui/src/locales/index.ts b/seatunnel-ui/src/locales/index.ts
new file mode 100644
index 0000000..0f26f85
--- /dev/null
+++ b/seatunnel-ui/src/locales/index.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createI18n } from 'vue-i18n'
+import zh_CN from './zh_CN'
+import en_US from './en_US'
+
+const i18n = createI18n({
+ legacy: false,
+ globalInjection: true,
+ locale: 'en_US',
+ messages: {
+ zh_CN,
+ en_US
+ }
+})
+
+export default i18n
diff --git a/seatunnel-ui/src/locales/zh_CN/index.ts b/seatunnel-ui/src/locales/zh_CN/index.ts
new file mode 100644
index 0000000..39626a3
--- /dev/null
+++ b/seatunnel-ui/src/locales/zh_CN/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default {}
diff --git a/seatunnel-ui/src/main.ts b/seatunnel-ui/src/main.ts
new file mode 100644
index 0000000..c648237
--- /dev/null
+++ b/seatunnel-ui/src/main.ts
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App'
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
+import i18n from '@/locales'
+import router from './router'
+import utils from '@/utils'
+import './index.css'
+
+const meta = document.createElement('meta')
+meta.name = 'naive-ui-style'
+document.head.appendChild(meta)
+
+const app = createApp(App)
+const pinia = createPinia()
+
+pinia.use(piniaPluginPersistedstate)
+app.config.globalProperties.trim = utils.trim
+
+app.use(router)
+app.use(pinia)
+app.use(i18n)
+app.mount('#app')
diff --git a/seatunnel-ui/src/router/data-pipes.ts b/seatunnel-ui/src/router/data-pipes.ts
new file mode 100644
index 0000000..365d7bc
--- /dev/null
+++ b/seatunnel-ui/src/router/data-pipes.ts
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import utils from '@/utils'
+import type { Component } from 'vue'
+
+const modules = import.meta.glob('/src/views/**/**.tsx')
+const components: { [key: string]: Component } = utils.mapping(modules)
+
+export default {
+ path: '/data-pipes',
+ name: 'data-pipes',
+ meta: {
+ title: 'data-pipes'
+ },
+ redirect: { name: 'data-pipes-list' },
+ component: () => import('@/layouts/dashboard'),
+ children: [
+ {
+ path: '/data-pipes/list',
+ name: 'data-pipes-list',
+ component: components['data-pipes-list'],
+ meta: {
+ title: 'data-pipes-list'
+ }
+ },
+ {
+ path: '/data-pipes/:dataPipeCode',
+ name: 'data-pipes-detail',
+ component: components['data-pipes-detail'],
+ meta: {
+ title: 'data-pipes-detail'
+ }
+ },
+ {
+ path: '/data-pipes/:dataPipeCode/edit',
+ name: 'data-pipes-edit',
+ component: components['data-pipes-edit'],
+ meta: {
+ title: 'data-pipes-edit'
+ }
+ },
+ {
+ path: '/data-pipes/create',
+ name: 'data-pipes-create',
+ component: components['data-pipes-create'],
+ meta: {
+ title: 'data-pipes-create'
+ }
+ }
+ ]
+}
diff --git a/seatunnel-ui/src/router/index.ts b/seatunnel-ui/src/router/index.ts
new file mode 100644
index 0000000..188a9f4
--- /dev/null
+++ b/seatunnel-ui/src/router/index.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { createRouter, createWebHistory } from 'vue-router'
+import routes from './routes'
+import NProgress from 'nprogress'
+import 'nprogress/nprogress.css'
+
+const router = createRouter({
+ history: createWebHistory('/'),
+ routes
+})
+
+router.afterEach(() => {
+ NProgress.done()
+})
+
+export default router
diff --git a/seatunnel-ui/src/router/jobs.ts b/seatunnel-ui/src/router/jobs.ts
new file mode 100644
index 0000000..24c21cb
--- /dev/null
+++ b/seatunnel-ui/src/router/jobs.ts
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import utils from '@/utils'
+import type { Component } from 'vue'
+
+const modules = import.meta.glob('/src/views/**/**.tsx')
+const components: { [key: string]: Component } = utils.mapping(modules)
+
+export default {
+ path: '/jobs',
+ name: 'jobs',
+ meta: {
+ title: 'jobs'
+ },
+ redirect: { name: 'jobs-list' },
+ component: () => import('@/layouts/dashboard'),
+ children: [
+ {
+ path: '/jobs/list',
+ name: 'jobs-list',
+ component: components['jobs-list'],
+ meta: {
+ title: 'jobs-list'
+ }
+ }
+ ]
+}
diff --git a/seatunnel-ui/src/router/routes.ts b/seatunnel-ui/src/router/routes.ts
new file mode 100644
index 0000000..1784f7c
--- /dev/null
+++ b/seatunnel-ui/src/router/routes.ts
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import utils from '@/utils'
+import dataPipes from '@/router/data-pipes'
+import jobs from '@/router/jobs'
+import tasks from '@/router/tasks'
+import userManage from '@/router/user-manage'
+import type { RouteRecordRaw } from 'vue-router'
+import type { Component } from 'vue'
+
+const modules = import.meta.glob('/src/views/**/**.tsx')
+const components: { [key: string]: Component } = utils.mapping(modules)
+
+const basePage: RouteRecordRaw[] = [dataPipes, jobs, tasks, userManage]
+
+const loginPage: RouteRecordRaw[] = [
+ {
+ path: '/login',
+ name: 'login',
+ component: components['login'],
+ meta: {
+ auth: []
+ }
+ }
+]
+
+const routes: RouteRecordRaw[] = [...basePage, ...loginPage]
+
+export default routes
diff --git a/seatunnel-ui/src/router/tasks.ts b/seatunnel-ui/src/router/tasks.ts
new file mode 100644
index 0000000..8e1dd71
--- /dev/null
+++ b/seatunnel-ui/src/router/tasks.ts
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import utils from '@/utils'
+import type { Component } from 'vue'
+
+const modules = import.meta.glob('/src/views/**/**.tsx')
+const components: { [key: string]: Component } = utils.mapping(modules)
+
+export default {
+ path: '/tasks',
+ name: 'tasks',
+ meta: {
+ title: 'tasks'
+ },
+ redirect: { name: 'tasks-list' },
+ component: () => import('@/layouts/dashboard'),
+ children: [
+ {
+ path: '/tasks/list',
+ name: 'tasks-list',
+ component: components['tasks-list'],
+ meta: {
+ title: 'tasks-list'
+ }
+ }
+ ]
+}
diff --git a/seatunnel-ui/src/router/user-manage.ts b/seatunnel-ui/src/router/user-manage.ts
new file mode 100644
index 0000000..be0dcdc
--- /dev/null
+++ b/seatunnel-ui/src/router/user-manage.ts
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import utils from '@/utils'
+import type { Component } from 'vue'
+
+const modules = import.meta.glob('/src/views/**/**.tsx')
+const components: { [key: string]: Component } = utils.mapping(modules)
+
+export default {
+ path: '/user-manage',
+ name: 'user-manage',
+ meta: {
+ title: 'user-manage'
+ },
+ redirect: { name: 'user-manage-list' },
+ component: () => import('@/layouts/dashboard'),
+ children: [
+ {
+ path: '/user-manage/list',
+ name: 'user-manage-list',
+ component: components['user-manage-list'],
+ meta: {
+ title: 'user-manage-list'
+ }
+ }
+ ]
+}
diff --git a/seatunnel-ui/src/service/script/index.ts b/seatunnel-ui/src/service/script/index.ts
new file mode 100644
index 0000000..abf8f62
--- /dev/null
+++ b/seatunnel-ui/src/service/script/index.ts
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { axios } from '@/service/service'
+import type { ScriptList, ScriptAdd } from '@/service/script/types'
+
+export function scriptList(params: ScriptList): any {
+ return axios({
+ url: '/script',
+ method: 'get',
+ params
+ })
+}
+
+export function scriptAdd(data: ScriptAdd): any {
+ return axios({
+ url: '/script',
+ method: 'post',
+ data
+ })
+}
+
+export function scriptDelete(scriptId: number): any {
+ return axios({
+ url: `/script/${scriptId}`,
+ method: 'delete'
+ })
+}
+
+export function scriptContent(scriptId: number): any {
+ return axios({
+ url: `/script/${scriptId}/content`,
+ method: 'get'
+ })
+}
+
+export function scriptContentUpdate(scriptId: number, content: string): any {
+ return axios({
+ url: `/script/${scriptId}/content`,
+ method: 'put',
+ data: {
+ content
+ }
+ })
+}
+
+export function scriptParam(scriptId: number): any {
+ return axios({
+ url: `/script/${scriptId}/param`,
+ method: 'get'
+ })
+}
+
+export function scriptParamUpdate(scriptId: number): any {
+ return axios({
+ url: `/script/${scriptId}/param`,
+ method: 'put'
+ })
+}
+
+export function scriptPublish(scriptId: number): any {
+ return axios({
+ url: `/script/${scriptId}/publish`,
+ method: 'patch'
+ })
+}
diff --git a/seatunnel-ui/src/service/script/types.ts b/seatunnel-ui/src/service/script/types.ts
new file mode 100644
index 0000000..0b50f20
--- /dev/null
+++ b/seatunnel-ui/src/service/script/types.ts
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface ScriptList {
+ name?: string
+ pageNo: number
+ pageSize: number
+ status?: string
+}
+
+interface ScriptAdd {
+ name: string
+ type: string
+}
+
+export { ScriptList, ScriptAdd }
diff --git a/seatunnel-ui/src/service/service.ts b/seatunnel-ui/src/service/service.ts
new file mode 100644
index 0000000..94bb599
--- /dev/null
+++ b/seatunnel-ui/src/service/service.ts
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
+import utils from '@/utils'
+import { useUserStore } from '@/store/user'
+import type { UserDetail } from '@/service/user/types'
+
+const userStore = useUserStore()
+
+const handleError = (res: AxiosResponse<any, any>) => {
+ if (import.meta.env.MODE === 'development') {
+ utils.log.capsule('SeaTunnel', 'UI')
+ utils.log.error(res)
+ }
+ console.log(res)
+ window.$message.error(res.data.msg)
+}
+
+const baseRequestConfig: AxiosRequestConfig = {
+ timeout: 6000,
+ baseURL: '/api/v1'
+}
+
+const service = axios.create(baseRequestConfig)
+
+const err = (err: AxiosError): Promise<AxiosError> => {
+ return Promise.reject(err)
+}
+
+service.interceptors.request.use((config: AxiosRequestConfig<any>) => {
+ if (Object.keys(userStore.getUserInfo).length > 0) {
+ config.headers &&
+ (config.headers.token = (userStore.getUserInfo as UserDetail)
+ .token as string)
+ }
+
+ return config
+}, err)
+
+service.interceptors.response.use((res: AxiosResponse) => {
+ if (res.data.success) return res.data
+
+ handleError(res)
+}, err)
+
+export { service as axios }
diff --git a/seatunnel-ui/src/service/task/index.ts b/seatunnel-ui/src/service/task/index.ts
new file mode 100644
index 0000000..606d787
--- /dev/null
+++ b/seatunnel-ui/src/service/task/index.ts
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { axios } from '@/service/service'
+import type {
+ TaskList,
+ TaskJobList,
+ TaskRecycle,
+ TaskExecute
+} from '@/service/task/types'
+
+export function taskInstanceList(params: TaskList): any {
+ return axios({
+ url: '/task/instance',
+ method: 'get',
+ params
+ })
+}
+
+export function taskJobList(params: TaskList): any {
+ return axios({
+ url: '/task/job',
+ method: 'get',
+ params
+ })
+}
+
+export function taskExecute(scriptId: number, data: TaskExecute): any {
+ return axios({
+ url: `/task/${scriptId}/execute`,
+ method: 'post',
+ data
+ })
+}
+
+export function taskRecycle(scriptId: number): any {
+ return axios({
+ url: `/task/${scriptId}/recycle`,
+ method: 'patch'
+ })
+}
+
+export function taskInstanceDetail(taskInstanceId: number): any {
+ return axios({
+ url: `/task/${taskInstanceId}`,
+ method: 'get'
+ })
+}
+
+export function taskInstanceKill(taskInstanceId: number): any {
+ return axios({
+ url: `/task/${taskInstanceId}`,
+ method: 'patch'
+ })
+}
diff --git a/seatunnel-ui/src/service/task/types.ts b/seatunnel-ui/src/service/task/types.ts
new file mode 100644
index 0000000..7258649
--- /dev/null
+++ b/seatunnel-ui/src/service/task/types.ts
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface TaskList {
+ name?: string
+ pageNo: number
+ pageSize: number
+}
+
+interface TaskJobList {
+ name: string
+ pageNo: number
+ pageSize: number
+}
+
+interface TaskRecycle {
+ scriptId: number
+ operatorId: number
+}
+
+interface TaskExecute {
+ content: string
+ executeType: number
+ params: object
+}
+
+export { TaskList, TaskJobList, TaskRecycle, TaskExecute }
diff --git a/seatunnel-ui/src/service/types.ts b/seatunnel-ui/src/service/types.ts
new file mode 100644
index 0000000..3bc79ff
--- /dev/null
+++ b/seatunnel-ui/src/service/types.ts
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface ResponseBasic<T> {
+ code: number
+ failed: boolean
+ success: boolean
+ msg: string | null
+ data: T
+}
+
+type ResponseTable<T> = ResponseBasic<{
+ pageNo: number
+ pageSize: number
+ totalCount: number
+ totalPage: number
+ data: T
+}>
+
+export { ResponseTable }
diff --git a/seatunnel-ui/src/service/user/index.ts b/seatunnel-ui/src/service/user/index.ts
new file mode 100644
index 0000000..d6f9d47
--- /dev/null
+++ b/seatunnel-ui/src/service/user/index.ts
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { axios } from '@/service/service'
+import type { UserList, UserLogin, UserDetail } from '@/service/user/types'
+
+export function userList(params: UserList): any {
+ return axios({
+ url: '/user',
+ method: 'get',
+ params
+ })
+}
+
+export function userAdd(data: UserDetail): any {
+ return axios({
+ url: '/user',
+ method: 'post',
+ data
+ })
+}
+
+export function userLogin(data: UserLogin): any {
+ return axios({
+ url: '/user/login',
+ method: 'post',
+ data
+ })
+}
+
+export function userLogout(): any {
+ return axios({
+ url: '/user/logout',
+ method: 'patch'
+ })
+}
+
+export function userDelete(userId: number): any {
+ return axios({
+ url: `/user/${userId}`,
+ method: 'delete'
+ })
+}
+
+export function userUpdate(userId: number, data: UserDetail): any {
+ return axios({
+ url: `/user/${userId}`,
+ method: 'put',
+ data
+ })
+}
+
+export function userDisable(userId: number): any {
+ return axios({
+ url: `/user/${userId}/disable`,
+ method: 'put'
+ })
+}
+
+export function userEnable(userId: number): any {
+ return axios({
+ url: `/user/${userId}/enable`,
+ method: 'patch'
+ })
+}
diff --git a/seatunnel-ui/src/service/user/types.ts b/seatunnel-ui/src/service/user/types.ts
new file mode 100644
index 0000000..31ef9e5
--- /dev/null
+++ b/seatunnel-ui/src/service/user/types.ts
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface UserList {
+ name?: string
+ pageNo: number
+ pageSize: number
+}
+
+interface UserLogin {
+ password: string
+ username: string
+}
+
+interface UserDetail extends UserLogin {
+ status: number
+ type?: number
+ token?: string
+ id?: number
+ name?: string
+ createTime?: any | null
+ updateTime?: any | null
+}
+
+export { UserList, UserLogin, UserDetail }
diff --git a/seatunnel-ui/src/store/locale/index.ts b/seatunnel-ui/src/store/locale/index.ts
new file mode 100644
index 0000000..1b31f7a
--- /dev/null
+++ b/seatunnel-ui/src/store/locale/index.ts
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineStore } from 'pinia'
+import { LocalesStore, Locales } from './types'
+
+export const useLocalesStore = defineStore({
+ id: 'locales',
+ state: (): LocalesStore => ({
+ locales: 'en_US'
+ }),
+ persist: true,
+ getters: {
+ getLocales(): Locales {
+ return this.locales
+ }
+ },
+ actions: {
+ setLocales(lang: Locales): void {
+ this.locales = lang
+ }
+ }
+})
diff --git a/seatunnel-ui/src/store/locale/types.ts b/seatunnel-ui/src/store/locale/types.ts
new file mode 100644
index 0000000..03625ad
--- /dev/null
+++ b/seatunnel-ui/src/store/locale/types.ts
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+type Locales = 'zh_CN' | 'en_US'
+
+interface LocalesStore {
+ locales: Locales
+}
+
+export { LocalesStore, Locales }
diff --git a/seatunnel-ui/src/store/theme/index.ts b/seatunnel-ui/src/store/theme/index.ts
new file mode 100644
index 0000000..91df4f4
--- /dev/null
+++ b/seatunnel-ui/src/store/theme/index.ts
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineStore } from 'pinia'
+import { ThemeState } from './types'
+
+export const useThemeStore = defineStore({
+ id: 'theme',
+ state: (): ThemeState => ({
+ darkTheme: false
+ }),
+ persist: true,
+ getters: {
+ getTheme(): boolean {
+ return this.darkTheme
+ }
+ },
+ actions: {
+ setDarkTheme(): void {
+ this.darkTheme = !this.darkTheme
+ }
+ }
+})
diff --git a/seatunnel-ui/src/store/theme/types.ts b/seatunnel-ui/src/store/theme/types.ts
new file mode 100644
index 0000000..fa7e56d
--- /dev/null
+++ b/seatunnel-ui/src/store/theme/types.ts
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface ThemeState {
+ darkTheme: boolean
+}
+
+export { ThemeState }
diff --git a/seatunnel-ui/src/store/user/index.ts b/seatunnel-ui/src/store/user/index.ts
new file mode 100644
index 0000000..8c10ee3
--- /dev/null
+++ b/seatunnel-ui/src/store/user/index.ts
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineStore } from 'pinia'
+import type { UserState } from './types'
+import type { UserDetail } from '@/service/user/types'
+
+export const useUserStore = defineStore({
+ id: 'user',
+ state: (): UserState => ({
+ userInfo: {}
+ }),
+ persist: true,
+ getters: {
+ getUserInfo(): UserDetail | {} {
+ return this.userInfo
+ }
+ },
+ actions: {
+ setUserInfo(userInfo: UserDetail | {}): void {
+ this.userInfo = userInfo
+ }
+ }
+})
diff --git a/seatunnel-ui/src/store/user/types.ts b/seatunnel-ui/src/store/user/types.ts
new file mode 100644
index 0000000..ed746c3
--- /dev/null
+++ b/seatunnel-ui/src/store/user/types.ts
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { UserDetail } from '@/service/user/types'
+
+interface UserState {
+ userInfo: UserDetail | {}
+}
+
+export { UserState }
diff --git a/seatunnel-ui/src/themes/index.ts b/seatunnel-ui/src/themes/index.ts
new file mode 100644
index 0000000..a5f70cb
--- /dev/null
+++ b/seatunnel-ui/src/themes/index.ts
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import light from './modules/light'
+import dark from './modules/dark'
+
+const themeList = {
+ light,
+ dark
+}
+
+export default themeList
diff --git a/seatunnel-ui/src/themes/modules/dark.ts b/seatunnel-ui/src/themes/modules/dark.ts
new file mode 100644
index 0000000..5473e6f
--- /dev/null
+++ b/seatunnel-ui/src/themes/modules/dark.ts
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const dark = {}
+
+export default dark
diff --git a/seatunnel-ui/src/themes/modules/light.ts b/seatunnel-ui/src/themes/modules/light.ts
new file mode 100644
index 0000000..4986ed2
--- /dev/null
+++ b/seatunnel-ui/src/themes/modules/light.ts
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { GlobalThemeOverrides } from 'naive-ui'
+
+const light: GlobalThemeOverrides = {
+ common: {
+ primaryColor: '#1890ff',
+ primaryColorHover: '#40a9ff',
+ primaryColorPressed: '#096dd9',
+ primaryColorSuppl: '#1890ff',
+
+ infoColor: '#1890ff',
+ successColor: '#52c41a',
+ warningColor: '#faad14',
+ errorColor: '#ff4d4f'
+ }
+}
+
+export default light
diff --git a/seatunnel-ui/src/utils/index.ts b/seatunnel-ui/src/utils/index.ts
new file mode 100644
index 0000000..d806dfb
--- /dev/null
+++ b/seatunnel-ui/src/utils/index.ts
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mapping from './mapping'
+import trim from './trim'
+import log from './log'
+
+const utils = {
+ mapping,
+ trim,
+ log
+}
+
+export default utils
diff --git a/seatunnel-ui/src/utils/log.ts b/seatunnel-ui/src/utils/log.ts
new file mode 100644
index 0000000..543ba75
--- /dev/null
+++ b/seatunnel-ui/src/utils/log.ts
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const log = {
+ capsule: (unusedTitle: string, unusedText: string, unusedType?: string) => {},
+ error: (unusedInfo: any) => {}
+}
+
+/**
+ * @description Returns the color value of the style
+ * @param {String} type The style name [ primary | success | warning | error ]
+ */
+const typeColor = (type = 'primary') => {
+ let color = ''
+ switch (type) {
+ case 'primary':
+ color = '#1890ff'
+ break
+ case 'success':
+ color = '#52c41a'
+ break
+ case 'warning':
+ color = '#faad14'
+ break
+ case 'error':
+ color = '#ff4d4f'
+ break
+ default:
+ break
+ }
+ return color
+}
+
+/**
+ * @description capsule
+ * @param {String} title title text
+ * @param {String} text info text
+ * @param {String} type style
+ */
+log.capsule = (title: string, text: string, type = 'primary') => {
+ // eslint-disable-next-line no-console
+ console.log(
+ `%c ${title} %c ${text} %c`,
+ 'background:#35495E; padding: 2px ; border-radius: 3px 0 0 3px; color: #fff;',
+ `background:${typeColor(
+ type
+ )}; padding: 2px; border-radius: 0 3px 3px 0; color: #fff;`,
+ 'background:transparent'
+ )
+}
+
+/**
+ * @description Prints text in error style
+ */
+log.error = function (info) {
+ // eslint-disable-next-line no-console
+ console.group('error info')
+ // eslint-disable-next-line no-console
+ console.log('responseURL: ', `${info.config.baseURL}${info.config.url}`)
+ // eslint-disable-next-line no-console
+ console.log('msg: ', info.data.msg)
+ // eslint-disable-next-line no-console
+ console.groupEnd()
+}
+
+export default log
diff --git a/seatunnel-ui/src/utils/mapping.ts b/seatunnel-ui/src/utils/mapping.ts
new file mode 100644
index 0000000..a200f94
--- /dev/null
+++ b/seatunnel-ui/src/utils/mapping.ts
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { Component } from 'vue'
+
+const mapping = (modules: any) => {
+ const components: { [key: string]: Component } = {}
+ Object.keys(modules).forEach((key: string) => {
+ const nameMatch: string[] | null = key.match(/^\/src\/views\/(.+)\.tsx/)
+
+ if (!nameMatch) {
+ return
+ }
+
+ const indexMatch: string[] | null = nameMatch[1].match(/(.*)\/Index$/i)
+
+ let name: string = indexMatch ? indexMatch[1] : nameMatch[1]
+
+ name = name.replaceAll('/', '-')
+
+ components[name] = modules[key]
+ })
+ return components
+}
+
+export default mapping
diff --git a/seatunnel-ui/src/utils/trim.ts b/seatunnel-ui/src/utils/trim.ts
new file mode 100644
index 0000000..d7f731b
--- /dev/null
+++ b/seatunnel-ui/src/utils/trim.ts
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const trim = (value: string) => {
+ return !value.startsWith(' ') && !value.endsWith(' ')
+}
+
+export default trim
diff --git a/seatunnel-ui/src/views/data-pipes/create/components/configuration-modal.tsx b/seatunnel-ui/src/views/data-pipes/create/components/configuration-modal.tsx
new file mode 100644
index 0000000..0f55836
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/create/components/configuration-modal.tsx
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, onMounted, toRefs } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NButton, NDataTable, NForm, NFormItem, NInput, NSpace } from 'naive-ui'
+import { useConfigurationModal } from './use-configuration-modal'
+import Modal from '@/components/modal'
+import type { PropType } from 'vue'
+
+const props = {
+ showModal: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ type: {
+ type: String as PropType<'engine-parameter' | 'self-defined-parameter'>
+ }
+}
+
+const ConfigurationModal = defineComponent({
+ props,
+ emits: ['cancelModal', 'confirmModal'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+ const { state, createColumns, handleValidate } = useConfigurationModal()
+
+ const handleCancel = () => {
+ ctx.emit('cancelModal', props.showModal)
+ }
+
+ const handleConfirm = () => {}
+
+ const handleClickAdd = () => {
+ handleValidate()
+ }
+
+ onMounted(() => {
+ createColumns(state)
+ })
+
+ return { t, ...toRefs(state), handleCancel, handleConfirm, handleClickAdd }
+ },
+ render($props: any) {
+ return (
+ <Modal
+ title={
+ this.t(
+ 'data_pipes.' +
+ ($props.type === 'engine-parameter'
+ ? 'engine_parameter'
+ : 'self_defined_parameter')
+ ) +
+ ' ' +
+ this.t('data_pipes.configuration')
+ }
+ show={this.showModal}
+ onCancel={this.handleCancel}
+ onConfirm={this.handleConfirm}
+ >
+ <NSpace vertical>
+ <NForm model={this.model} rules={this.rules} ref='parameterForm'>
+ <NFormItem label={this.t('data_pipes.key')} path='key'>
+ <NInput v-model={[this.model.key, 'value']} clearable />
+ </NFormItem>
+ <NFormItem label={this.t('data_pipes.value')} path='value'>
+ <NInput v-model={[this.model.value, 'value']} clearable />
+ </NFormItem>
+ <NButton class='w-full' onClick={this.handleClickAdd}>
+ {this.t('data_pipes.add')}
+ </NButton>
+ </NForm>
+ <NDataTable
+ loading={this.loading}
+ columns={this.columns}
+ data={this.tableData}
+ />
+ </NSpace>
+ </Modal>
+ )
+ }
+})
+
+export default ConfigurationModal
diff --git a/seatunnel-ui/src/views/data-pipes/create/components/use-configuration-modal.ts b/seatunnel-ui/src/views/data-pipes/create/components/use-configuration-modal.ts
new file mode 100644
index 0000000..5b28e29
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/create/components/use-configuration-modal.ts
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { h, reactive, ref, SetupContext } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NButton, NSpace } from 'naive-ui'
+
+export function useConfigurationModal() {
+ const { t } = useI18n()
+ const state = reactive({
+ parameterForm: ref(),
+ model: {
+ key: ref(''),
+ value: ref('')
+ },
+ rules: {
+ key: {
+ required: true,
+ trigger: ['input', 'blur'],
+ message: t('data_pipes.model_validate_tips')
+ },
+ value: {
+ required: true,
+ trigger: ['input', 'blur'],
+ message: t('data_pipes.model_validate_tips')
+ }
+ },
+ loading: ref(false),
+ columns: [],
+ tableData: [{ key: 'key1', value: 'value1' }]
+ })
+
+ const createColumns = (state: any) => {
+ state.columns = [
+ {
+ title: t('data_pipes.key'),
+ key: 'key'
+ },
+ {
+ title: t('data_pipes.value'),
+ key: 'value'
+ },
+ {
+ title: t('data_pipes.operation'),
+ key: 'operation',
+ render: (row: any) =>
+ h(
+ NButton,
+ { text: true, onClick: () => handleDelete(row) },
+ t('user_manage.delete')
+ )
+ }
+ ]
+ }
+
+ const handleValidate = () => {
+ state.parameterForm.validate((errors: any) => {
+ if (!errors) {
+ state.tableData.push({ key: state.model.key, value: state.model.value })
+ state.model.key = ''
+ state.model.value = ''
+ } else {
+ return
+ }
+ })
+ }
+
+ const handleDelete = (row: any) => {}
+
+ return { state, createColumns, handleValidate }
+}
diff --git a/seatunnel-ui/src/views/data-pipes/create/index.tsx b/seatunnel-ui/src/views/data-pipes/create/index.tsx
new file mode 100644
index 0000000..47d4d71
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/create/index.tsx
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useRouter } from 'vue-router'
+import {
+ NBreadcrumb,
+ NBreadcrumbItem,
+ NButton,
+ NCard,
+ NIcon,
+ NInput,
+ NSpace,
+ NTooltip,
+ NDropdown
+} from 'naive-ui'
+import { BulbOutlined } from '@vicons/antd'
+import MonacoEditor from '@/components/monaco-editor'
+import Log from '@/components/log'
+import ConfigurationModal from './components/configuration-modal'
+import type { Router } from 'vue-router'
+import type { Ref } from 'vue'
+
+const DataPipesCreate = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const router: Router = useRouter()
+ const showConfigurationModal: Ref<boolean> = ref(false)
+ const configurationType: Ref<
+ 'engine-parameter' | 'self-defined-parameter'
+ > = ref('engine-parameter')
+
+ const handleClickDataPipes = () => {
+ router.push({ path: '/data-pipes/list' })
+ }
+
+ const handleSelectConfiguration = (
+ key: 'engine-parameter' | 'self-defined-parameter'
+ ) => {
+ configurationType.value = key
+ showConfigurationModal.value = true
+ }
+
+ const handleCancelConfigurationModal = () => {
+ showConfigurationModal.value = false
+ }
+
+ const handleConfirmConfigurationModal = () => {
+ showConfigurationModal.value = false
+ }
+
+ return {
+ t,
+ showConfigurationModal,
+ configurationType,
+ handleClickDataPipes,
+ handleSelectConfiguration,
+ handleCancelConfigurationModal,
+ handleConfirmConfigurationModal
+ }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard>
+ {{
+ header: () => (
+ <NSpace align='center'>
+ <NBreadcrumb>
+ <NBreadcrumbItem onClick={this.handleClickDataPipes}>
+ {this.t('data_pipes.data_pipes')}
+ </NBreadcrumbItem>
+ <NBreadcrumbItem>
+ {this.t('data_pipes.create')}
+ </NBreadcrumbItem>
+ </NBreadcrumb>
+ </NSpace>
+ ),
+ 'header-extra': () => (
+ <NSpace>
+ <NButton secondary>{this.t('data_pipes.cancel')}</NButton>
+ <NButton secondary>{this.t('data_pipes.save')}</NButton>
+ </NSpace>
+ )
+ }}
+ </NCard>
+ <NCard>
+ <NSpace align='center'>
+ <span>{this.t('data_pipes.name')}</span>
+ <NSpace align='center'>
+ <NInput
+ clearable
+ maxlength='100'
+ showCount
+ style={{ width: '600px' }}
+ />
+ <NTooltip placement='right' trigger='hover'>
+ {{
+ default: () => <span>{this.t('data_pipes.name_tips')}</span>,
+ trigger: () => (
+ <NIcon size='20' style={{ cursor: 'pointer' }}>
+ <BulbOutlined />
+ </NIcon>
+ )
+ }}
+ </NTooltip>
+ </NSpace>
+ </NSpace>
+ </NCard>
+ <NCard>
+ <NSpace vertical>
+ <NSpace justify='end'>
+ <NButton secondary>{this.t('data_pipes.execute')}</NButton>
+ <NButton secondary>{this.t('data_pipes.kill')}</NButton>
+ <NButton secondary>{this.t('data_pipes.stop')}</NButton>
+ <NDropdown
+ trigger='click'
+ options={[
+ {
+ label: this.t('data_pipes.engine_parameter'),
+ key: 'engine-parameter'
+ },
+ {
+ label: this.t('data_pipes.self_defined_parameter'),
+ key: 'self-defined-parameter'
+ }
+ ]}
+ onSelect={this.handleSelectConfiguration}
+ >
+ <NButton secondary>
+ {this.t('data_pipes.configuration')}
+ </NButton>
+ </NDropdown>
+ </NSpace>
+ <MonacoEditor />
+ </NSpace>
+ </NCard>
+ <NCard>
+ <Log />
+ </NCard>
+ <ConfigurationModal
+ type={this.configurationType}
+ showModal={this.showConfigurationModal}
+ onCancelModal={this.handleCancelConfigurationModal}
+ onConfirmModal={this.handleConfirmConfigurationModal}
+ />
+ </NSpace>
+ )
+ }
+})
+
+export default DataPipesCreate
diff --git a/seatunnel-ui/src/views/data-pipes/detail/components/detail-overview.tsx b/seatunnel-ui/src/views/data-pipes/detail/components/detail-overview.tsx
new file mode 100644
index 0000000..485bf8c
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/detail/components/detail-overview.tsx
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, onMounted, toRefs } from 'vue'
+import { NGi, NGrid, NSpace, NTabs, NTabPane, NDataTable } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useDetailOverview } from './use-detail-overview'
+import Log from '@/components/log'
+
+const DetailOverview = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const { state, createColumns } = useDetailOverview()
+
+ onMounted(() => {
+ createColumns(state)
+ })
+
+ return { t, ...toRefs(state) }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NGrid x-gap='12' cols='2'>
+ <NGi>{this.t('data_pipes.input_metrics')}</NGi>
+ <NGi>{this.t('data_pipes.output_metrics')}</NGi>
+ </NGrid>
+ <NGrid x-gap='12' cols='4'>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.bytes_per_second')}
+ </span>
+ </NGi>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.record_per_second')}
+ </span>
+ </NGi>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.bytes_per_second')}
+ </span>
+ </NGi>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.record_per_second')}
+ </span>
+ </NGi>
+ </NGrid>
+ <NGrid x-gap='12' cols='4'>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.total_bytes')}
+ </span>
+ </NGi>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.total_records')}
+ </span>
+ </NGi>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.total_bytes')}
+ </span>
+ </NGi>
+ <NGi
+ class={['flex', 'justify-between', 'py-4', 'px-3', 'bg-gray-50']}
+ >
+ <span>1212</span>
+ <span class='text-gray-400'>
+ {this.t('data_pipes.total_records')}
+ </span>
+ </NGi>
+ </NGrid>
+ <NTabs type='line' justify-content='space-evenly' class='mt-7'>
+ <NTabPane name='run-log' tab={this.t('data_pipes.run_log')}>
+ <Log />
+ </NTabPane>
+ <NTabPane
+ name='historical-run-logs'
+ tab={this.t('data_pipes.historical_run_logs')}
+ >
+ <NDataTable
+ loading={this.loading}
+ columns={this.columns}
+ data={this.tableData}
+ />
+ </NTabPane>
+ </NTabs>
+ </NSpace>
+ )
+ }
+})
+
+export default DetailOverview
diff --git a/seatunnel-ui/src/views/data-pipes/detail/components/use-detail-overview.ts b/seatunnel-ui/src/views/data-pipes/detail/components/use-detail-overview.ts
new file mode 100644
index 0000000..c9eba53
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/detail/components/use-detail-overview.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive, ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+
+export function useDetailOverview() {
+ const { t } = useI18n()
+ const state = reactive({
+ loading: ref(false),
+ columns: [],
+ tableData: [{ name: '' }]
+ })
+
+ const createColumns = (state: any) => {
+ state.columns = [
+ {
+ title: t('data_pipes.name'),
+ key: 'name'
+ },
+ {
+ title: t('data_pipes.execute_time'),
+ key: 'executeTime'
+ },
+ {
+ title: t('data_pipes.end_time'),
+ key: 'endTime'
+ },
+ {
+ title: t('data_pipes.state'),
+ key: 'state'
+ }
+ ]
+ }
+
+ return { state, createColumns }
+}
diff --git a/seatunnel-ui/src/views/data-pipes/detail/index.tsx b/seatunnel-ui/src/views/data-pipes/detail/index.tsx
new file mode 100644
index 0000000..5f0907f
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/detail/index.tsx
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import {
+ NSpace,
+ NCard,
+ NButton,
+ NBreadcrumb,
+ NBreadcrumbItem,
+ NTabs,
+ NTabPane
+} from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useRouter } from 'vue-router'
+import MonacoEditor from '@/components/monaco-editor'
+import DetailOverview from './components/detail-overview'
+import type { Router } from 'vue-router'
+
+const DataPipesDetail = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const router: Router = useRouter()
+
+ const handleClickDataPipes = () => {
+ router.push({ path: '/data-pipes/list' })
+ }
+
+ return { t, handleClickDataPipes }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard>
+ {{
+ header: () => (
+ <NSpace align='center'>
+ <NBreadcrumb>
+ <NBreadcrumbItem onClick={this.handleClickDataPipes}>
+ {this.t('data_pipes.data_pipes')}
+ </NBreadcrumbItem>
+ <NBreadcrumbItem>user-order-tables-10</NBreadcrumbItem>
+ </NBreadcrumb>
+ <div
+ class={['w-3', 'h-3', 'rounded-full', 'bg-green-400']}
+ ></div>
+ <span
+ style={{
+ fontSize: 'var(--n-font-size)',
+ color: 'var(--n-item-text-color-active)'
+ }}
+ >
+ {this.t('data_pipes.stop')}
+ </span>
+ </NSpace>
+ ),
+ 'header-extra': () => (
+ <NSpace>
+ <NButton secondary>{this.t('data_pipes.execute')}</NButton>
+ <NButton secondary>{this.t('data_pipes.kill')}</NButton>
+ <NButton secondary>{this.t('data_pipes.stop')}</NButton>
+ </NSpace>
+ )
+ }}
+ </NCard>
+ <NTabs type='segment' class='mt-9'>
+ <NTabPane name='overview' tab={this.t('data_pipes.overview')}>
+ <NCard>
+ <DetailOverview />
+ </NCard>
+ </NTabPane>
+ <NTabPane name='script' tab={this.t('data_pipes.script')}>
+ <NCard>
+ <MonacoEditor />
+ </NCard>
+ </NTabPane>
+ </NTabs>
+ </NSpace>
+ )
+ }
+})
+
+export default DataPipesDetail
diff --git a/seatunnel-ui/src/views/data-pipes/edit/index.tsx b/seatunnel-ui/src/views/data-pipes/edit/index.tsx
new file mode 100644
index 0000000..28f33bb
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/edit/index.tsx
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import {
+ NBreadcrumb,
+ NBreadcrumbItem,
+ NButton,
+ NCard,
+ NSpace,
+ NInput,
+ NIcon,
+ NTooltip
+} from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useRouter } from 'vue-router'
+import { BulbOutlined } from '@vicons/antd'
+import MonacoEditor from '@/components/monaco-editor'
+import type { Router } from 'vue-router'
+
+const DataPipesEdit = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const router: Router = useRouter()
+
+ const handleClickDataPipes = () => {
+ router.push({ path: '/data-pipes/list' })
+ }
+
+ return { t, handleClickDataPipes }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard>
+ {{
+ header: () => (
+ <NSpace align='center'>
+ <NBreadcrumb>
+ <NBreadcrumbItem onClick={this.handleClickDataPipes}>
+ {this.t('data_pipes.data_pipes')}
+ </NBreadcrumbItem>
+ <NBreadcrumbItem>{this.t('data_pipes.edit')}</NBreadcrumbItem>
+ </NBreadcrumb>
+ </NSpace>
+ ),
+ 'header-extra': () => (
+ <NSpace>
+ <NButton secondary>{this.t('data_pipes.cancel')}</NButton>
+ <NButton secondary>{this.t('data_pipes.save')}</NButton>
+ </NSpace>
+ )
+ }}
+ </NCard>
+ <NCard>
+ <NSpace align='center'>
+ <span>{this.t('data_pipes.name')}</span>
+ <NSpace align='center'>
+ <NInput
+ clearable
+ maxlength='100'
+ showCount
+ style={{ width: '600px' }}
+ />
+ <NTooltip placement='right' trigger='hover'>
+ {{
+ default: () => <span>{this.t('data_pipes.name_tips')}</span>,
+ trigger: () => (
+ <NIcon size='20' style={{ cursor: 'pointer' }}>
+ <BulbOutlined />
+ </NIcon>
+ )
+ }}
+ </NTooltip>
+ </NSpace>
+ </NSpace>
+ </NCard>
+ <NCard>
+ <MonacoEditor />
+ </NCard>
+ </NSpace>
+ )
+ }
+})
+
+export default DataPipesEdit
diff --git a/seatunnel-ui/src/views/data-pipes/list/components/delete-modal.tsx b/seatunnel-ui/src/views/data-pipes/list/components/delete-modal.tsx
new file mode 100644
index 0000000..f2355ac
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/list/components/delete-modal.tsx
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { useI18n } from 'vue-i18n'
+import Modal from '@/components/modal'
+import type { PropType } from 'vue'
+
+const props = {
+ showModal: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ row: {
+ type: Object as PropType<any>,
+ default: {}
+ }
+}
+
+const DeleteModal = defineComponent({
+ props,
+ emits: ['cancelModal', 'confirmModal'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+
+ const handleCancel = () => {
+ ctx.emit('cancelModal', props.showModal)
+ }
+
+ const handleConfirm = () => {}
+
+ return { t, handleCancel, handleConfirm }
+ },
+ render() {
+ return (
+ <Modal
+ title={this.t('data_pipes.delete')}
+ show={this.showModal}
+ onCancel={this.handleCancel}
+ onConfirm={this.handleConfirm}
+ >
+ {{
+ default: () => (
+ <span>{this.t('data_pipes.data_pipes_delete_tips')}</span>
+ )
+ }}
+ </Modal>
+ )
+ }
+})
+
+export default DeleteModal
diff --git a/seatunnel-ui/src/views/data-pipes/list/components/publish-modal.tsx b/seatunnel-ui/src/views/data-pipes/list/components/publish-modal.tsx
new file mode 100644
index 0000000..abfce10
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/list/components/publish-modal.tsx
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { useI18n } from 'vue-i18n'
+import Modal from '@/components/modal'
+import type { PropType } from 'vue'
+
+const props = {
+ showModal: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ row: {
+ type: Object as PropType<any>,
+ default: {}
+ }
+}
+
+const PublishModal = defineComponent({
+ props,
+ emits: ['cancelModal', 'confirmModal'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+
+ const handleCancel = () => {
+ ctx.emit('cancelModal', props.showModal)
+ }
+
+ const handleConfirm = () => {}
+
+ return { t, handleCancel, handleConfirm }
+ },
+ render() {
+ return (
+ <Modal
+ title={this.t('data_pipes.publish')}
+ show={this.showModal}
+ onCancel={this.handleCancel}
+ onConfirm={this.handleConfirm}
+ >
+ {{
+ default: () => (
+ <span>{this.t('data_pipes.data_pipes_publish_tips')}</span>
+ )
+ }}
+ </Modal>
+ )
+ }
+})
+
+export default PublishModal
diff --git a/seatunnel-ui/src/views/data-pipes/list/index.tsx b/seatunnel-ui/src/views/data-pipes/list/index.tsx
new file mode 100644
index 0000000..a8cafb8
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/list/index.tsx
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, onMounted, toRefs } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { useTable } from './use-table'
+import { NButton, NCard, NDataTable, NPagination, NSpace } from 'naive-ui'
+import { useRouter } from 'vue-router'
+import DeleteModal from './components/delete-modal'
+import PublishModal from './components/publish-modal'
+import type { Router } from 'vue-router'
+
+const DataPipesList = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const router: Router = useRouter()
+ const { state, createColumns } = useTable()
+
+ const handleCancelDeleteModal = () => {
+ state.showDeleteModal = false
+ }
+
+ const handleConfirmDeleteModal = () => {
+ state.showDeleteModal = false
+ }
+
+ const handleCancelPublishModal = () => {
+ state.showPublishModal = false
+ }
+
+ const handleConfirmPublishModal = () => {
+ state.showPublishModal = false
+ }
+
+ const handleCreate = () => {
+ router.push({ path: '/data-pipes/create' })
+ }
+
+ onMounted(() => {
+ createColumns(state)
+ })
+
+ return {
+ t,
+ ...toRefs(state),
+ handleCancelDeleteModal,
+ handleConfirmDeleteModal,
+ handleCancelPublishModal,
+ handleConfirmPublishModal,
+ handleCreate
+ }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard title={this.t('data_pipes.data_pipes')}>
+ {{
+ 'header-extra': () => (
+ <NButton onClick={this.handleCreate}>
+ {this.t('data_pipes.create')}
+ </NButton>
+ )
+ }}
+ </NCard>
+ <NCard>
+ <NSpace vertical>
+ <NDataTable
+ loading={this.loading}
+ columns={this.columns}
+ data={this.tableData}
+ />
+ <NSpace justify='center'>
+ <NPagination
+ v-model:page={this.page}
+ v-model:page-size={this.pageSize}
+ page-count={this.totalPage}
+ show-size-picker
+ page-sizes={[10, 30, 50]}
+ show-quick-jumper
+ />
+ </NSpace>
+ </NSpace>
+ </NCard>
+ <DeleteModal
+ showModal={this.showDeleteModal}
+ row={this.row}
+ onCancelModal={this.handleCancelDeleteModal}
+ onConfirmModal={this.handleConfirmDeleteModal}
+ />
+ <PublishModal
+ showModal={this.showPublishModal}
+ row={this.row}
+ onCancelModal={this.handleCancelPublishModal}
+ onConfirmModal={this.handleConfirmPublishModal}
+ />
+ </NSpace>
+ )
+ }
+})
+
+export default DataPipesList
diff --git a/seatunnel-ui/src/views/data-pipes/list/use-table.ts b/seatunnel-ui/src/views/data-pipes/list/use-table.ts
new file mode 100644
index 0000000..cfffaf5
--- /dev/null
+++ b/seatunnel-ui/src/views/data-pipes/list/use-table.ts
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive, ref, h } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { NSpace, NButton, NIcon, NDropdown } from 'naive-ui'
+import { EllipsisOutlined } from '@vicons/antd'
+
+export function useTable() {
+ const { t } = useI18n()
+ const state = reactive({
+ columns: [],
+ tableData: [{ username: '' }],
+ page: ref(1),
+ pageSize: ref(10),
+ totalPage: ref(1),
+ row: {},
+ loading: ref(false),
+ showDeleteModal: ref(false),
+ showPublishModal: ref(false)
+ })
+
+ const createColumns = (state: any) => {
+ state.columns = [
+ {
+ title: t('data_pipes.name'),
+ key: 'name'
+ },
+ {
+ title: t('data_pipes.state'),
+ key: 'state'
+ },
+ {
+ title: t('data_pipes.executed_time'),
+ key: 'executedTime'
+ },
+ {
+ title: t('data_pipes.modification_time'),
+ key: 'modificationTime'
+ },
+ {
+ title: t('data_pipes.operation'),
+ key: 'operation',
+ render: (row: any) =>
+ h(NSpace, null, {
+ default: () => [
+ h(NButton, { text: true }, t('data_pipes.execute')),
+ h(NButton, { text: true }, t('data_pipes.edit')),
+ h(
+ NButton,
+ { text: true, onClick: () => handlePublish(row) },
+ t('data_pipes.publish')
+ ),
+ h(
+ NButton,
+ {
+ text: true,
+ trigger: 'click'
+ },
+ h(
+ NDropdown,
+ {
+ options: [{ key: 'delete', label: t('data_pipes.delete') }],
+ onClick: () => handleDelete(row)
+ },
+ h(NIcon, {}, h(EllipsisOutlined))
+ )
+ )
+ ]
+ })
+ }
+ ]
+ }
+
+ const handleDelete = (row: any) => {
+ state.showDeleteModal = true
+ state.row = row
+ }
+
+ const handlePublish = (row: any) => {
+ state.showPublishModal = true
+ state.row = row
+ }
+
+ return { state, createColumns }
+}
diff --git a/seatunnel-ui/src/views/jobs/list/index.tsx b/seatunnel-ui/src/views/jobs/list/index.tsx
new file mode 100644
index 0000000..88a09e7
--- /dev/null
+++ b/seatunnel-ui/src/views/jobs/list/index.tsx
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, onMounted, toRefs } from 'vue'
+import {
+ NSpace,
+ NCard,
+ NButton,
+ NInput,
+ NDataTable,
+ NPagination
+} from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useTable } from './use-table'
+
+const JobsList = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const { state, createColumns } = useTable()
+
+ const handleSearch = () => {}
+
+ onMounted(() => {
+ createColumns(state)
+ })
+
+ return { t, handleSearch, ...toRefs(state) }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard title={this.t('jobs.jobs')}>
+ {{
+ 'header-extra': () => (
+ <NSpace>
+ <NInput
+ placeholder={this.t('jobs.data_pipe_name')}
+ style={{ width: '200px' }}
+ />
+ <NButton onClick={this.handleSearch}>
+ {this.t('jobs.search')}
+ </NButton>
+ </NSpace>
+ )
+ }}
+ </NCard>
+ <NCard>
+ <NSpace vertical>
+ <NDataTable
+ loading={this.loading}
+ columns={this.columns}
+ data={this.tableData}
+ />
+ <NSpace justify='center'>
+ <NPagination
+ v-model:page={this.page}
+ v-model:page-size={this.pageSize}
+ page-count={this.totalPage}
+ show-size-picker
+ page-sizes={[10, 30, 50]}
+ show-quick-jumper
+ />
+ </NSpace>
+ </NSpace>
+ </NCard>
+ </NSpace>
+ )
+ }
+})
+
+export default JobsList
diff --git a/seatunnel-ui/src/views/jobs/list/use-table.ts b/seatunnel-ui/src/views/jobs/list/use-table.ts
new file mode 100644
index 0000000..ff6e781
--- /dev/null
+++ b/seatunnel-ui/src/views/jobs/list/use-table.ts
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { useI18n } from 'vue-i18n'
+import { h, reactive, ref } from 'vue'
+import { NButton, NSpace, NSwitch } from 'naive-ui'
+
+export function useTable() {
+ const { t } = useI18n()
+
+ const state = reactive({
+ columns: [],
+ tableData: [{}],
+ page: ref(1),
+ pageSize: ref(10),
+ totalPage: ref(1),
+ loading: ref(false)
+ })
+
+ const createColumns = (state: any) => {
+ state.columns = [
+ {
+ title: t('jobs.data_pipe_name'),
+ key: 'data_pipe_name'
+ },
+ {
+ title: t('jobs.plan'),
+ key: 'plan'
+ },
+ {
+ title: t('jobs.create_date'),
+ key: 'create_date'
+ },
+ {
+ title: t('jobs.publish'),
+ key: 'publish',
+ render: (row: any) => h(NSwitch, { round: false })
+ },
+ {
+ title: t('jobs.operation'),
+ key: 'operation',
+ render: (row: any) =>
+ h(NSpace, null, {
+ default: () => [
+ h(NButton, { text: true }, t('jobs.executed_immediately')),
+ h(NButton, { text: true }, t('jobs.stop_plan'))
+ ]
+ })
+ }
+ ]
+ }
+
+ return { state, createColumns }
+}
diff --git a/seatunnel-ui/src/views/login/index.tsx b/seatunnel-ui/src/views/login/index.tsx
new file mode 100644
index 0000000..3d66573
--- /dev/null
+++ b/seatunnel-ui/src/views/login/index.tsx
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, toRefs, withKeys, getCurrentInstance } from 'vue'
+import { NSpace, NForm, NFormItem, NInput, NButton, useMessage } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useForm } from './use-form'
+
+const Login = defineComponent({
+ setup() {
+ window.$message = useMessage()
+ const { t } = useI18n()
+ const { state, handleLogin } = useForm()
+ const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
+
+ return {
+ t,
+ ...toRefs(state),
+ trim,
+ handleLogin
+ }
+ },
+ render() {
+ return (
+ <NSpace
+ justify='center'
+ align='center'
+ class='w-full h-screen bg-blue-400'
+ >
+ <div class='w-96 bg-white px-10 py-8'>
+ <h2 class='text-2xl mb-6'>{this.t('login.login_to_sea_tunnel')}</h2>
+ <NForm rules={this.rules} ref='loginFormRef'>
+ <NFormItem
+ label={this.t('login.username')}
+ label-style={{ color: 'black' }}
+ path='userName'
+ >
+ <NInput
+ allowInput={this.trim}
+ type='text'
+ v-model={[this.loginForm.username, 'value']}
+ placeholder={this.t('login.username_tips')}
+ autofocus
+ onKeydown={withKeys(this.handleLogin, ['enter'])}
+ />
+ </NFormItem>
+ <NFormItem
+ label={this.t('login.password')}
+ label-style={{ color: 'black' }}
+ path='userPassword'
+ >
+ <NInput
+ allowInput={this.trim}
+ type='password'
+ v-model={[this.loginForm.password, 'value']}
+ placeholder={this.t('login.password_tips')}
+ onKeydown={withKeys(this.handleLogin, ['enter'])}
+ />
+ </NFormItem>
+ </NForm>
+ <NButton
+ type='info'
+ disabled={!this.loginForm.username || !this.loginForm.password}
+ style={{ width: '100%' }}
+ onClick={this.handleLogin}
+ >
+ {this.t('login.login')}
+ </NButton>
+ </div>
+ </NSpace>
+ )
+ }
+})
+
+export default Login
diff --git a/seatunnel-ui/src/views/login/use-form.ts b/seatunnel-ui/src/views/login/use-form.ts
new file mode 100644
index 0000000..65b4a9b
--- /dev/null
+++ b/seatunnel-ui/src/views/login/use-form.ts
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive, ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { userLogin } from '@/service/user'
+import { useUserStore } from '@/store/user'
+import { useRouter } from 'vue-router'
+import type { FormRules } from 'naive-ui'
+import type { Router } from 'vue-router'
+
+export function useForm() {
+ const router: Router = useRouter()
+ const { t } = useI18n()
+ const userStore = useUserStore()
+
+ const state = reactive({
+ loginFormRef: ref(),
+ loginForm: {
+ username: '',
+ password: ''
+ },
+ rules: {
+ username: {
+ trigger: ['input', 'blur'],
+ validator() {
+ if (state.loginForm.username === '') {
+ return new Error(t('login.username_tips'))
+ }
+ }
+ },
+ password: {
+ trigger: ['input', 'blur'],
+ validator() {
+ if (state.loginForm.password === '') {
+ return new Error(t('login.password_tips'))
+ }
+ }
+ }
+ } as FormRules
+ })
+
+ const handleLogin = () => {
+ userLogin({ ...state.loginForm }).then((res: any) => {
+ userStore.setUserInfo(res.data)
+ router.push({ path: '/data-pipes' })
+ })
+ }
+
+ return {
+ state,
+ handleLogin
+ }
+}
diff --git a/seatunnel-ui/src/views/tasks/list/index.tsx b/seatunnel-ui/src/views/tasks/list/index.tsx
new file mode 100644
index 0000000..b18977b
--- /dev/null
+++ b/seatunnel-ui/src/views/tasks/list/index.tsx
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, onMounted, toRefs } from 'vue'
+import {
+ NButton,
+ NCard,
+ NDataTable,
+ NInput,
+ NPagination,
+ NSpace,
+ NSelect
+} from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useTable } from './use-table'
+
+const TasksList = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const { state, createColumns } = useTable()
+
+ const handleSearch = () => {}
+
+ onMounted(() => {
+ createColumns(state)
+ })
+
+ return { t, handleSearch, ...toRefs(state) }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard title={this.t('tasks.tasks')}>
+ {{
+ 'header-extra': () => (
+ <NSpace>
+ <NInput
+ placeholder={this.t('tasks.tasks_name')}
+ style={{ width: '200px' }}
+ />
+ <NSelect
+ placeholder={this.t('tasks.state')}
+ style={{ width: '200px' }}
+ options={[
+ { label: this.t('tasks.success'), value: 'success' },
+ { label: this.t('tasks.fail'), value: 'fail' },
+ { label: this.t('tasks.running'), value: 'running' }
+ ]}
+ />
+ <NButton onClick={this.handleSearch}>
+ {this.t('tasks.search')}
+ </NButton>
+ </NSpace>
+ )
+ }}
+ </NCard>
+ <NCard>
+ <NSpace vertical>
+ <NDataTable
+ loading={this.loading}
+ columns={this.columns}
+ data={this.tableData}
+ />
+ <NSpace justify='center'>
+ <NPagination
+ v-model:page={this.page}
+ v-model:page-size={this.pageSize}
+ page-count={this.totalPage}
+ show-size-picker
+ page-sizes={[10, 30, 50]}
+ show-quick-jumper
+ />
+ </NSpace>
+ </NSpace>
+ </NCard>
+ </NSpace>
+ )
+ }
+})
+
+export default TasksList
diff --git a/seatunnel-ui/src/views/tasks/list/use-table.ts b/seatunnel-ui/src/views/tasks/list/use-table.ts
new file mode 100644
index 0000000..0ea5683
--- /dev/null
+++ b/seatunnel-ui/src/views/tasks/list/use-table.ts
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { useI18n } from 'vue-i18n'
+import { h, reactive, ref } from 'vue'
+import { NButton, NSpace, NTag, NIcon } from 'naive-ui'
+import { UploadOutlined, DownloadOutlined } from '@vicons/antd'
+
+export function useTable() {
+ const { t } = useI18n()
+
+ const state = reactive({
+ columns: [],
+ tableData: [{ state: 'success' }, { state: 'fail' }, { state: 'running' }],
+ page: ref(1),
+ pageSize: ref(10),
+ totalPage: ref(1),
+ loading: ref(false)
+ })
+
+ const createColumns = (state: any) => {
+ state.columns = [
+ {
+ title: t('tasks.task_name'),
+ key: 'task_name'
+ },
+ {
+ title: t('tasks.state'),
+ key: 'state',
+ render: (row: any) => {
+ if (row.state === 'success') {
+ return h(NTag, { type: 'success' }, t('tasks.success'))
+ } else if (row.state === 'fail') {
+ return h(NTag, { type: 'error' }, t('tasks.fail'))
+ } else if (row.state === 'running') {
+ return h(NTag, { type: 'info' }, t('tasks.running'))
+ }
+ }
+ },
+ {
+ title: t('tasks.run_frequency'),
+ key: 'run_frequency'
+ },
+ {
+ title: t('tasks.next_run'),
+ key: 'next_run'
+ },
+ {
+ title: t('tasks.last_run'),
+ key: 'last_run'
+ },
+ {
+ title: t('tasks.last_total_bytes'),
+ key: 'last_total_bytes',
+ render: (row: any) =>
+ h(NSpace, {}, [
+ h(
+ NTag,
+ { type: 'success' },
+ { icon: h(NIcon, {}, h(UploadOutlined)), default: 12 + ' (KB)' }
+ ),
+ h(
+ NTag,
+ { type: 'error' },
+ { icon: h(NIcon, {}, h(DownloadOutlined)), default: 16 + ' (KB)' }
+ )
+ ])
+ },
+ {
+ title: t('tasks.last_total_records'),
+ key: 'last_total_records',
+ render: (row: any) =>
+ h(NSpace, {}, [
+ h(
+ NTag,
+ { type: 'success' },
+ { icon: h(NIcon, {}, h(UploadOutlined)), default: 66 }
+ ),
+ h(
+ NTag,
+ { type: 'error' },
+ { icon: h(NIcon, {}, h(DownloadOutlined)), default: 77 }
+ )
+ ])
+ },
+ {
+ title: t('tasks.operation'),
+ key: 'operation',
+ render: (row: any) =>
+ h(NSpace, null, {
+ default: () => [
+ h(NButton, { text: true }, t('tasks.rerun')),
+ h(NButton, { text: true }, t('tasks.kill')),
+ h(NButton, { text: true }, t('tasks.view_log'))
+ ]
+ })
+ }
+ ]
+ }
+
+ return { state, createColumns }
+}
diff --git a/seatunnel-ui/src/views/user-manage/list/components/delete-modal.tsx b/seatunnel-ui/src/views/user-manage/list/components/delete-modal.tsx
new file mode 100644
index 0000000..4d52eb8
--- /dev/null
+++ b/seatunnel-ui/src/views/user-manage/list/components/delete-modal.tsx
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent } from 'vue'
+import { useI18n } from 'vue-i18n'
+import Modal from '@/components/modal'
+import type { PropType } from 'vue'
+
+const props = {
+ showModal: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ row: {
+ type: Object as PropType<any>,
+ default: {}
+ }
+}
+
+const DeleteModal = defineComponent({
+ props,
+ emits: ['cancelModal', 'confirmModal'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+
+ const handleCancel = () => {
+ ctx.emit('cancelModal', props.showModal)
+ }
+
+ const handleConfirm = () => {
+ ctx.emit('confirmModal')
+ }
+
+ return { t, handleCancel, handleConfirm }
+ },
+ render() {
+ return (
+ <Modal
+ title={this.t('user_manage.delete')}
+ show={this.showModal}
+ onCancel={this.handleCancel}
+ onConfirm={this.handleConfirm}
+ >
+ {{
+ default: () => <span>{this.t('user_manage.user_delete_tips')}</span>
+ }}
+ </Modal>
+ )
+ }
+})
+
+export default DeleteModal
diff --git a/seatunnel-ui/src/views/user-manage/list/components/form-modal.tsx b/seatunnel-ui/src/views/user-manage/list/components/form-modal.tsx
new file mode 100644
index 0000000..d95fc0f
--- /dev/null
+++ b/seatunnel-ui/src/views/user-manage/list/components/form-modal.tsx
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, getCurrentInstance, toRefs, watch } from 'vue'
+import {
+ NForm,
+ NFormItem,
+ NInput,
+ NRadioGroup,
+ NRadio,
+ NIcon,
+ NSpace,
+ NTooltip
+} from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { BulbOutlined } from '@vicons/antd'
+import { useFormModal } from './use-form-modal'
+import Modal from '@/components/modal'
+import type { PropType } from 'vue'
+
+const props = {
+ showModal: {
+ type: Boolean as PropType<boolean>,
+ default: false
+ },
+ status: {
+ type: Number as PropType<number>,
+ default: 0
+ },
+ row: {
+ type: Object as PropType<any>,
+ default: {}
+ }
+}
+
+const FormModal = defineComponent({
+ props,
+ emits: ['cancelModal', 'confirmModal'],
+ setup(props, ctx) {
+ const { t } = useI18n()
+ const { state, handleValidate, clearForm } = useFormModal(props, ctx)
+ const trim = getCurrentInstance()?.appContext.config.globalProperties.trim
+
+ const handleCancel = () => {
+ ctx.emit('cancelModal', props.showModal)
+ }
+
+ const handleConfirm = () => {
+ handleValidate(props.status)
+ }
+
+ watch(
+ () => props.showModal,
+ () => {
+ clearForm()
+ if (props.status === 1) {
+ state.model.id = props.row.id
+ state.model.username = props.row.name
+ state.model.status = props.row.status
+ }
+ state.rules.password.required = props.row.id === undefined
+ }
+ )
+
+ return { t, ...toRefs(state), trim, handleCancel, handleConfirm }
+ },
+ render() {
+ return (
+ <Modal
+ title={
+ this.status === 0
+ ? this.t('user_manage.create')
+ : this.t('user_manage.edit')
+ }
+ show={this.showModal}
+ onCancel={this.handleCancel}
+ onConfirm={this.handleConfirm}
+ confirmDisabled={
+ !this.model.username || (this.status === 0 && !this.model.password)
+ }
+ >
+ {{
+ default: () => (
+ <NForm model={this.model} rules={this.rules} ref='userManageForm'>
+ <NFormItem label={this.t('user_manage.username')} path='username'>
+ <NSpace align='center'>
+ <NInput
+ clearable
+ maxlength='50'
+ show-count
+ allowInput={this.trim}
+ style={{ width: '510px' }}
+ v-model={[this.model.username, 'value']}
+ />
+ <NTooltip placement='right' trigger='hover'>
+ {{
+ default: () => (
+ <span>{this.t('user_manage.username_tips')}</span>
+ ),
+ trigger: () => (
+ <NIcon size='20' style={{ cursor: 'pointer' }}>
+ <BulbOutlined />
+ </NIcon>
+ )
+ }}
+ </NTooltip>
+ </NSpace>
+ </NFormItem>
+ <NFormItem label={this.t('user_manage.password')} path='password'>
+ <NSpace align='center'>
+ <NInput
+ clearable
+ type='password'
+ maxlength='6'
+ show-count
+ allowInput={this.trim}
+ style={{ width: '510px' }}
+ v-model={[this.model.password, 'value']}
+ />
+ <NTooltip placement='right' trigger='hover'>
+ {{
+ default: () => (
+ <span>{this.t('user_manage.password_tips')}</span>
+ ),
+ trigger: () => (
+ <NIcon size='20' style={{ cursor: 'pointer' }}>
+ <BulbOutlined />
+ </NIcon>
+ )
+ }}
+ </NTooltip>
+ </NSpace>
+ </NFormItem>
+ <NFormItem label={this.t('user_manage.status')} path='status'>
+ <NRadioGroup v-model={[this.model.status, 'value']}>
+ <NRadio value={0}>{this.t('user_manage.enable')}</NRadio>
+ <NRadio value={1}>{this.t('user_manage.disable')}</NRadio>
+ </NRadioGroup>
+ </NFormItem>
+ </NForm>
+ )
+ }}
+ </Modal>
+ )
+ }
+})
+
+export default FormModal
diff --git a/seatunnel-ui/src/views/user-manage/list/components/use-form-modal.ts b/seatunnel-ui/src/views/user-manage/list/components/use-form-modal.ts
new file mode 100644
index 0000000..a35aac6
--- /dev/null
+++ b/seatunnel-ui/src/views/user-manage/list/components/use-form-modal.ts
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive, ref, SetupContext } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { userAdd, userUpdate } from '@/service/user'
+
+export function useFormModal(
+ props: any,
+ ctx: SetupContext<('cancelModal' | 'confirmModal')[]>
+) {
+ const { t } = useI18n()
+ const state = reactive({
+ userManageForm: ref(),
+ model: {
+ id: ref(),
+ username: ref(''),
+ password: ref(''),
+ status: ref(0)
+ },
+ rules: {
+ username: {
+ required: true,
+ trigger: ['input', 'blur'],
+ message: t('user_manage.model_validate_tips')
+ },
+ password: {
+ required: true,
+ trigger: ['input', 'blur'],
+ message: t('user_manage.model_validate_tips')
+ }
+ }
+ })
+
+ const handleValidate = (status: number) => {
+ state.userManageForm.validate((errors: any) => {
+ if (errors) return
+
+ status === 0 ? handleAdd() : handleUpdate()
+ })
+ }
+
+ const clearForm = () => {
+ state.model.id = ''
+ state.model.username = ''
+ state.model.password = ''
+ state.model.status = 0
+ }
+
+ const handleAdd = () => {
+ userAdd({
+ username: state.model.username,
+ password: state.model.password,
+ status: state.model.status,
+ type: 0
+ }).then(() => {
+ ctx.emit('confirmModal', props.showModal)
+ })
+ }
+
+ const handleUpdate = () => {
+ userUpdate(state.model.id, {
+ username: state.model.username,
+ password: state.model.password,
+ status: state.model.status,
+ type: 0
+ }).then(() => {
+ ctx.emit('confirmModal', props.showModal)
+ })
+ }
+
+ return { state, handleValidate, clearForm }
+}
diff --git a/seatunnel-ui/src/views/user-manage/list/index.tsx b/seatunnel-ui/src/views/user-manage/list/index.tsx
new file mode 100644
index 0000000..4de902f
--- /dev/null
+++ b/seatunnel-ui/src/views/user-manage/list/index.tsx
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, toRefs, onMounted } from 'vue'
+import { NSpace, NCard, NButton, NDataTable, NPagination } from 'naive-ui'
+import { useI18n } from 'vue-i18n'
+import { useTable } from './use-table'
+import FormModal from './components/form-modal'
+import DeleteModal from './components/delete-modal'
+
+const UserManageList = defineComponent({
+ setup() {
+ const { t } = useI18n()
+ const { state, createColumns, getTableData, handleConfirmDeleteModal } =
+ useTable()
+
+ const handleFormModal = () => {
+ state.showFormModal = true
+ state.status = 0
+ state.row = {}
+ }
+
+ const handleCancelFormModal = () => {
+ state.showFormModal = false
+ }
+
+ const handleConfirmFormModal = () => {
+ state.showFormModal = false
+ requestData()
+ }
+
+ const handleCancelDeleteModal = () => {
+ state.showDeleteModal = false
+ }
+
+ const handlePageSize = () => {
+ state.pageNo = 1
+ requestData()
+ }
+
+ const requestData = () => {
+ getTableData({
+ pageSize: state.pageSize,
+ pageNo: state.pageNo
+ })
+ }
+
+ onMounted(() => {
+ createColumns(state)
+ requestData()
+ })
+
+ return {
+ t,
+ ...toRefs(state),
+ requestData,
+ handleFormModal,
+ handleCancelFormModal,
+ handleConfirmFormModal,
+ handleCancelDeleteModal,
+ handleConfirmDeleteModal,
+ handlePageSize
+ }
+ },
+ render() {
+ return (
+ <NSpace vertical>
+ <NCard title={this.t('user_manage.user_manage')}>
+ {{
+ 'header-extra': () => (
+ <NButton onClick={this.handleFormModal}>
+ {this.t('user_manage.create')}
+ </NButton>
+ )
+ }}
+ </NCard>
+ <NCard>
+ <NSpace vertical>
+ <NDataTable
+ loading={this.loading}
+ columns={this.columns}
+ data={this.tableData}
+ />
+ <NSpace justify='center'>
+ <NPagination
+ v-model:page={this.pageNo}
+ v-model:page-size={this.pageSize}
+ page-count={this.totalPage}
+ show-size-picker
+ page-sizes={[10, 30, 50]}
+ show-quick-jumper
+ onUpdatePage={this.requestData}
+ onUpdatePageSize={this.handlePageSize}
+ />
+ </NSpace>
+ </NSpace>
+ </NCard>
+ <FormModal
+ showModal={this.showFormModal}
+ status={this.status}
+ row={this.row}
+ onCancelModal={this.handleCancelFormModal}
+ onConfirmModal={this.handleConfirmFormModal}
+ />
+ <DeleteModal
+ showModal={this.showDeleteModal}
+ row={this.row}
+ onCancelModal={this.handleCancelDeleteModal}
+ onConfirmModal={this.handleConfirmDeleteModal}
+ />
+ </NSpace>
+ )
+ }
+})
+
+export default UserManageList
diff --git a/seatunnel-ui/src/views/user-manage/list/use-table.ts b/seatunnel-ui/src/views/user-manage/list/use-table.ts
new file mode 100644
index 0000000..f21e0a4
--- /dev/null
+++ b/seatunnel-ui/src/views/user-manage/list/use-table.ts
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { reactive, ref, h } from 'vue'
+import { useAsyncState } from '@vueuse/core'
+import { useI18n } from 'vue-i18n'
+import { NSpace, NButton } from 'naive-ui'
+import { userList, userDelete, userEnable, userDisable } from '@/service/user'
+import type { ResponseTable } from '@/service/types'
+import type { UserDetail } from '@/service/user/types'
+
+export function useTable() {
+ const { t } = useI18n()
+ const state = reactive({
+ columns: [],
+ tableData: [{ username: '' }],
+ pageNo: ref(1),
+ pageSize: ref(10),
+ totalPage: ref(1),
+ row: {},
+ loading: ref(false),
+ showFormModal: ref(false),
+ showDeleteModal: ref(false),
+ status: ref(0)
+ })
+
+ const createColumns = (state: any) => {
+ state.columns = [
+ {
+ title: t('user_manage.username'),
+ key: 'name'
+ },
+ {
+ title: t('user_manage.create_time'),
+ key: 'createTime'
+ },
+ {
+ title: t('user_manage.update_time'),
+ key: 'updateTime'
+ },
+ {
+ title: t('user_manage.operation'),
+ key: 'operation',
+ render: (row: UserDetail) =>
+ h(NSpace, null, {
+ default: () => [
+ h(
+ NButton,
+ { text: true, onClick: () => handleStatus(row) },
+ row.status === 1
+ ? t('user_manage.enable')
+ : t('user_manage.disable')
+ ),
+ h(
+ NButton,
+ { text: true, onClick: () => handleEdit(row) },
+ t('user_manage.edit')
+ ),
+ h(
+ NButton,
+ { text: true, onClick: () => handleDelete(row) },
+ t('user_manage.delete')
+ )
+ ]
+ })
+ }
+ ]
+ }
+
+ const handleStatus = (row: UserDetail) => {
+ const req = row.status === 1 ? userEnable : userDisable
+ req(row.id as number).then(() => {
+ getTableData({
+ pageSize: state.pageSize,
+ pageNo: state.pageNo
+ })
+ })
+ }
+
+ const handleEdit = (row: UserDetail) => {
+ state.showFormModal = true
+ state.status = 1
+ state.row = row
+ }
+
+ const handleDelete = (row: UserDetail) => {
+ state.showDeleteModal = true
+ state.row = row
+ }
+
+ const handleConfirmDeleteModal = () => {
+ if (state.tableData.length === 1 && state.pageNo > 1) {
+ --state.pageNo
+ }
+
+ userDelete((state.row as UserDetail).id as number).then(() => {
+ state.showDeleteModal = false
+ getTableData({
+ pageSize: state.pageSize,
+ pageNo: state.pageNo
+ })
+ })
+ }
+
+ const getTableData = (params: any) => {
+ if (state.loading) return
+ state.loading = true
+ useAsyncState(
+ userList({ ...params }).then(
+ (res: ResponseTable<Array<UserDetail> | []>) => {
+ state.tableData = res.data.data
+ state.totalPage = res.data.totalPage
+ state.loading = false
+ }
+ ),
+ {}
+ )
+ }
+
+ return { state, createColumns, getTableData, handleConfirmDeleteModal }
+}
diff --git a/seatunnel-ui/tailwind.config.js b/seatunnel-ui/tailwind.config.js
new file mode 100644
index 0000000..90a1a03
--- /dev/null
+++ b/seatunnel-ui/tailwind.config.js
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module.exports = {
+ content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
+ darkMode: 'media',
+ theme: {
+ extend: {}
+ },
+ variants: {
+ extend: {}
+ },
+ plugins: []
+}
\ No newline at end of file
diff --git a/seatunnel-ui/tsconfig.json b/seatunnel-ui/tsconfig.json
new file mode 100644
index 0000000..8806a48
--- /dev/null
+++ b/seatunnel-ui/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "moduleResolution": "node",
+ "strict": true,
+ "jsx": "preserve",
+ "sourceMap": true,
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "lib": ["esnext", "dom"],
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"]
+ },
+ "skipLibCheck": true,
+ "types": ["vite/client"],
+ "plugins": [{ "name": "typescript-plugin-css-modules" }]
+ },
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
+}
diff --git a/seatunnel-ui/vite.config.ts b/seatunnel-ui/vite.config.ts
new file mode 100644
index 0000000..48538c9
--- /dev/null
+++ b/seatunnel-ui/vite.config.ts
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineConfig, loadEnv } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import viteCompression from 'vite-plugin-compression'
+import path from 'path'
+
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ viteCompression({
+ verbose: true,
+ disable: false,
+ threshold: 10240,
+ algorithm: 'gzip',
+ ext: '.gz',
+ deleteOriginFile: false
+ })
+ ],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, 'src')
+ }
+ },
+ server: {
+ proxy: {
+ '/api/v1': {
+ target: loadEnv('development', './').VITE_APP_DEV_WEB_URL,
+ changeOrigin: true
+ }
+ }
+ }
+})
\ No newline at end of file
diff --git a/tools/checkstyle/checkStyle.xml b/tools/checkstyle/checkStyle.xml
new file mode 100755
index 0000000..edf2cc0
--- /dev/null
+++ b/tools/checkstyle/checkStyle.xml
@@ -0,0 +1,543 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+ "http://checkstyle.org/dtds/configuration_1_3.dtd">
+<module name="Checker">
+
+ <property name="charset" value="UTF-8"/>
+
+ <property name="severity" value="error"/>
+
+ <property name="fileExtensions" value="java, properties, xml"/>
+
+ <module name="NewlineAtEndOfFile">
+ <!-- windows can use \r\n vs \n, so enforce the most used one ie UNIx style -->
+ <property name="lineSeparator" value="lf"/>
+ </module>
+
+ <property name="localeLanguage" value="en"/>
+
+ <module name="FileTabCharacter">
+ <property name="eachLine" value="true"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <property name="format" value="System\.out\.println"/>
+ <property name="message" value="Prohibit invoking System.out.println in source code !"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <property name="format" value="^\s*\*\s*@author"/>
+ <property name="minimum" value="0"/>
+ <property name="maximum" value="0"/>
+ <property name="message" value="ASF project doesn't allow @author copyright."/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <property name="format"
+ value=".*[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]+.*"/>
+ <property name="message" value="Not allow chinese character !"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <!-- Checks that TODOs don't have stuff in parenthesis, e.g., username. -->
+ <property name="format" value="((//.*)|(\*.*))TODO\("/>
+ <property name="message" value="TODO comments must not include usernames."/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <!-- \s matches whitespace character, $ matches end of line. -->
+ <property name="format" value="\s+$"/>
+ <property name="severity" value="error"/>
+ <property name="message" value="No trailing whitespace allowed."/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <property name="format" value="Throwables.propagate\("/>
+ <property name="message" value="Throwables.propagate is deprecated"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="FileLength">
+ <property name="max" value="3000"/>
+ </module>
+
+ <module name="LineLength">
+ <property name="max" value="500"/>
+ <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
+ </module>
+
+ <module name="SuppressionSingleFilter">
+ <property name="files" value=".*(IT|Test).java"/>
+ <property name="checks" value="MagicNumber"/>
+ </module>
+
+ <module name="SuppressWarningsFilter"/>
+ <module name="TreeWalker">
+ <module name="SuppressWarningsHolder"/>
+ <module name="ImportOrder">
+ <property name="severity" value="error"/>
+ <property name="staticGroups" value="org.apache.seatunnel,org.apache.seatunnel.shade,*,javax,java,scala"/>
+ <property name="groups" value="org.apache.seatunnel,org.apache.seatunnel.shade,*,javax,java,scala"/>
+ <property name="separated" value="true"/>
+ <property name="sortStaticImportsAlphabetically" value="true"/>
+ <property name="option" value="top"/>
+ <property name="tokens" value="STATIC_IMPORT, IMPORT"/>
+ <message key="import.ordering" value="Import {0} appears after other imports that it should precede"/>
+ </module>
+
+ <!-- Prohibit T.getT() methods for standard boxed types -->
+ <module name="Regexp">
+ <property name="format" value="Boolean\.getBoolean"/>
+ <property name="illegalPattern" value="true"/>
+ <property name="message" value="Use System.getProperties() to get system properties."/>
+ </module>
+
+ <module name="Regexp">
+ <property name="format" value="Integer\.getInteger"/>
+ <property name="illegalPattern" value="true"/>
+ <property name="message" value="Use System.getProperties() to get system properties."/>
+ </module>
+
+ <module name="Regexp">
+ <property name="format" value="Long\.getLong"/>
+ <property name="illegalPattern" value="true"/>
+ <property name="message" value="Use System.getProperties() to get system properties."/>
+ </module>
+
+ <!-- IllegalImport cannot blacklist classes so we have to fall back to Regexp. -->
+ <!-- forbid use of commons lang validate -->
+ <module name="Regexp">
+ <property name="format" value="org\.apache\.commons\.lang3\.Validate"/>
+ <property name="illegalPattern" value="true"/>
+ <property name="message"
+ value="Use Guava Checks instead of Commons Validate. Please refer to the coding guidelines."/>
+ </module>
+
+ <module name="Regexp">
+ <property name="format" value="org\.apache\.commons\.lang\."/>
+ <property name="illegalPattern" value="true"/>
+ <property name="message" value="Use commons-lang3 instead of commons-lang."/>
+ </module>
+
+ <module name="Regexp">
+ <property name="format" value="org\.codehaus\.jettison"/>
+ <property name="illegalPattern" value="true"/>
+ <property name="message" value="Use com.fasterxml.jackson instead of jettison."/>
+ </module>
+
+ <module name="IllegalImport">
+ <property name="regexp" value="true"/>
+ <property name="illegalPkgs"
+ value="^com\.google\.api\.client\.repackaged,
+ ^avro\.shaded, ^org\.apache\.hadoop\.hbase\.shaded,
+ ^org\.apache\.hadoop\.shaded,
+ ^javax\.ws\.rs\.ext,
+ ^cc\.concurrent\.mango\.util\.concurrent,
+ ^org\.apache\.curator-test\.shaded,
+ ^com\.sun\.istack,
+ ^org\.jetbrains\.annotations,
+ ^jline\.internal,
+ ^com\.cronutils\.utils,
+ ^javax\.ws\.rs\.ext,
+ ^org\.jboss\.netty\.util\.internal,
+ ^com\.sun\.javafx,
+ ^io\.reactivex\.annotations"/>
+ <property name="illegalClasses"
+ value="^java\.util\.logging\.Logging,
+ ^sun\.misc\.BASE64Encoder,
+ ^sun\.misc\.BASE64Decoder,
+ ^jdk\.internal\.jline\.internal\.Nullable,
+ ^org\.junit\.(?!jupiter\.).+"/>
+ </module>
+
+ <module name="OuterTypeFilename">
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="OneTopLevelClass">
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="NoLineWrap">
+ <property name="severity" value="error"/>
+ </module>
+
+ <!-- Checks for braces around if and else blocks -->
+ <module name="NeedBraces">
+ <property name="severity" value="error"/>
+ <property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
+ </module>
+
+ <module name="LeftCurly">
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="InnerTypeLast"/>
+ <module name="IllegalTokenText">
+ <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
+ <property name="format"
+ value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
+ <property name="message"
+ value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
+ </module>
+
+ <module name="AvoidEscapedUnicodeCharacters">
+ <property name="allowEscapesForControlCharacters" value="true"/>
+ <property name="allowByTailComment" value="true"/>
+ <property name="allowNonPrintableEscapes" value="true"/>
+ </module>
+
+ <module name="EmptyBlock">
+ <property name="option" value="TEXT"/>
+ <property name="tokens" value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
+ </module>
+
+ <module name="OneStatementPerLine"/>
+
+ <module name="MagicNumber">
+ <property name="ignoreHashCodeMethod" value="true"/>
+ </module>
+
+ <module name="MultipleVariableDeclarations"/>
+
+ <module name="ArrayTypeStyle"/>
+
+ <module name="MissingSwitchDefault"/>
+
+ <module name="FallThrough">
+ <!-- Warn about falling through to the next case statement. Similar to
+ javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
+ on the last non-blank line preceding the fallen-into case contains 'fall through' (or
+ some other variants that we don't publicized to promote consistency).
+ -->
+ <property name="reliefPattern"
+ value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <!-- MODIFIERS CHECKS -->
+ <module name="ModifierOrder">
+ <!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
+ 8.4.3. The prescribed order is:
+ public, protected, private, abstract, static, final, transient, volatile,
+ synchronized, native, strictfp
+ -->
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="SeparatorWrap">
+ <property name="tokens" value="DOT"/>
+ <property name="option" value="nl"/>
+ </module>
+
+ <module name="SeparatorWrap">
+ <property name="tokens" value="COMMA"/>
+ <property name="option" value="EOL"/>
+ </module>
+
+ <module name="UnusedImports">
+ <property name="severity" value="error"/>
+ <property name="processJavadoc" value="true"/>
+ <message key="import.unused" value="Unused import: {0}."/>
+ </module>
+
+ <module name="RedundantImport">
+ <!-- Checks for redundant import statements. -->
+ <property name="severity" value="error"/>
+ <message key="import.redundancy" value="Redundant import {0}."/>
+ </module>
+
+ <!-- Require static importing from Preconditions. -->
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="^import com.google.common.base.Preconditions;$"/>
+ <property name="message" value="Static import functions from Guava Preconditions"/>
+ </module>
+
+ <!-- Detect multiple consecutive semicolons (e.g. ";;"). -->
+ <module name="RegexpSinglelineJava">
+ <property name="format" value=";{2,}"/>
+ <property name="message" value="Use one semicolon"/>
+ <property name="ignoreComments" value="true"/>
+ </module>
+
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="throw new \w+Error\("/>
+ <property name="message" value="Avoid throwing error in application code."/>
+ </module>
+
+ <module name="RegexpSinglelineJava">
+ <property name="format" value="Objects\.toStringHelper"/>
+ <property name="message" value="Avoid using Object.toStringHelper. Use ToStringBuilder instead."/>
+ </module>
+
+ <module name="JavadocStyle">
+ <property name="severity" value="error"/>
+ <property name="checkHtml" value="true"/>
+ <property name="endOfSentenceFormat" value=""/>
+ </module>
+
+ <module name="RedundantModifier">
+ <!-- Checks for redundant modifiers on various symbol definitions.
+ See: http://checkstyle.sourceforge.net/config_modifier.html#RedundantModifier
+
+ We exclude METHOD_DEF to allow final methods in final classes to make them more future-proof.
+ -->
+ <property name="tokens" value="VARIABLE_DEF, ANNOTATION_FIELD_DEF, INTERFACE_DEF, CLASS_DEF, ENUM_DEF"/>
+ </module>
+
+ <module name="AvoidStarImport"/>
+
+ <module name="NonEmptyAtclauseDescription"/>
+
+ <!--Checks that classes that override equals() also override hashCode()-->
+ <module name="EqualsHashCode"/>
+ <!--Checks for over-complicated boolean expressions. Currently finds code like if (topic == true), topic || true, !false, etc.-->
+ <module name="SimplifyBooleanExpression"/>
+ <module name="OneStatementPerLine"/>
+ <module name="UnnecessaryParentheses"/>
+ <!--Checks for over-complicated boolean return statements. For example the following code-->
+ <module name="SimplifyBooleanReturn"/>
+
+ <!--Check that the default is after all the cases in producerGroup switch statement-->
+ <module name="DefaultComesLast"/>
+ <!--Detects empty statements (standalone ";" semicolon)-->
+ <module name="EmptyStatement">
+ <property name="severity" value="error"/>
+ </module>
+
+ <!--Checks that long constants are defined with an upper ell-->
+ <module name="UpperEll">
+ <!-- Checks that long constants are defined with an upper ell.-->
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="ConstantName">
+ <property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
+ </module>
+ <!--Checks that local, non-final variable names conform to producerGroup format specified by the format property-->
+ <module name="LocalVariableName">
+ <!-- Validates identifiers for local variables against the expression "^[a-z][a-zA-Z0-9]*$". -->
+ <property name="tokens" value="VARIABLE_DEF"/>
+ <property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
+ <property name="severity" value="error"/>
+ <message key="name.invalidPattern" value="Local variable name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+
+ <!--Validates identifiers for local, final variables, including catch parameters-->
+ <module name="LocalFinalVariableName">
+ <!-- Validates identifiers for local final variables against the expression "^[a-z][a-zA-Z0-9]*$". -->
+ <property name="severity" value="error"/>
+ </module>
+
+ <!--Validates identifiers for non-static fields-->
+ <module name="MemberName">
+ <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+ <message key="name.invalidPattern" value="Member name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+
+ <!--Validates identifiers for class type parameters-->
+ <module name="ClassTypeParameterName">
+ <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
+ <message key="name.invalidPattern" value="Class type name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+
+ <module name="PackageName">
+ <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="ConstantNameCheck">
+ <!-- Validates non-private, static, final fields against the supplied public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
+ <metadata name="altname" value="ConstantName"/>
+ <property name="applyToPublic" value="true"/>
+ <property name="applyToProtected" value="true"/>
+ <property name="applyToPackage" value="true"/>
+ <property name="applyToPrivate" value="false"/>
+ <property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
+ <message key="name.invalidPattern"
+ value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="MemberNameCheck">
+ <!-- Validates non-static members against the supplied expression. -->
+ <metadata name="altname" value="MemberName"/>
+ <property name="applyToPublic" value="true"/>
+ <property name="applyToProtected" value="true"/>
+ <property name="applyToPackage" value="true"/>
+ <property name="applyToPrivate" value="true"/>
+ <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="MethodNameCheck">
+ <!-- Validates identifiers for method names. -->
+ <metadata name="altname" value="MethodName"/>
+ <property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="MethodName">
+ <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
+ <message key="name.invalidPattern" value="Method name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+
+ <module name="EmptyCatchBlock">
+ <property name="exceptionVariableName" value="expected"/>
+ </module>
+
+ <module name="CommentsIndentation"/>
+
+ <module name="ParameterName">
+ <!-- Validates identifiers for method parameters against the expression "^[a-z][a-zA-Z0-9]*$". -->
+ <property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
+ <property name="severity" value="error"/>
+ <message key="name.invalidPattern" value="Parameter name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+
+ <module name="CatchParameterName">
+ <property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
+ <message key="name.invalidPattern" value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+
+ <module name="StaticVariableNameCheck">
+ <!-- Validates static, non-final fields against the supplied expression "^[a-z][a-zA-Z0-9]*_?$". -->
+ <metadata name="altname" value="StaticVariableName"/>
+ <property name="applyToPublic" value="true"/>
+ <property name="applyToProtected" value="true"/>
+ <property name="applyToPackage" value="true"/>
+ <property name="applyToPrivate" value="true"/>
+ <property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="TypeNameCheck">
+ <!-- Validates static, final fields against the expression "^[A-Z][a-zA-Z0-9]*$". -->
+ <metadata name="altname" value="TypeName"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="TypeName">
+ <property name="format" value="(^[A-Z][a-zA-Z0-9]*$)|(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)"/>
+ <message key="name.invalidPattern" value="Type name ''{0}'' must match pattern ''{1}''."/>
+ </module>
+ <module name="MissingOverride"/>
+
+ <!--whitespace-->
+ <module name="GenericWhitespace">
+ <message key="ws.followed" value="GenericWhitespace ''{0}'' is followed by whitespace."/>
+ <message key="ws.preceded" value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
+ <message key="ws.illegalFollow" value="GenericWhitespace ''{0}'' should followed by whitespace."/>
+ <message key="ws.notPreceded" value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
+ </module>
+
+ <module name="Indentation">
+ <property name="basicOffset" value="4"/>
+ <property name="braceAdjustment" value="0"/>
+ <property name="caseIndent" value="4"/>
+ <property name="throwsIndent" value="2"/>
+ <property name="lineWrappingIndentation" value="4"/>
+ <property name="arrayInitIndent" value="4"/>
+ </module>
+
+ <module name="NoFinalizer"/>
+
+ <module name="NoWhitespaceAfter">
+ <!-- Checks that there is no whitespace after various unary operators.
+ Linebreaks are allowed.
+ -->
+ <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/>
+ <property name="allowLineBreaks" value="true"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="WhitespaceAfter">
+ <!-- Checks that commas, semicolons and typecasts are followed by
+ whitespace.
+ -->
+ <property name="tokens" value="COMMA, SEMI, TYPECAST"/>
+ </module>
+
+ <module name="WhitespaceAround">
+ <!-- Checks that various tokens are surrounded by whitespace.
+ This includes most binary operators and keywords followed
+ by regular or curly braces.
+ -->
+ <property name="allowEmptyConstructors" value="true"/>
+ <property name="allowEmptyMethods" value="true"/>
+ <property name="allowEmptyTypes" value="true"/>
+ <property name="allowEmptyLoops" value="true"/>
+ <property name="severity" value="error"/>
+ <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
+ BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
+ EQUAL, GE, GT, LAMBDA, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
+ LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
+ LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
+ MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
+ SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN, TYPE_EXTENSION_AND"/>
+ <message key="ws.notFollowed"
+ value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
+ <message key="ws.notPreceded" value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
+ </module>
+
+ <module name="MethodParamPad"/>
+ <module name="ParenPad">
+ <!-- Checks that there is no whitespace before close parens or after open parens. -->
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="NoWhitespaceBefore">
+ <!-- Checks that there is no whitespace before various unary operators. Linebreaks are allowed. -->
+ <property name="tokens" value="COMMA, SEMI, DOT, POST_DEC, POST_INC, ELLIPSIS, METHOD_REF"/>
+ <property name="allowLineBreaks" value="true"/>
+ <property name="severity" value="error"/>
+ </module>
+
+ <module name="OperatorWrap">
+ <!-- Checks that assignment operators are at the end of the line. -->
+ <property name="option" value="eol"/>
+ <property name="tokens"
+ value="ASSIGN, BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LE, LITERAL_INSTANCEOF, LT, MINUS, MOD, NOT_EQUAL, QUESTION, SL, SR, STAR, METHOD_REF"/>
+ </module>
+
+ <module name="AnnotationLocation">
+ <property name="allowSamelineMultipleAnnotations" value="false"/>
+ <property name="allowSamelineSingleParameterlessAnnotation" value="false"/>
+ <property name="allowSamelineParameterizedAnnotation" value="true"/>
+ <property name="tokens" value="METHOD_DEF, CTOR_DEF, VARIABLE_DEF, CLASS_DEF, INTERFACE_DEF, ENUM_DEF"/>
+ </module>
+
+ <module name="TypecastParenPad"/>
+
+ <module name="EmptyLineSeparator">
+ <!-- Checks for empty line separator between tokens. The only
+ excluded token is VARIABLE_DEF, allowing class fields to
+ be declared on consecutive lines.
+ -->
+ <property name="allowNoEmptyLineBetweenFields" value="true"/>
+ <property name="allowMultipleEmptyLines" value="false"/>
+ <property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
+ <property name="tokens"
+ value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF, STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF"/>
+ </module>
+ </module>
+</module>
diff --git a/tools/dependencies/checkLicense.sh b/tools/dependencies/checkLicense.sh
new file mode 100755
index 0000000..9c8c2ae
--- /dev/null
+++ b/tools/dependencies/checkLicense.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -e
+
+if [ -d "/tmp/seatunnel-dependencies" ]; then
+ rm -rf /tmp/seatunnel-dependencies/*
+fi
+
+./mvnw clean -pl '!seatunnel-dist' --batch-mode --no-snapshot-updates dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=/tmp/seatunnel-dependencies
+
+# List all modules(jars) that belong to the SeaTunnel itself, these will be ignored when checking the dependency
+ls /tmp/seatunnel-dependencies | sort > all-dependencies.txt
+
+echo "start"
+
+# licenses
+echo '=== Self modules: ' && ./mvnw --batch-mode --quiet -Dexec.executable='echo' -Dexec.args='${project.artifactId}-${project.version}.jar' exec:exec | tee self-modules.txt
+
+# Exclude all self modules(jars) to generate all third-party dependencies
+echo '=== Third party dependencies: ' && grep -vf self-modules.txt all-dependencies.txt | sort | uniq | tee third-party-dependencies.txt
+
+# 1. Compare the third-party dependencies with known dependencies, expect that all third-party dependencies are KNOWN
+# and the exit code of the command is 0, otherwise we should add its license to LICENSE file and add the dependency to
+# known-dependencies.txt. 2. Unify the `sort` behaviour: here we'll sort them again in case that the behaviour of `sort`
+# command in target OS is different from what we used to sort the file `known-dependencies.txt`, i.e. "sort the two file
+# using the same command (and default arguments)"
+
+diff -w -B -U0 <(sort < tools/dependencies/known-dependencies.txt) <(sort < third-party-dependencies.txt)
\ No newline at end of file
diff --git a/tools/dependencies/known-dependencies.txt b/tools/dependencies/known-dependencies.txt
new file mode 100644
index 0000000..4f33ba0
--- /dev/null
+++ b/tools/dependencies/known-dependencies.txt
@@ -0,0 +1,81 @@
+HikariCP-4.0.3.jar
+aspectjweaver-1.9.7.jar
+classmate-1.3.1.jar
+commons-collections4-4.4.jar
+commons-lang3-3.4.jar
+config-1.3.3.jar
+guava-19.0.jar
+hibernate-validator-6.2.2.Final.jar
+jackson-annotations-2.12.6.jar
+jackson-core-2.12.6.jar
+jackson-databind-2.12.6.jar
+jackson-datatype-jdk8-2.13.3.jar
+jackson-datatype-jsr310-2.13.3.jar
+jackson-module-parameter-names-2.13.3.jar
+jakarta.annotation-api-1.3.5.jar
+jakarta.servlet-api-4.0.4.jar
+jakarta.validation-api-2.0.2.jar
+jakarta.websocket-api-1.1.2.jar
+javax.annotation-api-1.3.2.jar
+jboss-logging-3.4.1.Final.jar
+jetty-continuation-9.4.46.v20220331.jar
+jetty-http-9.4.46.v20220331.jar
+jetty-io-9.4.46.v20220331.jar
+jetty-security-9.4.46.v20220331.jar
+jetty-server-9.4.46.v20220331.jar
+jetty-servlet-9.4.46.v20220331.jar
+jetty-servlets-9.4.46.v20220331.jar
+jetty-util-9.4.46.v20220331.jar
+jetty-util-ajax-9.4.46.v20220331.jar
+jetty-webapp-9.4.46.v20220331.jar
+jetty-xml-9.4.46.v20220331.jar
+jjwt-api-0.10.7.jar
+jjwt-impl-0.10.7.jar
+jjwt-jackson-0.10.7.jar
+jsoup-1.14.3.jar
+jul-to-slf4j-1.7.36.jar
+log4j-1.2.17.jar
+logback-classic-1.2.11.jar
+logback-core-1.2.11.jar
+mapstruct-1.0.0.Final.jar
+mybatis-3.5.9.jar
+mybatis-spring-2.0.7.jar
+mybatis-spring-boot-autoconfigure-2.2.2.jar
+mybatis-spring-boot-starter-2.2.2.jar
+seatunnel-common-2.1.2.jar
+seatunnel-config-base-2.1.1.jar
+seatunnel-config-shade-2.1.1.jar
+slf4j-api-1.7.25.jar
+slf4j-log4j12-1.7.25.jar
+snakeyaml-1.29.jar
+spring-aop-5.3.20.jar
+spring-beans-5.3.20.jar
+spring-boot-2.6.8.jar
+spring-boot-autoconfigure-2.6.8.jar
+spring-boot-starter-2.6.8.jar
+spring-boot-starter-aop-2.6.8.jar
+spring-boot-starter-jdbc-2.6.3.jar
+spring-boot-starter-jetty-2.6.8.jar
+spring-boot-starter-json-2.6.8.jar
+spring-boot-starter-logging-2.6.8.jar
+spring-boot-starter-web-2.6.8.jar
+spring-context-5.3.20.jar
+spring-core-5.3.20.jar
+spring-expression-5.3.20.jar
+spring-jcl-5.3.20.jar
+spring-jdbc-5.3.15.jar
+spring-plugin-core-1.2.0.RELEASE.jar
+spring-plugin-metadata-1.2.0.RELEASE.jar
+spring-tx-5.3.15.jar
+spring-web-5.3.20.jar
+spring-webmvc-5.3.20.jar
+springfox-core-2.6.1.jar
+springfox-schema-2.6.1.jar
+springfox-spi-2.6.1.jar
+springfox-spring-web-2.6.1.jar
+springfox-swagger-common-2.6.1.jar
+springfox-swagger-ui-2.6.1.jar
+springfox-swagger2-2.6.1.jar
+swagger-annotations-1.5.10.jar
+swagger-models-1.5.10.jar
+tomcat-embed-el-9.0.63.jar
\ No newline at end of file
diff --git a/tools/sonarcheck/check.sh b/tools/sonarcheck/check.sh
new file mode 100644
index 0000000..dc098d5
--- /dev/null
+++ b/tools/sonarcheck/check.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ ! "$SONAR_TOKEN" ]; then
+ echo "SONAR_TOKEN environment is null, skip check"
+ exit 0
+fi
+./mvnw --batch-mode verify sonar:sonar -Dmaven.test.skip=true -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=apache -Dsonar.projectKey=apache_incubator-seatunnel -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120
\ No newline at end of file