├── .env.dev ├── .env.product ├── .env.spring ├── .gitignore ├── .idea ├── .gitignore ├── OhMyScheduler-Console.iml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── LICENSE ├── README.md ├── babel.config.js ├── package.json ├── public ├── favicon.ico └── index.html ├── script ├── deploy.sh └── docker │ ├── Dockerfile │ ├── build.sh │ └── nginx.my.conf ├── src ├── App.vue ├── assets │ ├── banner.jpg │ ├── logo.png │ ├── panduanti.png │ ├── powerjob-console-logo.png │ ├── skip.svg │ ├── start.svg │ └── workflow.png ├── common.js ├── components │ ├── Console.vue │ ├── Welcome.vue │ ├── bar │ │ ├── Navbar.vue │ │ └── Sidebar.vue │ ├── common │ │ ├── DailyTimeIntervalForm.vue │ │ ├── Exporter.vue │ │ ├── InstanceDetail.vue │ │ └── TimeExpressionValidator.vue │ ├── dag │ │ ├── JSEditor.vue │ │ ├── PowerWorkflow.vue │ │ ├── WorkflowEditor.vue │ │ └── WorkflowInstanceDetail.vue │ └── views │ │ ├── ContainerManager.vue │ │ ├── ContainerTemplate.vue │ │ ├── Home.vue │ │ ├── InstanceManager.vue │ │ ├── JobManager.vue │ │ ├── WFInstanceManager.vue │ │ └── WorkflowManager.vue ├── element-variables.scss ├── i18n │ ├── i18n.js │ └── langs │ │ ├── cn.js │ │ ├── en.js │ │ └── index.js ├── iconfont.css ├── iconfont.ttf ├── main.js ├── plugins │ └── element.js ├── router.js ├── store.js └── styles.scss └── vue.config.js /.env.dev: -------------------------------------------------------------------------------- 1 | NODE_ENV = 'dev' 2 | VUE_APP_BASE_URL = "http://localhost:7700" 3 | -------------------------------------------------------------------------------- /.env.product: -------------------------------------------------------------------------------- 1 | NODE_ENV = 'product' 2 | VUE_APP_BASE_URL = "http://remotehost:7700" 3 | -------------------------------------------------------------------------------- /.env.spring: -------------------------------------------------------------------------------- 1 | NODE_ENV = 'spring' 2 | VUE_APP_BASE_URL = "./" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | 6 | 7 | HELP.md 8 | target/ 9 | !.mvn/wrapper/maven-wrapper.jar 10 | !**/src/main/** 11 | !**/src/test/** 12 | 13 | ### STS ### 14 | .apt_generated 15 | .classpath 16 | .factorypath 17 | .project 18 | .settings 19 | .springBeans 20 | .sts4-cache 21 | 22 | ### IntelliJ IDEA ### 23 | .idea 24 | *.iws 25 | *.iml 26 | *.ipr 27 | 28 | ### NetBeans ### 29 | /nbproject/private/ 30 | /nbbuild/ 31 | /dist/ 32 | /nbdist/ 33 | /.nb-gradle/ 34 | build/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | 39 | ### others ### 40 | *.jar 41 | *.log 42 | */.DS_Store 43 | .DS_Store -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml 3 | -------------------------------------------------------------------------------- /.idea/OhMyScheduler-Console.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerJob-Console 2 | 分布式调度与计算框架——PowerJob 前端页面 3 | 4 | 项目文档:https://www.yuque.com/powerjob/guidence 5 | 6 | # 命令 7 | npm run serve(使用 .env.dev ,请求 localhost:7700) 8 | 9 | npm run build(使用 .env.product) 10 | 11 | npm run build_spring(使用 .env.spring,请求 /,构建内置于 SpringBoot 的 vue project) 12 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oms-console", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --mode dev", 7 | "build": "vue-cli-service build --mode product", 8 | "lint": "vue-cli-service lint", 9 | "build_spring": "vue-cli-service build --mode spring" 10 | }, 11 | "dependencies": { 12 | "axios": "^0.19.2", 13 | "core-js": "^3.6.4", 14 | "d3": "^5.14.2", 15 | "dagre-d3": "^0.6.4", 16 | "element-ui": "^2.13.2", 17 | "flyio": "^0.6.14", 18 | "power-workflow": "0.0.17", 19 | "vue": "^2.6.11", 20 | "vue-axios": "^2.1.5", 21 | "vue-i18n": "^8.18.2", 22 | "vue-json-viewer": "^2.2.18", 23 | "vue-monaco-editor": "0.0.19", 24 | "vue-router": "^3.1.6", 25 | "vuex": "^3.1.3" 26 | }, 27 | "devDependencies": { 28 | "@vue/cli-plugin-babel": "~4.3.0", 29 | "@vue/cli-plugin-eslint": "~4.3.0", 30 | "@vue/cli-service": "~4.3.0", 31 | "babel-eslint": "^10.1.0", 32 | "eslint": "^6.7.2", 33 | "eslint-plugin-vue": "^6.2.2", 34 | "node-sass": "^4.9.2", 35 | "sass-loader": "^7.0.3", 36 | "vue-cli-plugin-element": "~1.0.1", 37 | "vue-cli-plugin-element-ui": "~1.1.4", 38 | "vue-template-compiler": "^2.6.11" 39 | }, 40 | "eslintConfig": { 41 | "root": true, 42 | "env": { 43 | "node": true 44 | }, 45 | "extends": [ 46 | "plugin:vue/essential", 47 | "eslint:recommended" 48 | ], 49 | "parserOptions": { 50 | "parser": "babel-eslint" 51 | }, 52 | "rules": {} 53 | }, 54 | "browserslist": [ 55 | "> 1%", 56 | "last 2 versions", 57 | "not dead" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | PowerJob 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /script/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 在根目录运行该脚本文件,自动替换 oms-server 的静态文件 4 | 5 | rm -rf dist 6 | npm run build_spring 7 | rm -rf ../PowerJob/powerjob-server/powerjob-server-starter/src/main/resources/static/* 8 | mv dist/* ../PowerJob/powerjob-server/powerjob-server-starter/src/main/resources/static/ 9 | 10 | -------------------------------------------------------------------------------- /script/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | MAINTAINER tengjiqi@gmail.com 3 | EXPOSE 80 4 | 5 | # 将静态资源拷入镜像 6 | RUN mkdir -p /opt/oms-console 7 | COPY dist /opt/oms-console/dist 8 | # 修改 nginx 配置文件 9 | RUN rm -rf /etc/nginx/conf.d/* 10 | COPY nginx.my.conf /etc/nginx/conf.d/ 11 | -------------------------------------------------------------------------------- /script/docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # -p:允许后面跟一个字符串作为提示 -r:保证读入的是原始内容,不会发生任何转义 3 | read -r -p "请输入Dockedr镜像版本:" version 4 | echo "即将构建的 oms-console 镜像:oms-console:$version" 5 | read -r -p "任意键继续:" 6 | 7 | # 一键部署脚本,请勿挪动脚本 8 | cd `dirname $0`/../.. || exit 9 | 10 | read -r -p "是否进行 npm 构建(y/n):" neednpm 11 | if [ "$neednpm" = "y" ] || [ "$neednpm" = "Y" ]; then 12 | rm -rf dist && rm -rf script/docker/dist 13 | echo "=============================== 安装依赖 ===============================" 14 | npm install 15 | echo "=============================== 构建dist ===============================" 16 | npm run build || exit 17 | sleep 5 18 | echo "=============================== 拷贝dist===============================" 19 | cp -r dist script/docker/dist 20 | fi 21 | echo "=============================== 停止应用 ===============================" 22 | docker stop oms-console 23 | echo "=============================== 删除旧容器 ===============================" 24 | docker container rm oms-console:$version 25 | echo "=============================== 删除旧镜像 ===============================" 26 | docker rmi -f tjqq/oms-console:$version 27 | echo "=============================== 构建新镜像 ===============================" 28 | docker build -t tjqq/oms-console:$version script/docker/. || exit 29 | 30 | echo "=============================== 启动应用 ===============================" 31 | docker run -d -p 80:80 --name oms-console tjqq/oms-console:$version 32 | -------------------------------------------------------------------------------- /script/docker/nginx.my.conf: -------------------------------------------------------------------------------- 1 | # vue 项目的 nginx 配置,将被放到 /etc/nginx/conf.d 目录下,被主配置文件 nginx.conf 加载 2 | server { 3 | listen 80; 4 | server_name localhost; 5 | 6 | #charset koi8-r; 7 | #access_log /var/log/nginx/host.access.log main; 8 | 9 | location / { 10 | root /opt/oms-console/dist; 11 | index index.html; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | 14 | 35 | -------------------------------------------------------------------------------- /src/assets/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/src/assets/banner.jpg -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/panduanti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/src/assets/panduanti.png -------------------------------------------------------------------------------- /src/assets/powerjob-console-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/src/assets/powerjob-console-logo.png -------------------------------------------------------------------------------- /src/assets/skip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/start.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/src/assets/workflow.png -------------------------------------------------------------------------------- /src/common.js: -------------------------------------------------------------------------------- 1 | import i18n from "./i18n/i18n"; 2 | 3 | let timestamp2Str = ts => { 4 | if (ts < 10000) { 5 | return "N/A"; 6 | } 7 | try { 8 | if (ts) { 9 | let time = new Date(ts); 10 | let y = time.getFullYear(); 11 | let M = time.getMonth() + 1; 12 | let d = time.getDate(); 13 | let h = time.getHours(); 14 | let m = time.getMinutes(); 15 | let s = time.getSeconds(); 16 | return y + '-' + addZero(M) + '-' + addZero(d) + ' ' + addZero(h) + ':' + addZero(m) + ':' + addZero(s); 17 | } else { 18 | return ''; 19 | } 20 | }catch (e) { 21 | return "N/A"; 22 | } 23 | }; 24 | 25 | // 公共函数,涉及到 i18n ,放进 common.js 报错,暂时先放在这里吧 26 | let translateInstanceStatus = status => { 27 | switch (status) { 28 | case 1: return i18n.t('message.waitingDispatch'); 29 | case 2: return i18n.t('message.waitingWorkerReceive'); 30 | case 3: return i18n.t('message.running'); 31 | case 4: return i18n.t('message.failed'); 32 | case 5: return i18n.t('message.success'); 33 | case 9: return i18n.t('message.canceled'); 34 | case 10: return i18n.t('message.stopped'); 35 | default: return "unknown"; 36 | } 37 | }; 38 | 39 | let translateWfInstanceStatus = status => { 40 | switch (status) { 41 | case 1: return i18n.t('message.wfWaiting'); 42 | case 2: return i18n.t('message.running'); 43 | case 3: return i18n.t('message.failed'); 44 | case 4: return i18n.t('message.success'); 45 | case 10: return i18n.t('message.stopped'); 46 | default: return "unknown"; 47 | } 48 | }; 49 | 50 | // 更换语言 51 | let switchLanguage = cmd => { 52 | console.log("switch language to %o", cmd); 53 | i18n.locale = cmd; 54 | // 存储到LangStorage 55 | window.localStorage.setItem('oms_lang', cmd) 56 | }; 57 | 58 | function addZero(m) { 59 | return m < 10 ? '0' + m : m; 60 | } 61 | 62 | export default { 63 | timestamp2Str, 64 | translateInstanceStatus, 65 | translateWfInstanceStatus, 66 | switchLanguage 67 | } 68 | -------------------------------------------------------------------------------- /src/components/Console.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | 20 | 26 | -------------------------------------------------------------------------------- /src/components/Welcome.vue: -------------------------------------------------------------------------------- 1 | 98 | 99 | 237 | 238 | 291 | -------------------------------------------------------------------------------- /src/components/bar/Navbar.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 105 | 106 | 143 | -------------------------------------------------------------------------------- /src/components/bar/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 5 | 73 | 74 | 84 | 133 | -------------------------------------------------------------------------------- /src/components/common/DailyTimeIntervalForm.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 89 | 90 | -------------------------------------------------------------------------------- /src/components/common/Exporter.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 76 | 77 | -------------------------------------------------------------------------------- /src/components/common/InstanceDetail.vue: -------------------------------------------------------------------------------- 1 | 283 | 284 | 346 | 347 | 404 | 412 | -------------------------------------------------------------------------------- /src/components/common/TimeExpressionValidator.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 36 | 37 | 40 | -------------------------------------------------------------------------------- /src/components/dag/JSEditor.vue: -------------------------------------------------------------------------------- 1 | 16 | 42 | 60 | 61 | -------------------------------------------------------------------------------- /src/components/dag/PowerWorkflow.vue: -------------------------------------------------------------------------------- 1 | 85 | 448 | -------------------------------------------------------------------------------- /src/components/dag/WorkflowEditor.vue: -------------------------------------------------------------------------------- 1 | 293 | 294 | 772 | 773 | 852 | 853 | 884 | -------------------------------------------------------------------------------- /src/components/dag/WorkflowInstanceDetail.vue: -------------------------------------------------------------------------------- 1 | 139 | 140 | 292 | 293 | 347 | 348 | 363 | -------------------------------------------------------------------------------- /src/components/views/ContainerManager.vue: -------------------------------------------------------------------------------- 1 | 79 | 80 | 233 | 234 | 285 | -------------------------------------------------------------------------------- /src/components/views/ContainerTemplate.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 75 | 76 | 83 | -------------------------------------------------------------------------------- /src/components/views/Home.vue: -------------------------------------------------------------------------------- 1 | 107 | 108 | 172 | 173 | 202 | 203 | 204 | 221 | -------------------------------------------------------------------------------- /src/components/views/InstanceManager.vue: -------------------------------------------------------------------------------- 1 | 155 | 156 | 331 | 332 | 352 | -------------------------------------------------------------------------------- /src/components/views/WFInstanceManager.vue: -------------------------------------------------------------------------------- 1 | 99 | 100 | 208 | 209 | 234 | -------------------------------------------------------------------------------- /src/components/views/WorkflowManager.vue: -------------------------------------------------------------------------------- 1 | 96 | 97 | 242 | 243 | 246 | -------------------------------------------------------------------------------- /src/element-variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | Write your variables here. All available variables can be 3 | found in element-ui/packages/theme-chalk/src/common/var.scss. 4 | For example, to overwrite the theme color: 5 | */ 6 | $--color-primary: teal; 7 | 8 | /* icon font path, required */ 9 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 10 | 11 | @import "~element-ui/packages/theme-chalk/src/index"; 12 | -------------------------------------------------------------------------------- /src/i18n/i18n.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import locale from 'element-ui/lib/locale'; 3 | import VueI18n from 'vue-i18n' 4 | import messages from './langs' 5 | 6 | Vue.use(VueI18n); 7 | //从localStorage中拿到用户的语言选择,如果没有,那默认中文。 8 | const i18n = new VueI18n({ 9 | locale: localStorage.lang || 'cn', 10 | messages, 11 | }); 12 | locale.i18n((key, value) => i18n.t(key, value)); //为了实现element插件的多语言切换 13 | 14 | export default i18n 15 | -------------------------------------------------------------------------------- /src/i18n/langs/cn.js: -------------------------------------------------------------------------------- 1 | import zhLocale from 'element-ui/lib/locale/lang/zh-CN' 2 | const cn = { 3 | message: { 4 | 5 | // common 6 | 'save': '保存', 7 | 'cancel': '取消', 8 | 'confirm': '确定', 9 | 'refresh': '刷新', 10 | 'query': '查询', 11 | 'reset': '重置', 12 | 'bulkImport': '批量导入', 13 | 'keyword': '关键字', 14 | 'run': '运行', 15 | 'edit': '编辑', 16 | 'delete': '删除', 17 | 'success': '成功', 18 | 'failed': '失败', 19 | 'detail': '详情', 20 | 'download': '下载', 21 | 'stop': '停止', 22 | 'back': '返回', 23 | 'all': '全部', 24 | 'more': '| 更多', 25 | 26 | // 欢迎界面 27 | 'appRegister': '执行应用注册', 28 | 'userRegister': '报警用户录入', 29 | 'appNameInputPLH': '请输入应用名称', 30 | 'appName': '应用名称', 31 | 'appPassword': '密码', 32 | 'register': '注册', 33 | 'name': '姓名', 34 | 'phone': '手机号', 35 | 'email': '邮箱地址', 36 | 'webhook': 'WebHook', 37 | 'welcomeTitle': '欢迎使用 PowerJob!', 38 | 'login': '登陆', 39 | 'logout': '退出', 40 | 'changeAppInfo': '修改应用信息', 41 | 'newPassword': '新密码', 42 | 'newPassword2': '确认密码', 43 | 'stayLogged': '保持登录状态', 44 | 45 | 46 | // 左侧tab栏 47 | 'tabHome': '系统首页', 48 | 'tabJobManage': '任务管理', 49 | 'tabJobInstance': '任务实例', 50 | 'tabWorkflowManage': '工作流管理', 51 | 'tabWfInstance': '工作流实例', 52 | 'tabContainerOps': '容器', 53 | 'tabTemplate': '模版生成', 54 | 'tabContainerManager': '容器运维', 55 | 56 | // 系统首页 57 | 'omsServerTime': '调度服务器时间', 58 | 'omsServerTimezone': '调度服务器时区', 59 | 'localBrowserTime': '本地时间', 60 | 'localBrowserTimezone': '本地时区', 61 | 'githubURL': '项目地址', 62 | 'docURL': '文档地址', 63 | 'totalJobNum': '任务总数', 64 | 'runningInstanceNum': '当前运行实例数', 65 | 'recentFailedInstanceNum': '近期失败任务数', 66 | 'workerNum': '集群机器数', 67 | 'workerAddress': '机器地址', 68 | 'cpuLoad': 'CPU 占用', 69 | 'memoryLoad': '内存占用', 70 | 'diskLoad': '磁盘占用', 71 | 'lastActiveTime': '上次在线时间', 72 | 'advanceConfig': '高级设置', 73 | 74 | // 任务管理 75 | 'jobId': '任务 ID', 76 | 'instanceId': '任务实例 ID', 77 | 'jobName': '任务名称', 78 | 'scheduleInfo': '定时信息', 79 | 'executeType': '执行类型', 80 | 'processorType': '处理器类型', 81 | 'status': '状态', 82 | 'operation': '操作', 83 | 'newJob': '新建任务', 84 | 'inputJob': '导入任务', 85 | 'jobDescription': '任务描述', 86 | 'jobParams': '任务参数', 87 | 'timeExpressionType': '时间表达式类型', 88 | 'dispatchStrategy': '分发策略', 89 | 'dispatchStrategyConfig': '分发策略配置', 90 | 'timeExpressionPlaceHolder': 'CRON 填写 CRON 表达式,秒级任务填写整数,API 无需填写', 91 | 'executeConfig': '执行配置', 92 | 'javaProcessorInfoPLH': '全限定类名,eg:tech.powerjob.HelloWordProcessor', 93 | 'containerProcessorInfoPLH': '容器ID#全限定类名,eg:1#tech.powerjob.HelloWordProcessor', 94 | 'shellProcessorInfoPLH': 'SHELL 脚本文件内容', 95 | 'pythonProcessorInfoPLH': 'Python 脚本文件内容', 96 | 'runtimeConfig': '运行时配置', 97 | 'maxInstanceNum': '最大实例数', 98 | 'threadConcurrency': '单机线程并发度', 99 | 'timeout': '运行时间限制(毫秒)', 100 | 'retryConfig': '重试配置', 101 | 'taskRetryTimes': 'Instance 重试次数', 102 | 'subTaskRetryTimes': "Task 重试次数", 103 | 'workerConfig': '机器配置', 104 | 'minCPU': '最低 CPU 核心数', 105 | 'minMemory': '最低内存(GB)', 106 | 'minDisk': '最低磁盘空间(GB)', 107 | 'clusterConfig': '集群配置', 108 | 'designatedWorkerAddress': '执行机器地址', 109 | 'designatedWorkerAddressPLH': '执行机器地址(可选,不指定代表全部;多值英文逗号分割)', 110 | 'maxWorkerNum': '最大执行机器数量', 111 | 'maxWorkerNumPLH': '最大执行机器数量(0代表不限)', 112 | 'alarmConfig': '报警配置', 113 | 'logConfig': '日志配置', 114 | 'logType': '日志类型', 115 | 'logLevel': '日志级别', 116 | 'loggerName': 'Logger名称', 117 | 'alarmSelectorPLH': '选择报警通知人员', 118 | 'standalone': '单机执行', 119 | 'broadcast': '广播执行', 120 | 'map': 'Map执行', 121 | 'mapReduce': 'MapReduce 执行', 122 | 'fixRate': '固定频率(毫秒)', 123 | 'fixDelay': '固定延迟(毫秒)', 124 | 'workflow': '工作流', 125 | 'dailyTimeInterval': '每日固定间隔', 126 | 'validateTimeExpression': '校验定时参数', 127 | 'javaContainer': 'Java(容器)', 128 | 'runHistory': '运行记录', 129 | 'reRun': '重试', 130 | 'builtIn': '内建', 131 | 'external': '外置(动态加载)', 132 | 'interval': '时间间隔', 133 | 'timeRange': '时间范围', 134 | 'weekRange': '星期范围', 135 | 'taskTrackerBehavior':'TaskTracker行为', 136 | 137 | // 任务实例管理 138 | 'wfInstanceId': '工作流实例 ID', 139 | 'normalInstance': '普通任务实例', 140 | 'wfInstance': '工作流任务实例', 141 | 'triggerTime': '触发时间', 142 | 'finishedTime': '结束时间', 143 | 'log': '日志', 144 | 'runningTimes': '运行次数', 145 | 'taskTrackerAddress': 'TaskTracker 地址', 146 | 'startTime': '开始时间', 147 | 'endTime': '结束时间', 148 | 'createdTime': '创建时间', 149 | 'lastModifiedTime': '最后编辑时间', 150 | 'lastReportTime': '最后上报时间', 151 | 'failedCnt':'失败数', 152 | 'expectedTriggerTime': '预计执行时间', 153 | 'result': '任务结果', 154 | 'taskDetail': 'Task 统计', 155 | // 'secondlyJobHistory': '最近 10 条秒级任务历史记录(秒级任务专用)', 156 | 'secondlyJobHistory': '最近 10 条秒级任务历史记录', 157 | 'queriedTaskDetailInfoList':'Task 查询结果记录', 158 | 'subInstanceId': '子任务实例 ID', 159 | 'instanceParams': '任务实例参数', 160 | 'lifeCycle': '生命周期', 161 | 'alertThreshold': '错误阈值', 162 | 'statisticWindow': '统计窗口', 163 | 'silenceWindow': '沉默窗口', 164 | 'runByParameter': '参数运行', 165 | 'enteringParameter': '填写参数', 166 | 167 | 168 | // 工作流管理 169 | 'wfId': '工作流 ID', 170 | 'wfName': '工作流名称', 171 | 'newWorkflow': '新建工作流', 172 | 'wfDescription': '工作流描述', 173 | 'importJob': '导入任务', 174 | 'deleteJob': '删除任务', 175 | 'newStartPoint': '新增起点', 176 | 'newEndPoint': '新增终点', 177 | 'deleteEdge': '删除边', 178 | 'importJobTitle': "请选择需要导入工作流的任务", 179 | 'wfTimeExpressionPLH': 'CRON 填写 CRON 表达式,API 无需填写', 180 | 'import': '导入', 181 | 'ntfClickNeedDeleteNode': '请点击需要删除的节点', 182 | 'ntfClickStartPoint': '请点击起始节点', 183 | 'ntfClickTargetPoint': '请点击目标节点', 184 | 'ntfClickDeleteEdge': '请点击需要删除的边', 185 | 'ntfAddStartPointFirst': '请先添加起点!', 186 | 'ntfInvalidEdge': '非法操作(起点终点相同)!', 187 | 188 | // 工作流实例 189 | 'wfTips': 'tips:点击节点可查看任务实例详情', 190 | 'ntfClickNoInstanceNode': '未生成任务实例,无法查看详情!', 191 | 'wfInitParams': '启动参数', 192 | 193 | // 容器 194 | 'newContainer': '新增容器', 195 | 'containerType': '容器类型', 196 | 'containerGitURL': 'Git 仓库地址', 197 | 'branchName': '分支名称', 198 | 'username': '用户名', 199 | 'oldPassword': '旧密码', 200 | 'password': '密码', 201 | 'containerId': '容器 ID', 202 | 'containerName': '容器名称', 203 | 'containerVersion': '容器版本', 204 | 'deployTime': '部署时间', 205 | 'deploy': '部署', 206 | 'deployedWorkerList': '机器列表', 207 | 'uploadTips': '拖拽或点击文件后会自动上传', 208 | 209 | // 任务实例状态 210 | 'waitingDispatch': '等待派发', 211 | 'waitingWorkerReceive': '等待Worker接收', 212 | 'running': '运行中', 213 | 'stopped': '手动停止', 214 | 'canceled': '手动取消', 215 | 'canceleded': '已取消', 216 | 'wfWaiting': '等待调度', 217 | 'waitingUpstream': '等待上游节点', 218 | 219 | // 新增的提示信息 220 | 'noSelect': '请至少选中一条数据', 221 | 'nodeName': '节点名称', 222 | 'nodeParams': '节点参数', 223 | 'enable': '是否启用', 224 | 'skipWhenFailed': '失败跳过', 225 | 'fullScreen': '全屏', 226 | 'zoomIn': '放大', 227 | 'zoomOut': '缩小', 228 | 'autoFit': '自适应', 229 | 'markerSuccess': '标记成功', 230 | 'restart': '重试', 231 | 'wfContext': '上下文', 232 | 'yes': 'YES', 233 | 'no': 'NO', 234 | 'copy': '复制', 235 | 'export': '导出', 236 | 'condition': '判断节点', 237 | 'workflowChild': '子流程节点', 238 | 'importWorkflowTitle': '工作流节点引入' 239 | }, 240 | ...zhLocale 241 | }; 242 | 243 | export default cn 244 | -------------------------------------------------------------------------------- /src/i18n/langs/en.js: -------------------------------------------------------------------------------- 1 | import enLocale from 'element-ui/lib/locale/lang/en' 2 | 3 | const en = { 4 | message: { 5 | 6 | 'save': 'Save', 7 | 'cancel': 'Cancel', 8 | 'confirm': 'Confirm', 9 | 'refresh': 'Refresh', 10 | 'query': 'Query', 11 | 'reset': 'Reset', 12 | 'bulkImport': 'Bulk Import', 13 | 'keyword': 'Keyword', 14 | 'run': 'Run', 15 | 'edit': 'Edit', 16 | 'delete': 'Delete', 17 | 'success': 'Success', 18 | 'failed': 'Failed', 19 | 'detail': 'Detail', 20 | 'download': 'Download', 21 | 'stop': 'Stop', 22 | 'back': 'Back', 23 | 'all': 'ALL', 24 | 'more': '| More', 25 | 26 | // 欢迎界面 27 | 'appRegister': 'App Registration', 28 | 'userRegister': 'User Registration', 29 | 'appNameInputPLH': 'Enter The AppName', 30 | 'appName': 'AppName', 31 | 'appPassword': 'AppPassword', 32 | 'register': 'Register', 33 | 'name': 'Name', 34 | 'phone': 'Phone', 35 | 'email': 'Email', 36 | 'webhook': 'Webhook', 37 | 'welcomeTitle': 'Welcome to use PowerJob!', 38 | 'login': 'Login', 39 | 'logout': 'Logout', 40 | 'changeAppInfo': 'Change AppInfo', 41 | 'newPassword': 'New Password', 42 | 'newPassword2': 'Check New Password', 43 | 'stayLogged': 'Keep me logged in', 44 | 45 | 'tabHome': 'Home', 46 | 'tabJobManage': 'Job management', 47 | 'tabJobInstance': 'Job instances', 48 | 'tabWorkflowManage': 'Workflow management', 49 | 'tabWfInstance': 'Workflow instances', 50 | 'tabContainerOps': 'Container DevOps', 51 | 'tabTemplate': 'Template generator', 52 | 'tabContainerManager': 'Container Management', 53 | 54 | 'omsServerTime': 'Server Time', 55 | 'omsServerTimezone': 'Server Timezone', 56 | 'localBrowserTime': 'Local Time', 57 | 'localBrowserTimezone': 'Local Timezone', 58 | 'githubURL': 'GitHub Repo', 59 | 'docURL': 'Document Address', 60 | 'totalJobNum': 'Total job num', 61 | 'runningInstanceNum': 'Running instance num', 62 | 'recentFailedInstanceNum': 'Recent failed instance num', 63 | 'workerNum': 'Worker node num', 64 | 'workerAddress': 'Worker address', 65 | 'cpuLoad': 'CPU Load', 66 | 'memoryLoad': 'Memory Load', 67 | 'diskLoad': 'Disk Load', 68 | 'lastActiveTime': 'Last Active Time', 69 | 'advanceConfig': 'Advance Config', 70 | 71 | // JobManage 72 | 'jobId': 'Job ID', 73 | 'instanceId': 'Instance ID', 74 | 'jobName': 'Job name', 75 | 'scheduleInfo': 'Schedule info', 76 | 'executeType': 'Execution type', 77 | 'processorType': 'Processor type', 78 | 'status': 'Status', 79 | 'operation': 'Operation', 80 | 'newJob': 'New job', 81 | 'inputJob': 'Input job', 82 | 'jobDescription': 'Job description', 83 | 'jobParams': 'Job params', 84 | 'timeExpressionType': 'Time expression type', 85 | 'dispatchStrategy': 'Dispatch strategy', 86 | 'dispatchStrategyConfig': 'Dispatch strategy config', 87 | 'timeExpressionPlaceHolder': 'Cron expression or number of millions for fixed_rate/fixed_delay job', 88 | 'executeConfig': 'Execution config', 89 | 'javaProcessorInfoPLH': 'Classname, eg: tech.powerjob.HelloWordProcessor', 90 | 'containerProcessorInfoPLH': 'ContainerID#classname, eg: 1#tech.powerjob.HelloWordProcessor', 91 | 'shellProcessorInfoPLH': 'Shell script', 92 | 'pythonProcessorInfoPLH': 'Python script', 93 | 'runtimeConfig': 'Runtime config', 94 | 'maxInstanceNum': 'Max instance num', 95 | 'threadConcurrency': 'Thread concurrency', 96 | 'timeout': 'Time limit (ms)', 97 | 'retryConfig': 'Retry config', 98 | 'taskRetryTimes': 'Instance retry times', 99 | 'subTaskRetryTimes': "Task retry times", 100 | 'workerConfig': 'Worker config', 101 | 'minCPU': 'MinAvailableCPUCores', 102 | 'minMemory': 'MinMemory(GB)', 103 | 'minDisk': 'MinDisk(GB)', 104 | 'clusterConfig': 'Cluster config', 105 | 'designatedWorkerAddress': 'Designated worker address', 106 | 'designatedWorkerAddressPLH': 'Empty for all workers; ip:port,ip:port for specific', 107 | 'maxWorkerNum': 'Max worker num', 108 | 'maxWorkerNumPLH': '0 means no limit', 109 | 'alarmConfig': 'Alarm config', 110 | 'logConfig': 'Log Config', 111 | 'logType': 'Log Type', 112 | 'logLevel': 'Log Level', 113 | 'loggerName': 'Logger Name', 114 | 'alarmSelectorPLH': 'Alarm receiver(s)', 115 | 'standalone': 'Standalone', 116 | 'broadcast': 'Broadcast', 117 | 'map': 'MAP', 118 | 'mapReduce': 'MapReduce', 119 | 'fixRate': 'Fixed rate (ms)', 120 | 'fixDelay': 'Fixed delay (ms)', 121 | 'workflow': 'Workflow', 122 | 'dailyTimeInterval': 'DailyTimeInterval', 123 | 'validateTimeExpression': 'Validate', 124 | 'javaContainer': 'External', 125 | 'runHistory': 'History', 126 | 'reRun': 'Retry', 127 | 'builtIn': 'BUILT_IN', 128 | 'External': 'EXTERNAL', 129 | 'interval': 'Interval', 130 | 'timeRange': 'TimeRange', 131 | 'weekRange': 'WeekRange', 132 | 133 | // JobInstance 134 | 'wfInstanceId': 'WorkflowInstanceId', 135 | 'normalInstance': 'Normal instance', 136 | 'wfInstance': 'Workflow instance', 137 | 'triggerTime': 'Trigger time', 138 | 'finishedTime': 'Finished time', 139 | 'log': 'Log', 140 | 'runningTimes': 'Running times', 141 | 'taskTrackerAddress': 'TaskTracker address', 142 | 'startTime': 'Start time', 143 | 'endTime': 'End time', 144 | 'createdTime': 'Created Time', 145 | 'lastModifiedTime': 'LastModifiedTime', 146 | 'lastReportTime': 'LastReportTime', 147 | 'failedCnt':'失败次数', 148 | 'expectedTriggerTime': 'Expected trigger time', 149 | 'result': 'Result', 150 | 'taskDetail': 'InstanceTaskStats', 151 | 'secondlyJobHistory': 'Secondly job history', 152 | 'queriedTaskDetailInfoList':'Queried TaskDetailInfo', 153 | 'subInstanceId': 'SubInstanceId', 154 | 'instanceParams': 'InstanceParams', 155 | 'lifeCycle': 'Life cycle', 156 | 'alertThreshold': 'AlertThreshold', 157 | 'statisticWindow': 'StatisticWindow', 158 | 'silenceWindow': 'SilenceWindow', 159 | 'runByParameter': 'Run by parameter', 160 | 'enteringParameter': 'Entering Parameter', 161 | 'taskTrackerBehavior':'TaskTracker Behavior', 162 | 163 | // workflowManage 164 | 'wfId': 'Workflow ID', 165 | 'wfName': 'Workflow name', 166 | 'newWorkflow': 'New workflow', 167 | 'wfDescription': 'Description', 168 | 'importJob': 'Import job', 169 | 'deleteJob': 'Delete job', 170 | 'newStartPoint': 'New starting point', 171 | 'newEndPoint': 'New ending point', 172 | 'deleteEdge': 'Delete edge', 173 | 'importJobTitle': "Select jobs", 174 | 'wfTimeExpressionPLH': 'Cron expression for CRON or empty for API', 175 | 'import': 'Import', 176 | 'ntfClickNeedDeleteNode': 'Please click on the node you want to delete.', 177 | 'ntfClickStartPoint': 'Please click on the start node', 178 | 'ntfClickTargetPoint': 'Please click on the end node', 179 | 'ntfClickDeleteEdge': 'Please click on the edge you want to remove.', 180 | 'ntfAddStartPointFirst': 'Please add the starting point first!', 181 | 'ntfInvalidEdge': 'Illegal operation (same origin and destination)!', 182 | 183 | // workflowInstance 184 | 'wfTips': 'tips:Click on a node to view details of the job instance', 185 | 'ntfClickNoInstanceNode': 'No instances have been generated, and details cannot be viewed!', 186 | 'wfInitParams': 'InitParams', 187 | 188 | // 容器 189 | 'newContainer': 'New container', 190 | 'containerType': 'Type', 191 | 'containerGitURL': 'Git URL', 192 | 'branchName': 'Branch', 193 | 'username': 'Username', 194 | 'oldPassword': 'Old password', 195 | 'password': 'Password', 196 | 'containerId': 'ID', 197 | 'containerName': 'Name', 198 | 'containerVersion': 'Version', 199 | 'deployTime': 'Deployed time', 200 | 'deploy': 'Deploy', 201 | 'deployedWorkerList': 'Worker list', 202 | 'uploadTips': 'Drag and drop or click on the file to upload it automatically', 203 | 204 | // 任务实例状态 205 | 'waitingDispatch': 'Waiting dispatch', 206 | 'waitingWorkerReceive': 'Waiting receive', 207 | 'running': 'Running', 208 | 'stopped': 'Stopped', 209 | 'canceled': 'Canceled', 210 | 'canceleded': 'Canceled', 211 | 'wfWaiting': 'Waiting', 212 | 'waitingUpstream': 'Waiting upstream', 213 | 214 | // 新增的提示信息 215 | 'noSelect': 'Please select at least one data item', 216 | 'nodeName': 'Node name', 217 | 'nodeParams': 'Node parameter', 218 | 'enable': 'Enable', 219 | 'skipWhenFailed': 'Allow skips when failed', 220 | 'fullScreen': 'Full Screen', 221 | 'zoomIn': 'Zoom In', 222 | 'zoomOut': 'Zoom out', 223 | 'autoFit': 'Auto Fit', 224 | 'markerSuccess': 'Marked Success', 225 | 'restart': 'restart', 226 | 'wfContext': 'Context', 227 | 'yes': 'YES', 228 | 'no': 'NO', 229 | 'copy': 'Copy', 230 | 'export': 'Export', 231 | 'condition': 'Condition', 232 | 'workflowChild': 'Subprocesses', 233 | 'importWorkflowTitle': 'importWorkflowTitle' 234 | }, 235 | ...enLocale 236 | }; 237 | 238 | export default en 239 | -------------------------------------------------------------------------------- /src/i18n/langs/index.js: -------------------------------------------------------------------------------- 1 | import en from './en' 2 | import cn from './cn' 3 | export default { 4 | en, 5 | cn 6 | } 7 | -------------------------------------------------------------------------------- /src/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; /* Project id */ 3 | src: url('./iconfont.ttf?t=1644910247420') format('truetype'); 4 | } 5 | 6 | .iconfont { 7 | font-family: "iconfont" !important; 8 | font-size: 14px; 9 | font-style: normal; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | .icon-workflow_:before { 15 | content: "\e60e"; 16 | } 17 | 18 | .icon-panduanti:before { 19 | content: "\e624"; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PowerJob/PowerJob-Console/1acca1e4693a129e6583540d212049eafe23e8ae/src/iconfont.ttf -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import ElementUI from 'element-ui' 4 | import { Message } from 'element-ui'; 5 | import './styles.scss' 6 | import './plugins/element.js' 7 | import i18n from './i18n/i18n' 8 | import './iconfont.css'; 9 | 10 | 11 | // axios 负责统一拦截处理 ResultDTO,fly 负责处理不需要拦截的请求 12 | import axios from 'axios'; 13 | import flyio from 'flyio'; 14 | import router from "./router"; 15 | import store from "./store"; 16 | import common from "./common"; 17 | 18 | Vue.use(ElementUI); 19 | // let baseURL = "http://139.224.83.134:7700"; 20 | let baseURL = process.env.VUE_APP_BASE_URL; 21 | // let baseURL = '/api'; 22 | 23 | let timeout = 10000; 24 | 25 | Vue.prototype.common = common; 26 | /* ******* axios config ******* */ 27 | Vue.prototype.axios = axios; 28 | axios.defaults.baseURL = baseURL; 29 | axios.defaults.timeout = timeout; 30 | /* ******* fly.io config ******* */ 31 | Vue.prototype.flyio = flyio; 32 | flyio.config.baseURL = baseURL; 33 | flyio.config.timeout = timeout; 34 | 35 | Vue.config.productionTip = false; 36 | 37 | new Vue({ 38 | router, 39 | store, 40 | i18n, 41 | render: h => h(App), 42 | }).$mount('#app'); 43 | 44 | //请求发送拦截,没有 appId 要求重新 "登录" 45 | axios.interceptors.request.use((request) => { 46 | 47 | let url = request.url; 48 | let isListAppInfo = url.search("/appInfo/list") !== -1; 49 | let isAppRegister = url.search("/appInfo/save") !== -1; 50 | let isUserRegister = url.search("/user/save") !== -1; 51 | let isAssertAppInfo = url.search("/appInfo/assert") !== -1; 52 | 53 | if (isListAppInfo || isAppRegister || isUserRegister || isAssertAppInfo) { 54 | return request; 55 | } 56 | 57 | let appId = store.state.appInfo.id; 58 | if (appId === undefined || appId === null) { 59 | router.push("/"); 60 | // remove no appId warn due to too much user report this is a bug... 61 | return Promise.reject(); 62 | } 63 | return request; 64 | 65 | }, function (error) { 66 | // Do something with request error 67 | return Promise.reject(error); 68 | }); 69 | 70 | // 请求返回拦截,封装公共处理逻辑 71 | axios.interceptors.response.use((response) => { 72 | if (response.data.success === true) { 73 | return response.data.data; 74 | } 75 | Message.warning("ERROR:" + response.data.message); 76 | return Promise.reject(response.data.msg); 77 | }, (error) => { 78 | Message.error(error.toString()); 79 | return Promise.reject(error); 80 | }); 81 | 82 | export default baseURL; 83 | -------------------------------------------------------------------------------- /src/plugins/element.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Element from 'element-ui' 3 | import '../element-variables.scss' 4 | 5 | Vue.use(Element) 6 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueRouter from 'vue-router' 3 | import Console from "./components/Console"; 4 | 5 | Vue.use(VueRouter); 6 | 7 | const router = new VueRouter({ 8 | routes: [ 9 | { path: "/", redirect: '/welcome' }, 10 | { path: "/welcome", component: () => import('./components/Welcome') }, 11 | { 12 | path: "/oms", component: Console, redirect: "/oms/home", children: [ 13 | // 二级路由 14 | { path: "/oms/home", meta: { title: '主页' }, component: () => import('./components/views/Home') }, 15 | { path: "/oms/job", meta: { title: '任务管理' }, component: () => import('./components/views/JobManager') }, 16 | { path: "/oms/instance", name: "instanceManager", meta: { title: '实例管理' }, component: () => import('./components/views/InstanceManager') }, 17 | { path: "/oms/workflow", meta: { title: '工作流管理' }, component: () => import('./components/views/WorkflowManager') }, 18 | { path: "/oms/wfinstance", meta: { title: '工作流管理' }, component: () => import('./components/views/WFInstanceManager') }, 19 | { path: "/oms/template", meta: { title: '模版生成' }, component: () => import('./components/views/ContainerTemplate') }, 20 | { path: "/oms/containermanage", meta: { title: '容器管理' }, component: () => import('./components/views/ContainerManager') }, 21 | 22 | { path: "/oms/wfInstanceDetail", name: "WorkflowInstanceDetail", meta: { title: '工作流实例详情' }, component: () => import('./components/dag/WorkflowInstanceDetail') }, 23 | { path: "/oms/workflowEditor", name: "workflowEditor", meta: { title: '工作流编辑器' }, component: () => import('./components/dag/WorkflowEditor') } 24 | ] 25 | }, 26 | // 调试用 27 | { path: "/sidebar", component: () => import('./components/bar/Sidebar') }, 28 | { path: "/navbar", component: () => import('./components/bar/Navbar') }, 29 | ] 30 | }); 31 | 32 | // 默认导出,供 main.js 引入,作为项目的路由器 33 | export default router; 34 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue" 2 | import Vuex from "vuex" 3 | 4 | Vue.use(Vuex); 5 | 6 | const store = new Vuex.Store({ 7 | state: { 8 | // 包含两个属性:id和appName 9 | appInfo: {} 10 | }, 11 | // 推荐使用 mutations 改变 store中的值,调用方法:this.$store.commit('initAppInfo', xxx) 12 | mutations: { 13 | initAppInfo(state, appInfo) { 14 | state.appInfo = appInfo; 15 | } 16 | } 17 | }); 18 | 19 | export default store; 20 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* theme color */ 2 | $--color-primary: teal; 3 | 4 | /* icon font path, required */ 5 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 6 | 7 | @import "~element-ui/packages/theme-chalk/src/index"; 8 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devServer: { 3 | proxy: { 4 | '/api': { 5 | target: 'http://localhost:7700', 6 | changeOrigin: true, 7 | pathRewrite: { 8 | '^/api': '' 9 | } 10 | } 11 | } 12 | } 13 | } --------------------------------------------------------------------------------