├── lombok.config ├── images └── logo.png ├── thain-fe ├── .eslintignore ├── public │ └── favicon.ico ├── src │ ├── assets │ │ └── xdata_logo.png │ ├── pages │ │ ├── FlowEditor │ │ │ ├── font │ │ │ │ ├── toolbar-font.eot │ │ │ │ └── toolbar-font.ttf │ │ │ ├── style │ │ │ │ ├── editor.less │ │ │ │ ├── navigator.less │ │ │ │ ├── UploadBase64Input.less │ │ │ │ └── contextmenu.less │ │ │ ├── EditorEdge.ts │ │ │ ├── components │ │ │ │ ├── input │ │ │ │ │ ├── InputProps.ts │ │ │ │ │ ├── LineInput.tsx │ │ │ │ │ ├── UploadBase64Input.tsx │ │ │ │ │ ├── TextareaInput.tsx │ │ │ │ │ └── SelectInput.tsx │ │ │ │ └── Navigator.tsx │ │ │ ├── EditorNode.ts │ │ │ ├── service.ts │ │ │ └── editor.d.ts │ │ ├── Editor │ │ │ ├── readme.md │ │ │ ├── style │ │ │ │ └── itempanel.less │ │ │ └── ComponentDefine.ts │ │ ├── Exception │ │ │ ├── 403 │ │ │ │ ├── locales │ │ │ │ │ ├── zh-CN.ts │ │ │ │ │ └── en-US.ts │ │ │ │ └── index.tsx │ │ │ ├── 404 │ │ │ │ ├── locales │ │ │ │ │ ├── zh-CN.ts │ │ │ │ │ └── en-US.ts │ │ │ │ └── index.tsx │ │ │ └── 500 │ │ │ │ ├── locales │ │ │ │ ├── zh-CN.ts │ │ │ │ └── en-US.ts │ │ │ │ └── index.tsx │ │ ├── User │ │ │ └── Login │ │ │ │ ├── service.ts │ │ │ │ ├── utils │ │ │ │ └── utils.ts │ │ │ │ ├── components │ │ │ │ └── Login │ │ │ │ │ ├── LoginContext.tsx │ │ │ │ │ ├── LoginSubmit.tsx │ │ │ │ │ ├── index.less │ │ │ │ │ └── LoginTab.tsx │ │ │ │ └── style.less │ │ ├── FlowExecution │ │ │ └── List │ │ │ │ ├── table.less │ │ │ │ ├── service.ts │ │ │ │ └── LineChart.tsx │ │ ├── admin │ │ │ ├── service.ts │ │ │ ├── adminService.ts │ │ │ ├── x5configService.ts │ │ │ └── index.tsx │ │ ├── Dashboard │ │ │ ├── LoadingWrapper.tsx │ │ │ ├── RunningJobCountChart.tsx │ │ │ ├── IncreaseJobCountChart.tsx │ │ │ ├── RunningFlowCountChart.tsx │ │ │ └── IncreaseFlowCountChart.tsx │ │ └── Flow │ │ │ └── List │ │ │ ├── service.ts │ │ │ └── TableList.less │ ├── locales │ │ ├── zh-CN │ │ │ ├── editor.ts │ │ │ ├── x5config.ts │ │ │ ├── menu.ts │ │ │ ├── httpCode.ts │ │ │ ├── admin.ts │ │ │ ├── dashboard.ts │ │ │ ├── global.ts │ │ │ └── flowExecution.ts │ │ ├── en-US │ │ │ ├── editor.ts │ │ │ ├── x5config.ts │ │ │ ├── menu.ts │ │ │ ├── admin.ts │ │ │ ├── dashboard.ts │ │ │ ├── httpCode.ts │ │ │ ├── global.ts │ │ │ └── flowExecution.ts │ │ ├── en-US.ts │ │ └── zh-CN.ts │ ├── services │ │ ├── login.ts │ │ └── user.ts │ ├── layouts │ │ └── BlankLayout.tsx │ ├── utils │ │ ├── humpToLine.ts │ │ ├── delay.ts │ │ ├── hooks.ts │ │ ├── Authorized.ts │ │ ├── authority.ts │ │ ├── utils.less │ │ └── utils.ts │ ├── commonModels │ │ ├── FlowAllInfo.ts │ │ ├── JobExecutionModel.ts │ │ ├── FlowExecutionModel.ts │ │ ├── FlowExecutionAllInfo.ts │ │ ├── FlowModel.ts │ │ └── JobModel.ts │ ├── components │ │ ├── PageHeaderWrapper │ │ │ ├── index.less │ │ │ └── index.tsx │ │ ├── Authorized │ │ │ ├── index.tsx │ │ │ ├── AuthorizedRoute.tsx │ │ │ ├── renderAuthorize.ts │ │ │ └── Authorized.tsx │ │ ├── PageLoading │ │ │ └── index.tsx │ │ ├── HeaderDropdown │ │ │ ├── index.less │ │ │ └── index.tsx │ │ ├── SelectLang │ │ │ └── index.less │ │ ├── GlobalFooter │ │ │ ├── index.less │ │ │ └── index.tsx │ │ └── Exception │ │ │ └── typeConfig.ts │ ├── manifest.json │ ├── typings │ │ └── ApiResult.ts │ ├── global.less │ ├── enums │ │ ├── FlowLastRunStatus.ts │ │ └── JobExecutionStatus.ts │ ├── models │ │ ├── setting.ts │ │ └── login.ts │ └── typings.d.ts ├── .prettierrc.js ├── .stylelintrc.js ├── jsconfig.json ├── config │ └── proxy.ts ├── .prettierignore ├── .editorconfig ├── .gitignore ├── tsconfig.json └── .eslintrc.js ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── thain-sdk └── build.gradle ├── thain-core ├── src │ └── main │ │ ├── resources │ │ ├── sql │ │ │ ├── h2 │ │ │ │ ├── init_data.sql │ │ │ │ └── spring_session.sql │ │ │ └── mysql │ │ │ │ ├── init_data.sql │ │ │ │ └── spring_session.sql │ │ └── com │ │ │ └── xiaomi │ │ │ └── thain │ │ │ └── core │ │ │ └── mapper │ │ │ ├── UserMapper.xml │ │ │ ├── X5ConfigMapper.xml │ │ │ ├── FlowOperationLogMapper.xml │ │ │ └── JobMapper.xml │ │ ├── kotlin │ │ └── com │ │ │ └── xiaomi │ │ │ └── thain │ │ │ └── core │ │ │ ├── model │ │ │ ├── dp │ │ │ │ ├── AddFlowOperationLogDp.kt │ │ │ │ └── AddJobDp.kt │ │ │ ├── rq │ │ │ │ ├── AddFlowAndJobsRq.kt │ │ │ │ ├── AddJobRq.kt │ │ │ │ └── AddFlowRq.kt │ │ │ └── dr │ │ │ │ ├── X5ConfigDr.kt │ │ │ │ ├── JobDr.kt │ │ │ │ └── FlowDr.kt │ │ │ ├── mapper │ │ │ ├── X5ConfigMapper.kt │ │ │ ├── JobMapper.kt │ │ │ └── FlowOperationLogMapper.kt │ │ │ ├── entity │ │ │ └── ThainUser.kt │ │ │ ├── constant │ │ │ └── FlowOperationType.kt │ │ │ ├── scheduler │ │ │ └── job │ │ │ │ ├── CleanJob.kt │ │ │ │ └── RetryFlowJob.kt │ │ │ ├── dao │ │ │ ├── UserDao.kt │ │ │ └── X5ConfigDao.kt │ │ │ └── process │ │ │ ├── ProcessEngineStorage.kt │ │ │ └── runtime │ │ │ └── storage │ │ │ └── FlowExecutionStorage.kt │ │ └── java │ │ └── com │ │ └── xiaomi │ │ └── thain │ │ └── core │ │ ├── constant │ │ ├── LogLevel.java │ │ └── FlowExecutionTriggerType.java │ │ ├── mapper │ │ ├── UserMapper.java │ │ ├── JobExecutionMapper.java │ │ └── FlowMapper.java │ │ ├── entity │ │ └── LogEntity.java │ │ ├── scheduler │ │ └── SchedulerEngineConfiguration.java │ │ └── process │ │ └── runtime │ │ ├── notice │ │ └── MailNotice.java │ │ └── executor │ │ └── service │ │ └── FlowService.java ├── build.gradle └── .gitignore ├── settings.gradle ├── thain-server ├── src │ └── main │ │ ├── kotlin │ │ └── com │ │ │ └── xiaomi │ │ │ └── thain │ │ │ └── server │ │ │ ├── model │ │ │ └── rp │ │ │ │ ├── UserRp.kt │ │ │ │ ├── X5ConfigRp.kt │ │ │ │ ├── FlowAllInfoRp.kt │ │ │ │ └── FlowExecutionAllInfoRp.kt │ │ │ ├── service │ │ │ ├── DbUserDetailsServiceImpl.kt │ │ │ └── JobService.kt │ │ │ ├── Application.kt │ │ │ ├── handler │ │ │ └── ThreadLocalUser.kt │ │ │ ├── mapper │ │ │ ├── FlowMapper.kt │ │ │ └── FlowExecutionMapper.kt │ │ │ └── dao │ │ │ └── FlowDao.kt │ │ ├── java │ │ └── com │ │ │ └── xiaomi │ │ │ └── thain │ │ │ └── server │ │ │ ├── model │ │ │ ├── dr │ │ │ │ ├── StatusAndCountDr.java │ │ │ │ ├── SourceAndCountDr.java │ │ │ │ └── StatusAndCountAndTimeDr.java │ │ │ ├── rq │ │ │ │ ├── AddUserRq.java │ │ │ │ ├── UpdateUserRq.java │ │ │ │ ├── X5ConfigRq.java │ │ │ │ └── FlowListRq.java │ │ │ ├── X5Config.java │ │ │ └── dp │ │ │ │ └── X5ConfigDp.java │ │ │ ├── dao │ │ │ ├── JobDao.java │ │ │ └── X5Dao.java │ │ │ ├── mapper │ │ │ └── JobMapper.java │ │ │ └── config │ │ │ ├── ThainDataSource.java │ │ │ └── WebConfig.java │ │ └── resources │ │ ├── quartz.properties │ │ └── com.xiaomi.thain.server.mapper │ │ └── JobMapper.xml └── .gitignore ├── thain-component ├── build.gradle └── src │ └── main │ ├── resources │ └── componentDefineJson │ │ ├── readme.md │ │ ├── std_shell.json │ │ ├── std_x5http.json │ │ ├── std_mail.json │ │ └── std_http.json │ └── kotlin │ └── com │ └── xiaomi │ └── thain │ └── component │ ├── annotation │ └── ThainComponent.kt │ └── util │ └── global.kt ├── thain-common ├── src │ └── main │ │ ├── kotlin │ │ └── com │ │ │ └── xiaomi │ │ │ └── thain │ │ │ └── common │ │ │ ├── utils │ │ │ ├── HostUtils.kt │ │ │ └── global.kt │ │ │ └── model │ │ │ ├── dp │ │ │ └── AddFlowExecutionDp.kt │ │ │ ├── ComponentDefine.kt │ │ │ └── dr │ │ │ └── FlowExecutionDr.kt │ │ └── java │ │ └── com │ │ └── xiaomi │ │ └── thain │ │ └── common │ │ ├── model │ │ ├── rq │ │ │ └── UpdateJobPropertiesRq.java │ │ └── JobExecutionModel.java │ │ ├── exception │ │ ├── X5Exception.java │ │ ├── ThainException.java │ │ ├── JobExecuteException.java │ │ ├── ThainRuntimeException.java │ │ ├── JsonValidateException.java │ │ ├── ThainRepeatExecutionException.java │ │ ├── scheduler │ │ │ ├── ThainSchedulerInitException.java │ │ │ ├── ThainSchedulerException.java │ │ │ └── ThainSchedulerStartException.java │ │ ├── ThainMissRequiredArgumentsException.java │ │ ├── ThainFlowRunningException.java │ │ └── ThainCreateFlowExecutionException.java │ │ ├── constant │ │ ├── JobExecutionStatus.java │ │ ├── FlowSchedulingStatus.java │ │ └── FlowLastRunStatus.java │ │ └── entity │ │ ├── X5Response.java │ │ └── ApiResult.java └── build.gradle ├── version_upgrade.md └── .github └── workflows ├── java.yml └── nodejs.yml /lombok.config: -------------------------------------------------------------------------------- 1 | lombok.val.flagUsage = ALLOW 2 | -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoMi/thain/HEAD/images/logo.png -------------------------------------------------------------------------------- /thain-fe/.eslintignore: -------------------------------------------------------------------------------- 1 | /lambda/ 2 | /scripts 3 | /config 4 | **/editor.js 5 | -------------------------------------------------------------------------------- /thain-fe/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoMi/thain/HEAD/thain-fe/public/favicon.ico -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoMi/thain/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /thain-fe/src/assets/xdata_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoMi/thain/HEAD/thain-fe/src/assets/xdata_logo.png -------------------------------------------------------------------------------- /thain-fe/.prettierrc.js: -------------------------------------------------------------------------------- 1 | const fabric = require('@umijs/fabric'); 2 | 3 | module.exports = { 4 | ...fabric.prettier, 5 | }; 6 | -------------------------------------------------------------------------------- /thain-fe/.stylelintrc.js: -------------------------------------------------------------------------------- 1 | const fabric = require('@umijs/fabric'); 2 | 3 | module.exports = { 4 | ...fabric.stylelint, 5 | }; 6 | -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowEditor/font/toolbar-font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoMi/thain/HEAD/thain-fe/src/pages/FlowEditor/font/toolbar-font.eot -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowEditor/font/toolbar-font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XiaoMi/thain/HEAD/thain-fe/src/pages/FlowEditor/font/toolbar-font.ttf -------------------------------------------------------------------------------- /thain-sdk/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | dependencies { 5 | api project(':thain-common') 6 | } 7 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Editor/readme.md: -------------------------------------------------------------------------------- 1 | # New Thain Editor 2 | 3 | 这个目录下是新的 flow 编辑器 4 | 5 | 之前的/src/pages/FlowEditor 将慢慢替换过去 6 | 7 | ## 目标 8 | 9 | 1. 使用 GGEditor 3.0 10 | 1. 更加组件化,减少耦合 11 | -------------------------------------------------------------------------------- /thain-core/src/main/resources/sql/h2/init_data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO thain_user(user_id, user_name, password_hash, admin) 2 | VALUES ('admin', 'admin', '$2a$10$hm.fwmx.bnV5wMPSWybqGeTj0wBTCrhGPub1dPChRVwCJtT.2y8WG', 1); -------------------------------------------------------------------------------- /thain-core/src/main/resources/sql/mysql/init_data.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO thain_user(user_id, user_name, password_hash, admin) 2 | VALUES ('admin', 'admin', '$2a$10$hm.fwmx.bnV5wMPSWybqGeTj0wBTCrhGPub1dPChRVwCJtT.2y8WG', 1); -------------------------------------------------------------------------------- /thain-fe/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "emitDecoratorMetadata": true, 4 | "experimentalDecorators": true, 5 | "baseUrl": ".", 6 | "paths": { 7 | "@/*": ["./src/*"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /thain-fe/src/locales/zh-CN/editor.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 'editor.retry.settings': '重试设置', 3 | 'editor.retry.is.the.retry.mechanism.enabled': '是否启用重试机制', 4 | 'editor.retry.numbers': '重试次数', 5 | 'editor.retry.time.interval': '重试时间间隔(秒)', 6 | }; 7 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | 5 | rootProject.name = 'thain' 6 | include(':thain-common') 7 | include(':thain-component') 8 | include(':thain-core') 9 | include(':thain-server') 10 | include(':thain-sdk') 11 | -------------------------------------------------------------------------------- /thain-server/src/main/kotlin/com/xiaomi/thain/server/model/rp/UserRp.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.server.model.rp 2 | 3 | data class UserRp( 4 | val userId: String, 5 | val admin: Boolean, 6 | val email: String?, 7 | val username: String 8 | ) 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Dec 11 17:27:49 CST 2019 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /thain-fe/src/locales/en-US/editor.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 'editor.retry.settings': 'retry settings', 3 | 'editor.retry.is.the.retry.mechanism.enabled': 'Is the retry mechanism enabled', 4 | 'editor.retry.numbers': 'retry numbers', 5 | 'editor.retry.time.interval': 'time interval(second)', 6 | }; 7 | -------------------------------------------------------------------------------- /thain-component/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | 5 | dependencies { 6 | api project(':thain-common') 7 | } 8 | tasks.withType(JavaCompile) { 9 | options.encoding = "UTF-8" 10 | options.compilerArgs << "-Xlint:unchecked" 11 | } 12 | description = 'thain-component' 13 | -------------------------------------------------------------------------------- /thain-component/src/main/resources/componentDefineJson/readme.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | 这个目录下的文件都是现有component defineJson 的备份,并不会读 -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/model/dp/AddFlowOperationLogDp.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.model.dp 2 | 3 | class AddFlowOperationLogDp( 4 | val flowId: Long, 5 | val operationType: Int, 6 | val appId: String, 7 | val username: String, 8 | val extraInfo: String 9 | ) { 10 | val id: Long? = null 11 | } 12 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/mapper/X5ConfigMapper.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.mapper 2 | 3 | import com.xiaomi.thain.core.model.dr.X5ConfigDr 4 | 5 | /** 6 | * Date 19-5-17 下午5:22 7 | * 8 | * @author liangyongrui@xiaomi.com 9 | */ 10 | interface X5ConfigMapper { 11 | 12 | fun getX5ConfigByAppId(appId:String): X5ConfigDr? 13 | 14 | } 15 | -------------------------------------------------------------------------------- /thain-fe/src/services/login.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { get } from '@/utils/request'; 7 | 8 | export async function logout() { 9 | get('/api/login/logout'); 10 | } 11 | -------------------------------------------------------------------------------- /thain-fe/src/layouts/BlankLayout.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import React from 'react'; 7 | 8 | const Layout: React.FC = ({ children }) =>
{children}
; 9 | 10 | export default Layout; 11 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/403/locales/zh-CN.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'exception-403.exception.back': '返回首页', 8 | 'exception-403.description.403': '抱歉,你无权访问该页面', 9 | }; 10 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/404/locales/zh-CN.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'exception-404.exception.back': '返回首页', 8 | 'exception-404.description.404': '抱歉,你访问的页面不存在', 9 | }; 10 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/500/locales/zh-CN.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'exception-500.exception.back': '返回首页', 8 | 'exception-500.description.500': '抱歉,服务器出错了', 9 | }; 10 | -------------------------------------------------------------------------------- /thain-fe/src/utils/humpToLine.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | /** 7 | *小驼峰转换下划线 8 | */ 9 | export function humpToLine(name: string) { 10 | return name.replace(/([A-Z])/g, '_$1').toUpperCase(); 11 | } 12 | -------------------------------------------------------------------------------- /thain-common/src/main/kotlin/com/xiaomi/thain/common/utils/HostUtils.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.common.utils 2 | 3 | import java.net.InetAddress 4 | 5 | /** 6 | * @author liangyongrui 7 | */ 8 | object HostUtils { 9 | val hostInfo: String 10 | get() = try { 11 | InetAddress.getLocalHost().toString() 12 | } catch (e: Exception) { 13 | "unknown" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/model/rq/AddFlowAndJobsRq.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.model.rq 2 | 3 | /** 4 | * Date 19-7-9 下午8:14 5 | * 6 | * @author liangyongrui@xiaomi.com 7 | */ 8 | data class AddFlowAndJobsRq( 9 | /** 10 | * 为了兼容前端和旧的sdk 所以叫flowModel 和 jobModelList 11 | */ 12 | val flowModel: AddFlowRq, 13 | val jobModelList: List 14 | ) 15 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/entity/ThainUser.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.entity 2 | 3 | /** 4 | * Date 2019/8/9 下午3:42 5 | * 6 | * @author liangyongrui@xiaomi.com 7 | */ 8 | class ThainUser( 9 | val id: Long, 10 | val userId: String?, 11 | val userName: String?, 12 | val passwordHash: String?, 13 | val email: String?, 14 | val admin: Boolean 15 | ) 16 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/500/locales/en-US.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'exception-500.exception.back': 'Back to home', 8 | 'exception-500.description.500': 'Sorry, the server is reporting an error', 9 | }; 10 | -------------------------------------------------------------------------------- /thain-server/src/main/kotlin/com/xiaomi/thain/server/model/rp/X5ConfigRp.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.server.model.rp 2 | 3 | /** 4 | * @author wangsimin3@xiaomi.com 5 | * @date 2019/10/24 6 | */ 7 | data class X5ConfigRp( 8 | val appId: String, 9 | val appName: String, 10 | val appKey: String, 11 | val principals: List, 12 | val description: String?, 13 | val createTime: Long 14 | ) 15 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/403/locales/en-US.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'exception-403.exception.back': 'Back to home', 8 | 'exception-403.description.403': "Sorry, you don't have access to this page", 9 | }; 10 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/404/locales/en-US.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'exception-404.exception.back': 'Back to home', 8 | 'exception-404.description.404': 'Sorry, the page you visited does not exist', 9 | }; 10 | -------------------------------------------------------------------------------- /version_upgrade.md: -------------------------------------------------------------------------------- 1 | # Version Upgrade 2 | 3 | ## 1.2.x -> 1.3.x 4 | 5 | mysql execution 6 | 7 | ```sql 8 | alter table thain_flow 9 | add retry_number int unsigned default 0 not null comment '重试次数' after scheduling_status, 10 | add retry_time_interval int unsigned default 0 not null comment '每次重试的间隔,单位秒' after retry_number; 11 | alter table thain_flow_execution 12 | add variables text null comment '执行时赋予的变量' after trigger_type; 13 | ``` 14 | -------------------------------------------------------------------------------- /thain-fe/config/proxy.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | dev: { 8 | '/api/': { 9 | target: 'http://localhost:9900/', 10 | changeOrigin: true, 11 | pathRewrite: { '^/': '' }, 12 | }, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /thain-server/src/main/kotlin/com/xiaomi/thain/server/model/rp/FlowAllInfoRp.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.server.model.rp 2 | 3 | import com.xiaomi.thain.core.model.dr.FlowDr 4 | import com.xiaomi.thain.core.model.dr.JobDr 5 | 6 | /** 7 | * Date 19-7-1 上午10:33 8 | * flow model 和 jobModel list 9 | * 10 | * @author liangyongrui@xiaomi.com 11 | */ 12 | class FlowAllInfoRp( 13 | val flowModel: FlowDr, 14 | val jobModelList: List 15 | ) 16 | -------------------------------------------------------------------------------- /thain-component/src/main/kotlin/com/xiaomi/thain/component/annotation/ThainComponent.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.component.annotation 2 | 3 | import java.lang.annotation.Inherited 4 | 5 | /** 6 | * Thain组件 7 | * 8 | * @author liangyongrui@xiaomi.com 9 | */ 10 | @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) 11 | @Target(AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS) 12 | @Inherited 13 | annotation class ThainComponent(val value: String) 14 | -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowEditor/style/editor.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | * 6 | * 2019年03月19日 7 | * @author liangyongrui@xiaomi.com 8 | */ 9 | .editor { 10 | position: relative; 11 | width: 100%; 12 | background: #fff; 13 | user-select: none; 14 | } 15 | -------------------------------------------------------------------------------- /thain-fe/src/commonModels/FlowAllInfo.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { FlowModel } from './FlowModel'; 7 | import { JobModel } from './JobModel'; 8 | 9 | export interface FlowAllInfo { 10 | flowModel: FlowModel; 11 | jobModelList: JobModel[]; 12 | } 13 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/mapper/JobMapper.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.mapper 2 | 3 | import com.xiaomi.thain.core.model.dr.JobDr 4 | import org.apache.ibatis.annotations.Param 5 | 6 | /** 7 | * Date 19-5-17 下午5:22 8 | * 9 | * @author liangyongrui@xiaomi.com 10 | */ 11 | interface JobMapper { 12 | 13 | fun getJobs(@Param("flowId") flowId: Long): List 14 | 15 | fun cleanUpExpiredAndDeletedJob(dataReserveDays: Int): Int 16 | } 17 | -------------------------------------------------------------------------------- /thain-fe/src/pages/User/Login/service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { FromDataType } from './index'; 7 | import { postForm } from '@/utils/request'; 8 | 9 | export async function accountLogin(params: FromDataType) { 10 | return postForm('/api/login', params); 11 | } 12 | -------------------------------------------------------------------------------- /thain-fe/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | **/*.png 3 | **/*.eot 4 | **/*.ttf 5 | **/*.ico 6 | .* 7 | package.json 8 | .umi 9 | .umi-production 10 | **/editor.js 11 | src/service-worker.js 12 | src/components/Authorized/PromiseRender.tsx 13 | /build 14 | /dist 15 | .dockerignore 16 | .DS_Store 17 | .eslintignore 18 | *.png 19 | *.toml 20 | docker 21 | .editorconfig 22 | Dockerfile* 23 | .gitignore 24 | .prettierignore 25 | LICENSE 26 | .eslintcache 27 | *.lock 28 | yarn-error.log 29 | .history 30 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/mapper/FlowOperationLogMapper.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.mapper 2 | 3 | import com.xiaomi.thain.core.model.dp.AddFlowOperationLogDp 4 | import com.xiaomi.thain.core.model.dr.JobDr 5 | import org.apache.ibatis.annotations.Param 6 | 7 | /** 8 | * Date 19-5-17 下午5:22 9 | * 10 | * @author liangyongrui@xiaomi.com 11 | */ 12 | interface FlowOperationLogMapper { 13 | 14 | fun addLog(addFlowOperationLogDp: AddFlowOperationLogDp) 15 | 16 | } 17 | -------------------------------------------------------------------------------- /thain-fe/src/components/PageHeaderWrapper/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | @import '~antd/lib/style/themes/default.less'; 7 | 8 | .content { 9 | margin: 24px 24px 0; 10 | } 11 | 12 | @media screen and (max-width: @screen-sm) { 13 | .content { 14 | margin: 24px 0 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /thain-fe/src/locales/zh-CN/x5config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 'x5config.app.id': 'App Id', 3 | 'x5config.app.key': 'App Key', 4 | 'x5config.app.name': '名称', 5 | 'x5config.app.principal': 'Principal', 6 | 'x5config.app.description': '描述', 7 | 'x5config.app.create.time': '创建时间', 8 | 'x5config.app.add.button': '添加配置', 9 | 'x5config.app.edit.button': '编辑', 10 | 'x5config.app.select.button': '查询', 11 | 'x5config.app.delete.button': '删除', 12 | 'x5config.app.operation': '操作', 13 | 'x5config.app.info': '配置信息', 14 | }; 15 | -------------------------------------------------------------------------------- /thain-fe/src/utils/delay.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | /** 7 | * 延迟函数 8 | * 执行callback 超过 ms 没有改变后 9 | */ 10 | export const delay = (() => { 11 | let timer: NodeJS.Timeout; 12 | return (callback: () => void, ms: number) => { 13 | clearTimeout(timer); 14 | timer = setTimeout(callback, ms); 15 | }; 16 | })(); 17 | -------------------------------------------------------------------------------- /thain-component/src/main/resources/componentDefineJson/std_shell.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": "std", 3 | "name": "shell", 4 | "hidden": false, 5 | "items": [ 6 | { 7 | "property": "shellBase64", 8 | "label": "shell 脚本", 9 | "required": true, 10 | "input": { 11 | "id": "uploadBase64" 12 | } 13 | }, 14 | { 15 | "property": "environmentVariable", 16 | "label": "shell 变量(xxx=yyy 形式,多个用换行隔开)", 17 | "input": { 18 | "id": "textarea" 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /thain-fe/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Thain", 3 | "short_name": "Thain", 4 | "display": "standalone", 5 | "start_url": "./?utm_source=homescreen", 6 | "theme_color": "#002140", 7 | "background_color": "#001529", 8 | "icons": [ 9 | { 10 | "src": "icons/icon-192x192.png", 11 | "sizes": "192x192" 12 | }, 13 | { 14 | "src": "icons/icon-128x128.png", 15 | "sizes": "128x128" 16 | }, 17 | { 18 | "src": "icons/icon-512x512.png", 19 | "sizes": "512x512" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/java.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ${{ matrix.os }} 9 | 10 | strategy: 11 | matrix: 12 | os: [ubuntu-latest, macOS-latest] 13 | java_version: [8, 11] 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Set up JDK ${{matrix.java_version}} 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: ${{matrix.java_version}} 20 | - name: Build with Gradle 21 | run: | 22 | ./gradlew clean build --info 23 | -------------------------------------------------------------------------------- /thain-fe/.editorconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 2 | # This source code is licensed under the Apache License Version 2.0, which 3 | # can be found in the LICENSE file in the root directory of this source tree. 4 | # 5 | # http://editorconfig.org 6 | root = true 7 | 8 | [*] 9 | indent_style = space 10 | indent_size = 2 11 | end_of_line = lf 12 | charset = utf-8 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | 16 | [*.md] 17 | trim_trailing_whitespace = false 18 | 19 | [Makefile] 20 | indent_style = tab 21 | -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowEditor/EditorEdge.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export class EditorEdge { 7 | public id: string = ''; 8 | public index: number = 0; 9 | public readonly shape = 'flow-smoot'; 10 | public source: string = ''; 11 | public target: string = ''; 12 | public sourceAnchor: number = 0; 13 | public targetAnchor: number = 0; 14 | } 15 | -------------------------------------------------------------------------------- /thain-common/src/main/java/com/xiaomi/thain/common/model/rq/UpdateJobPropertiesRq.java: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.common.model.rq; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.NonNull; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * @author liangyongrui 11 | */ 12 | @AllArgsConstructor 13 | @Builder 14 | public class UpdateJobPropertiesRq { 15 | @NonNull 16 | public final Long flowId; 17 | @NonNull 18 | public final String jobName; 19 | @NonNull 20 | public final Map modifyProperties; 21 | } 22 | -------------------------------------------------------------------------------- /thain-fe/src/locales/en-US/x5config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 'x5config.app.id': 'App Id', 3 | 'x5config.app.key': 'App Key', 4 | 'x5config.app.name': 'App Name', 5 | 'x5config.app.principal': 'Accessible', 6 | 'x5config.app.description': 'Description', 7 | 'x5config.app.create.time': 'CreateTime', 8 | 'x5config.app.add.button': 'Add Config', 9 | 'x5config.app.edit.button': 'Edit', 10 | 'x5config.app.select.button': 'Inquire', 11 | 'x5config.app.delete.button': 'Delete', 12 | 'x5config.app.operation': 'Operation', 13 | 'x5config.app.info': 'Config Info', 14 | }; 15 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/dr/StatusAndCountDr.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model.dr; 7 | 8 | import lombok.AllArgsConstructor; 9 | 10 | /** 11 | * @author liangyongrui 12 | */ 13 | @AllArgsConstructor 14 | public class StatusAndCountDr { 15 | public final int status; 16 | public final int count; 17 | } 18 | -------------------------------------------------------------------------------- /thain-core/src/main/java/com/xiaomi/thain/core/constant/LogLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.core.constant; 7 | 8 | /** 9 | * Date 19-5-20 下午6:25 10 | * 日志等级 11 | * 12 | * @author liangyongrui@xiaomi.com 13 | */ 14 | public enum LogLevel { 15 | /** 16 | * 四个等级 17 | */ 18 | DEBUG, 19 | INFO, 20 | WARN, 21 | ERROR 22 | } 23 | -------------------------------------------------------------------------------- /thain-fe/src/typings/ApiResult.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | interface ApiResult { 7 | status: number; 8 | message: string; 9 | data: T; 10 | } 11 | 12 | class TableResult { 13 | public data: T[] = []; 14 | public count: number = 0; 15 | public page: number = 0; 16 | public pageSize: number = 0; 17 | } 18 | 19 | export { ApiResult, TableResult }; 20 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/dr/SourceAndCountDr.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model.dr; 7 | 8 | import lombok.AllArgsConstructor; 9 | 10 | /** 11 | * @author liangyongrui 12 | */ 13 | @AllArgsConstructor 14 | public class SourceAndCountDr { 15 | public final String source; 16 | public final int count; 17 | } 18 | -------------------------------------------------------------------------------- /thain-common/src/main/java/com/xiaomi/thain/common/exception/X5Exception.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.common.exception; 7 | 8 | /** 9 | * @author liangyongrui@xiaomi.com 10 | * @date 19-5-7 下午12:25 11 | */ 12 | public class X5Exception extends RuntimeException { 13 | public X5Exception(String message) { 14 | super(message); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /thain-fe/src/commonModels/JobExecutionModel.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | /** 7 | * 数据库中的thain_job_execution 8 | */ 9 | export interface JobExecutionModel { 10 | id: number; 11 | /** 12 | * 关联job的名称 13 | */ 14 | name?: string; 15 | flowExecutionId: number; 16 | jobId: number; 17 | status: number; 18 | logs: string; 19 | createTime: number; 20 | updateTime: number; 21 | } 22 | -------------------------------------------------------------------------------- /thain-core/src/main/java/com/xiaomi/thain/core/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.core.mapper; 7 | 8 | import com.xiaomi.thain.core.entity.ThainUser; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Date 19-5-17 下午5:22 14 | * 15 | * @author liangyongrui@xiaomi.com 16 | */ 17 | public interface UserMapper { 18 | 19 | List getAdminUsers(); 20 | } 21 | -------------------------------------------------------------------------------- /thain-fe/src/components/Authorized/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import Authorized from './Authorized'; 7 | import Secured from './Secured'; 8 | import check from './CheckPermissions'; 9 | import renderAuthorize from './renderAuthorize'; 10 | 11 | Authorized.Secured = Secured; 12 | Authorized.check = check; 13 | 14 | const RenderAuthorize = renderAuthorize(Authorized); 15 | 16 | export default RenderAuthorize; 17 | -------------------------------------------------------------------------------- /thain-fe/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | **/node_modules 5 | # roadhog-api-doc ignore 6 | /src/utils/request-temp.js 7 | _roadhog-api-doc 8 | 9 | # production 10 | /dist 11 | /.vscode 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | npm-debug.log* 17 | yarn-error.log 18 | 19 | /coverage 20 | .idea 21 | yarn.lock 22 | *bak 23 | .vscode 24 | 25 | # visual studio code 26 | .history 27 | *.log 28 | functions/* 29 | .temp/** 30 | 31 | # umi 32 | .umi 33 | .umi-production 34 | 35 | # screenshot 36 | screenshot 37 | .firebase 38 | .eslintcache 39 | -------------------------------------------------------------------------------- /thain-server/src/main/kotlin/com/xiaomi/thain/server/model/rp/FlowExecutionAllInfoRp.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.server.model.rp 2 | 3 | import com.xiaomi.thain.common.model.JobExecutionModel 4 | import com.xiaomi.thain.common.model.JobModel 5 | import com.xiaomi.thain.common.model.dr.FlowExecutionDr 6 | 7 | /** 8 | * Date 19-7-1 上午10:33 9 | * flow model 和 jobModel list 10 | * 11 | * @author liangyongrui@xiaomi.com 12 | */ 13 | data class FlowExecutionAllInfoRp( 14 | val flowExecutionModel: FlowExecutionDr, 15 | val jobModelList: List, 16 | val jobExecutionModelList: List 17 | ) 18 | -------------------------------------------------------------------------------- /thain-fe/src/components/PageLoading/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import React from 'react'; 7 | import { Spin } from 'antd'; 8 | 9 | // loading components from code split 10 | // https://umijs.org/plugin/umi-plugin-react.html#dynamicimport 11 | const PageLoading: React.FC = () => ( 12 |
13 | 14 |
15 | ); 16 | export default PageLoading; 17 | -------------------------------------------------------------------------------- /thain-component/src/main/resources/componentDefineJson/std_x5http.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": "std", 3 | "name": "x5http", 4 | "hidden": true, 5 | "items": [ 6 | { 7 | "property": "url", 8 | "label": "HTTP URL", 9 | "required": true, 10 | "input": { 11 | "id": "textarea" 12 | } 13 | }, 14 | { 15 | "property": "referenceData", 16 | "label": "流程数据引用", 17 | "input": { 18 | "id": "textarea" 19 | } 20 | }, 21 | { 22 | "property": "resultRegular", 23 | "label": "结果正则", 24 | "input": { 25 | "id": "textarea" 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /thain-fe/src/components/HeaderDropdown/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | @import '~antd/es/style/themes/default.less'; 7 | 8 | .container > * { 9 | background-color: @popover-bg; 10 | border-radius: 4px; 11 | box-shadow: @shadow-1-down; 12 | } 13 | 14 | @media screen and (max-width: @screen-xs) { 15 | .container { 16 | width: 100% !important; 17 | } 18 | .container > * { 19 | border-radius: 0 !important; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowEditor/components/input/InputProps.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | 7 | export interface InputProps { 8 | updateGraph: (key: string, value: string, updateAttributes?: boolean) => void; 9 | attr: string; 10 | value: any; 11 | updateAttributes?: boolean; 12 | selectList?: SelectOptions[]; 13 | onBlurFunction?: Function; 14 | } 15 | 16 | export interface SelectOptions { 17 | name?: string; 18 | id: string; 19 | } 20 | -------------------------------------------------------------------------------- /thain-fe/src/pages/User/Login/utils/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { parse } from 'qs'; 7 | 8 | export function getPageQuery() { 9 | return parse(window.location.href.split('?')[1]); 10 | } 11 | 12 | export function setAuthority(authority: string | string[]) { 13 | const proAuthority = typeof authority === 'string' ? [authority] : authority; 14 | return localStorage.setItem('antd-pro-authority', JSON.stringify(proAuthority)); 15 | } 16 | -------------------------------------------------------------------------------- /thain-component/src/main/kotlin/com/xiaomi/thain/component/util/global.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.component.util 2 | 3 | import com.xiaomi.thain.common.utils.ifNull 4 | 5 | fun formatHttpReferenceData(referenceData: String?, 6 | getStorageValueOrDefault: (String, String, Any) -> Any): Map { 7 | return referenceData.ifNull { "" } 8 | .split(",".toRegex()) 9 | .map { it.trim() } 10 | .map { it.split("[:.]".toRegex()) } 11 | .filter { it.size == 3 } 12 | .map { it[0] to getStorageValueOrDefault(it[1], it[2], "").toString() } 13 | .toMap() 14 | } 15 | -------------------------------------------------------------------------------- /thain-fe/src/commonModels/FlowExecutionModel.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | /** 7 | * 数据库中的 thain_flow_execution 8 | */ 9 | class FlowExecutionModel { 10 | id = 0; 11 | 12 | flowId = 0; 13 | 14 | status = 0; 15 | 16 | hostInfo = ''; 17 | 18 | triggerType = 0; 19 | 20 | variables: { [key: string]: string } | undefined; 21 | 22 | logs = ''; 23 | 24 | createTime = 0; 25 | 26 | updateTime = 0; 27 | } 28 | export default FlowExecutionModel; 29 | -------------------------------------------------------------------------------- /thain-fe/src/utils/hooks.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | /** 7 | * @date 2019年02月28日10:43:33 8 | * @author liangyongrui@xiaomi.com 9 | * 10 | * 通用hooks 11 | */ 12 | 13 | import { useEffect } from 'react'; 14 | 15 | /** 16 | * 相当于之前的componentDidMount 17 | */ 18 | export const useMount = (fn: () => void) => useEffect(() => fn(), []); 19 | /** 20 | * 相当于之前的componentWillUnmount 21 | */ 22 | export const useUnmount = (fn: () => void) => useEffect(() => fn, []); 23 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ${{ matrix.os }} 9 | 10 | strategy: 11 | matrix: 12 | os: [ubuntu-latest, macOS-latest] 13 | node-version: [8.x, 14.x, 16.x] 14 | 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: Use Node.js ${{ matrix.node-version }} 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | - name: npm install, build, and test 22 | run: | 23 | cd thain-fe 24 | npm install 25 | npm run build --if-present 26 | cd .. 27 | env: 28 | CI: true 29 | -------------------------------------------------------------------------------- /thain-fe/src/pages/User/Login/components/Login/LoginContext.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { createContext } from 'react'; 7 | 8 | export interface ILoginContext { 9 | tabUtil?: { 10 | addTab: (id: string) => void; 11 | removeTab: (id: string) => void; 12 | }; 13 | updateActive?: (activeItem: { [key: string]: string } | string) => void; 14 | } 15 | 16 | const LoginContext: React.Context = createContext({}); 17 | 18 | export default LoginContext; 19 | -------------------------------------------------------------------------------- /thain-component/src/main/resources/componentDefineJson/std_mail.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": "std", 3 | "name": "mail", 4 | "hidden": false, 5 | "items": [ 6 | { 7 | "property": "title", 8 | "label": "邮件标题", 9 | "required": true, 10 | "input": { 11 | "id": "textarea" 12 | } 13 | }, 14 | { 15 | "property": "contentHtml", 16 | "label": "邮件内容", 17 | "required": true, 18 | "input": { 19 | "id": "richText" 20 | } 21 | }, 22 | { 23 | "property": "recipient", 24 | "label": "收件人(多个用逗号隔开)", 25 | "required": true, 26 | "input": { 27 | "id": "textarea" 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /thain-fe/src/commonModels/FlowExecutionAllInfo.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { JobModel } from './JobModel'; 7 | import FlowExecutionModel from './FlowExecutionModel'; 8 | import { JobExecutionModel } from './JobExecutionModel'; 9 | 10 | class FlowExecutionAllInfo { 11 | flowExecutionModel: FlowExecutionModel = new FlowExecutionModel(); 12 | 13 | jobModelList: JobModel[] = []; 14 | 15 | jobExecutionModelList: JobExecutionModel[] = []; 16 | } 17 | export default FlowExecutionAllInfo; 18 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/403/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import React from 'react'; 7 | import { formatMessage } from 'umi-plugin-react/locale'; 8 | import Link from 'umi/link'; 9 | import Exception from '@/components/Exception'; 10 | 11 | export default () => ( 12 | 18 | ); 19 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/404/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import React from 'react'; 7 | import { formatMessage } from 'umi-plugin-react/locale'; 8 | import Link from 'umi/link'; 9 | import Exception from '@/components/Exception'; 10 | 11 | export default () => ( 12 | 18 | ); 19 | -------------------------------------------------------------------------------- /thain-fe/src/pages/Exception/500/index.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import React from 'react'; 7 | import { formatMessage } from 'umi-plugin-react/locale'; 8 | import Link from 'umi/link'; 9 | import Exception from '@/components/Exception'; 10 | 11 | export default () => ( 12 | 18 | ); 19 | -------------------------------------------------------------------------------- /thain-fe/src/locales/zh-CN/menu.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'menu.executions': '执行列表', 8 | 'menu.editor': '新建/编辑', 9 | 'menu.flows': '流程列表', 10 | 'menu.dashboard': '仪表盘', 11 | 'menu.home': '首页', 12 | 'menu.login': '登录', 13 | 'menu.exception.403': '403', 14 | 'menu.exception.404': '404', 15 | 'menu.exception.500': '500', 16 | 'menu.account.center': '个人中心', 17 | 'menu.account.settings': '个人设置', 18 | 'menu.account.logout': '退出登录', 19 | 'menu.admin': '管理列表', 20 | }; 21 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/dr/StatusAndCountAndTimeDr.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model.dr; 7 | 8 | import lombok.Builder; 9 | import lombok.NonNull; 10 | 11 | /** 12 | * Date 2019/7/31 下午5:12 13 | * 14 | * @author liangyongrui@xiaomi.com 15 | */ 16 | @Builder(toBuilder = true) 17 | public class StatusAndCountAndTimeDr { 18 | public final int status; 19 | public final long count; 20 | @NonNull 21 | public final String time; 22 | } 23 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/model/dr/X5ConfigDr.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.core.model.dr 7 | 8 | import java.sql.Timestamp 9 | 10 | /** 11 | * @author wangsimin3@xiaomi.com 12 | * @date 2019/10/29 13 | */ 14 | class X5ConfigDr( 15 | val id: Long, 16 | val appId: String, 17 | val appKey: String, 18 | val appName: String, 19 | val principal: String, 20 | val appDescription: String?, 21 | val createTime: Timestamp 22 | ) 23 | -------------------------------------------------------------------------------- /thain-common/src/main/kotlin/com/xiaomi/thain/common/utils/global.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.common.utils 2 | 3 | inline infix fun T?.ifNull(block: (T?) -> T): T { 4 | if (this == null) { 5 | return block(this) 6 | } 7 | return this 8 | } 9 | 10 | fun T?.isNull(): Boolean { 11 | return this == null 12 | } 13 | 14 | fun T?.isNotNull(): Boolean { 15 | return this != null 16 | } 17 | 18 | fun List.copyOf(): List { 19 | return mutableListOf().also { it.addAll(this) } 20 | } 21 | 22 | inline fun T.ifLet(predicate: (T) -> Boolean, transform: (T) -> T): T { 23 | if (predicate(this)) { 24 | return transform(this) 25 | } 26 | return this 27 | } 28 | 29 | -------------------------------------------------------------------------------- /thain-fe/src/utils/Authorized.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import RenderAuthorize from '@/components/Authorized'; 7 | import { getAuthority } from './authority'; 8 | /* eslint-disable eslint-comments/disable-enable-pair */ 9 | /* eslint-disable import/no-mutable-exports */ 10 | let Authorized = RenderAuthorize(getAuthority()); 11 | 12 | // Reload the rights component 13 | const reloadAuthorized = (): void => { 14 | Authorized = RenderAuthorize(getAuthority()); 15 | }; 16 | 17 | export { reloadAuthorized }; 18 | export default Authorized; 19 | -------------------------------------------------------------------------------- /thain-common/src/main/kotlin/com/xiaomi/thain/common/model/dp/AddFlowExecutionDp.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.common.model.dp 2 | 3 | /** 4 | * flowExecution dp 5 | * 6 | * @author liangyongrui@xiaomi.com 7 | */ 8 | data class AddFlowExecutionDp( 9 | /** 10 | * 所属的流程id 11 | */ 12 | val flowId: Long, 13 | /** 14 | * 流程执行状态, 0 等待运行 1 执行中、2 执行结束、3 执行异常 15 | */ 16 | val status: Int, 17 | /** 18 | * 执行机器 19 | */ 20 | val hostInfo: String, 21 | /** 22 | * 触发类型,1手动,2自动调度 23 | */ 24 | val triggerType: Int, 25 | val variables: String?) { 26 | /** 27 | * 自增id 28 | */ 29 | val id: Long? = null 30 | 31 | } 32 | -------------------------------------------------------------------------------- /thain-fe/src/locales/en-US/menu.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'menu.executions': 'Executions', 8 | 'menu.editor': 'New/Editor', 9 | 'menu.flows': 'Flows', 10 | 'menu.dashboard': 'Dashboard', 11 | 'menu.home': 'Home', 12 | 'menu.login': 'Login', 13 | 'menu.exception.403': '403', 14 | 'menu.exception.404': '404', 15 | 'menu.exception.500': '500', 16 | 'menu.account.center': 'User Center', 17 | 'menu.account.settings': 'User Setting', 18 | 'menu.account.logout': 'Logout', 19 | 'menu.admin': 'Admin', 20 | }; 21 | -------------------------------------------------------------------------------- /thain-server/.gitignore: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 2 | # This source code is licensed under the Apache License Version 2.0, which 3 | # can be found in the LICENSE file in the root directory of this source tree. 4 | # 5 | 6 | HELP.md 7 | /target/ 8 | !.mvn/wrapper/maven-wrapper.jar 9 | 10 | ### STS ### 11 | .apt_generated 12 | .classpath 13 | .factorypath 14 | .project 15 | .settings 16 | .springBeans 17 | .sts4-cache 18 | 19 | ### IntelliJ IDEA ### 20 | .idea 21 | *.iws 22 | *.iml 23 | *.ipr 24 | 25 | ### NetBeans ### 26 | /nbproject/private/ 27 | /nbbuild/ 28 | /dist/ 29 | /nbdist/ 30 | /.nb-gradle/ 31 | /build/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | 36 | src/main/resources/static 37 | /shell/job_execution* 38 | 39 | -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowEditor/EditorNode.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export class EditorNode { 7 | public id = ''; 8 | public jobId?: number; 9 | public index = 0; 10 | public attributes: { [props: string]: string } = {}; 11 | public condition = ''; 12 | public callbackUrl = ''; 13 | public category = ''; 14 | public color = '#1890ff'; 15 | public label = ''; 16 | public readonly shape = 'flow-rect'; 17 | public readonly size = '80*48'; 18 | public readonly type = 'node'; 19 | public x = 0; 20 | public y = 0; 21 | public logs = ''; 22 | } 23 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/rq/AddUserRq.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model.rq; 7 | 8 | 9 | import lombok.Builder; 10 | import lombok.NonNull; 11 | 12 | /** 13 | * @author wangsimin@xiaomi.com 14 | */ 15 | @Builder 16 | public class AddUserRq { 17 | @NonNull 18 | public final String userId; 19 | public final boolean admin; 20 | @NonNull 21 | public final String email; 22 | @NonNull 23 | public final String username; 24 | @NonNull 25 | public final String password; 26 | } 27 | -------------------------------------------------------------------------------- /thain-core/src/main/resources/com/xiaomi/thain/core/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /thain-fe/src/components/SelectLang/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | @import '~antd/es/style/themes/default.less'; 7 | 8 | .menu { 9 | :global(.anticon) { 10 | margin-right: 8px; 11 | } 12 | :global(.ant-dropdown-menu-item) { 13 | min-width: 160px; 14 | } 15 | } 16 | 17 | .dropDown { 18 | line-height: @layout-header-height; 19 | vertical-align: top; 20 | cursor: pointer; 21 | > i { 22 | font-size: 16px !important; 23 | transform: none !important; 24 | svg { 25 | position: relative; 26 | top: -1px; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /thain-fe/src/locales/zh-CN/httpCode.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | '200': '服务器成功返回请求的数据。', 8 | '201': '新建或修改数据成功。', 9 | '202': '一个请求已经进入后台排队(异步任务)。', 10 | '204': '删除数据成功。', 11 | '400': '发出的请求有错误,服务器没有进行新建或修改数据的操作。', 12 | '401': '用户没有权限(令牌、用户名、密码错误)。', 13 | '403': '用户得到授权,但是访问是被禁止的。', 14 | '404': '发出的请求针对的是不存在的记录,服务器没有进行操作。', 15 | '406': '请求的格式不可得。', 16 | '410': '请求的资源被永久删除,且不会再得到的。', 17 | '422': '当创建一个对象时,发生一个验证错误。', 18 | '500': '服务器发生错误,请检查服务器。', 19 | '502': '网关错误。', 20 | '503': '服务不可用,服务器暂时过载或维护。', 21 | '504': '网关超时。', 22 | }; 23 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/X5Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model; 7 | 8 | import lombok.Data; 9 | 10 | import java.util.Date; 11 | import javax.annotation.Nullable; 12 | 13 | /** 14 | * @author liangyongrui@xiaomi.com 15 | * @date 19-5-7 上午11:36 16 | */ 17 | @Data 18 | public class X5Config { 19 | @Nullable 20 | private Integer id; 21 | @Nullable 22 | private String appId; 23 | @Nullable 24 | private String appKey; 25 | @Nullable 26 | private Date createTime; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /thain-server/src/main/kotlin/com/xiaomi/thain/server/service/DbUserDetailsServiceImpl.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.server.service 2 | 3 | import com.xiaomi.thain.common.exception.ThainRuntimeException 4 | import com.xiaomi.thain.server.dao.UserDao 5 | import org.springframework.security.core.userdetails.UserDetails 6 | import org.springframework.security.core.userdetails.UserDetailsService 7 | import org.springframework.stereotype.Service 8 | 9 | /** 10 | * @author miaoyu 11 | */ 12 | @Service("DbUserDetailsService") 13 | class DbUserDetailsServiceImpl(private val userDao: UserDao) : UserDetailsService { 14 | override fun loadUserByUsername(userId: String): UserDetails { 15 | return userDao.getUserById(userId) ?: throw ThainRuntimeException("user does not exist") 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /thain-fe/src/pages/FlowExecution/List/table.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | 7 | .waitingRow { 8 | background-color: rgb(177, 175, 146); 9 | } 10 | 11 | .errorRow { 12 | background-color: rgb(255, 192, 192); 13 | } 14 | 15 | .runningRow { 16 | background-color: rgb(253, 255, 192); 17 | } 18 | 19 | .killedRow { 20 | background-color: rgb(192, 219, 255); 21 | } 22 | .errorWaitingRetry { 23 | color: rgb(171, 171, 171); 24 | background-color: rgb(215, 198, 198); 25 | } 26 | 27 | .doNotRunSameTimeRow { 28 | color: rgb(171, 171, 171); 29 | background-color: rgb(233, 235, 240); 30 | } 31 | -------------------------------------------------------------------------------- /thain-core/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | 5 | dependencies { 6 | api project(':thain-component') 7 | api 'com.google.code.gson:gson:2.8.6' 8 | implementation 'org.mybatis:mybatis:3.5.3' 9 | api ('org.quartz-scheduler:quartz:2.3.2'){ 10 | exclude group: 'com.mchange', module: 'c3p0' 11 | exclude group: 'slf4j-api', module: 'slf4j-api' 12 | } 13 | implementation 'org.quartz-scheduler:quartz-jobs:2.3.2' 14 | implementation 'com.mchange:c3p0:0.9.5.4' 15 | implementation 'mysql:mysql-connector-java:8.0.18' 16 | implementation 'com.h2database:h2:1.4.200' 17 | } 18 | tasks.withType(JavaCompile) { 19 | options.encoding = "UTF-8" 20 | options.compilerArgs << "-Xlint:unchecked" 21 | } 22 | description = 'thain-core' 23 | -------------------------------------------------------------------------------- /thain-core/src/main/resources/com/xiaomi/thain/core/mapper/X5ConfigMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /thain-server/src/main/kotlin/com/xiaomi/thain/server/Application.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server 7 | 8 | import org.mybatis.spring.annotation.MapperScan 9 | import org.springframework.boot.SpringApplication 10 | import org.springframework.boot.autoconfigure.SpringBootApplication 11 | 12 | /** 13 | * @author liangyongrui 14 | */ 15 | @MapperScan("com.xiaomi.thain.server.mapper") 16 | @SpringBootApplication(scanBasePackages = ["com.xiaomi.thain"]) 17 | class Application 18 | 19 | fun main(args: Array) { 20 | SpringApplication.run(Application::class.java, *args) 21 | } 22 | -------------------------------------------------------------------------------- /thain-core/src/main/kotlin/com/xiaomi/thain/core/model/dr/JobDr.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.core.model.dr 2 | 3 | import com.alibaba.fastjson.JSON 4 | import com.alibaba.fastjson.TypeReference 5 | import java.sql.Timestamp 6 | 7 | /** 8 | * Date 19-5-20 下午9:00 9 | * 10 | * @author liangyongrui@xiaomi.com 11 | */ 12 | class JobDr( 13 | val id: Long, 14 | val flowId: Long, 15 | val name: String, 16 | val condition: String, 17 | val component: String, 18 | val callbackUrl: String?, 19 | propertiesString: String, 20 | val xAxis: Int, 21 | val yAxis: Int, 22 | val createTime: Timestamp, 23 | val deleted: Boolean 24 | ) { 25 | val properties = JSON.parseObject(propertiesString, object : TypeReference>() {})!! 26 | } 27 | -------------------------------------------------------------------------------- /thain-fe/src/commonModels/FlowModel.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | /** 7 | * 数据库中的thain_flow 8 | */ 9 | export class FlowModel { 10 | id?: number; 11 | name = ''; 12 | cron?: string; 13 | createUser?: string; 14 | callbackEmail?: string; 15 | callbackUrl?: string; 16 | createAppId?: string; 17 | lastRunStatus?: number; 18 | schedulingStatus?: number; 19 | public slaDuration?: number; 20 | public slaEmail?: string; 21 | public slaKill?: boolean; 22 | retryNumber?: number; 23 | retryTimeInterval?: number; 24 | createTime?: number; 25 | updateTime?: number; 26 | statusUpdateTime?: number; 27 | } 28 | -------------------------------------------------------------------------------- /thain-fe/src/pages/admin/service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | import { get, post, del } from '@/utils/request'; 7 | import { ApiResult, TableResult } from '@/typings/ApiResult'; 8 | import { UserModel } from './models/UserAdminModel'; 9 | 10 | export async function addUser(props: UserModel) { 11 | return post('/api/admin/user', props); 12 | } 13 | 14 | export async function getUsers(props: { page?: number; pageSize?: number }) { 15 | return get('/api/admin/users', props); 16 | } 17 | 18 | export async function deleteUser(props: { userId: string }) { 19 | return del(`/api/admin/user/${props.userId}`); 20 | } 21 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/rq/UpdateUserRq.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model.rq; 7 | 8 | import lombok.Builder; 9 | import lombok.NonNull; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | /** 14 | * @author wangsimin3@xiaomi.com 15 | * @date 2019/10/28 16 | */ 17 | @Builder 18 | public class UpdateUserRq { 19 | @NonNull 20 | public final String userId; 21 | public final boolean admin; 22 | @Nullable 23 | public final String email; 24 | @Nullable 25 | public final String username; 26 | @Nullable 27 | public final String password; 28 | } 29 | -------------------------------------------------------------------------------- /thain-fe/src/components/GlobalFooter/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | @import '~antd/lib/style/themes/default.less'; 7 | 8 | .globalFooter { 9 | margin: 48px 0 24px 0; 10 | padding: 0 16px; 11 | text-align: center; 12 | 13 | .links { 14 | margin-bottom: 8px; 15 | 16 | a { 17 | color: @text-color-secondary; 18 | transition: all 0.3s; 19 | 20 | &:not(:last-child) { 21 | margin-right: 40px; 22 | } 23 | 24 | &:hover { 25 | color: @text-color; 26 | } 27 | } 28 | } 29 | 30 | .copyright { 31 | color: @text-color-secondary; 32 | font-size: @font-size-base; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /thain-common/src/main/java/com/xiaomi/thain/common/constant/JobExecutionStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.common.constant; 7 | 8 | /** 9 | * JobExecution的执行状态 10 | * 11 | * @author liangyongrui 12 | */ 13 | public enum JobExecutionStatus { 14 | /** 15 | * 1 未运行 16 | */ 17 | NEVER(1), 18 | /** 19 | * 2 正在运行 20 | */ 21 | RUNNING(2), 22 | /** 23 | * 3 执行成功 24 | */ 25 | SUCCESS(3), 26 | /** 27 | * 4 执行异常 28 | */ 29 | ERROR(4); 30 | 31 | public final int code; 32 | 33 | JobExecutionStatus(int code) { 34 | this.code = code; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /thain-server/src/main/java/com/xiaomi/thain/server/model/dp/X5ConfigDp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | package com.xiaomi.thain.server.model.dp; 7 | 8 | import lombok.Builder; 9 | import lombok.NonNull; 10 | 11 | import javax.annotation.Nullable; 12 | 13 | 14 | /** 15 | * @author wangsimin3@xiaomi.com 16 | * @date 2019/10/25 17 | */ 18 | @Builder 19 | public class X5ConfigDp { 20 | @NonNull 21 | public final String appId; 22 | @NonNull 23 | public final String appKey; 24 | @NonNull 25 | public final String appName; 26 | @Nullable 27 | public final String description; 28 | @NonNull 29 | public final String principal; 30 | } 31 | -------------------------------------------------------------------------------- /thain-fe/src/locales/zh-CN/admin.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019, Xiaomi, Inc. All rights reserved. 3 | * This source code is licensed under the Apache License Version 2.0, which 4 | * can be found in the LICENSE file in the root directory of this source tree. 5 | */ 6 | export default { 7 | 'admin.user.addUser': '添加用户', 8 | 'admin.user.userId': '用户ID', 9 | 'admin.user.userName': '用户名', 10 | 'admin.user.email': '电子邮箱', 11 | 'admin.user.operation': '操作', 12 | 'admin.user.delete': '删除', 13 | 'admin.user.password': '密码', 14 | 'admin.user.admin.yes': '是', 15 | 'admin.user.admin.no': '否', 16 | 'admin.user.cancel': '确认', 17 | 'admin.user.comfirm': '取消', 18 | 'admin.user.admin': '管理员', 19 | 'admin.index.userAdmin': '用户管理', 20 | 'admin.index.ClientAdmin': '客户端管理', 21 | 'admin.user.info': '用户信息', 22 | 'admin.home.index': '管理列表', 23 | 'admin.user.edit': '编辑', 24 | }; 25 | -------------------------------------------------------------------------------- /thain-common/src/main/kotlin/com/xiaomi/thain/common/model/ComponentDefine.kt: -------------------------------------------------------------------------------- 1 | package com.xiaomi.thain.common.model 2 | 3 | 4 | /** 5 | * 组件定义 6 | */ 7 | data class ComponentDefine( 8 | val group: String, 9 | val name: String, 10 | val hidden: Boolean, 11 | val items: List 12 | ) { 13 | data class Item( 14 | /** 15 | * 属性key 16 | */ 17 | val property: String, 18 | val required: Boolean = false, 19 | val label: String, 20 | val input: Input) { 21 | 22 | data class Input(val id: String, 23 | /** 24 | * 只有当id为select时 options才存在 25 | */ 26 | val options: List