Browse Source

update web app

tags/v0.4.0
之江天枢 3 years ago
parent
commit
60083ae4d5
100 changed files with 3566 additions and 1412 deletions
  1. +13
    -3
      webapp/.env.development
  2. +12
    -2
      webapp/.env.mock
  3. +13
    -4
      webapp/.env.production
  4. +10
    -1
      webapp/.env.test
  5. +3
    -1
      webapp/.eslintignore
  6. +21
    -45
      webapp/.eslintrc.js
  7. +2
    -2
      webapp/mock/api/v1/data/datasets/count.js
  8. +8
    -0
      webapp/mock/api/v1/train/trainJobDelete.js
  9. +2
    -1
      webapp/mock/mock-map.js
  10. +11
    -3
      webapp/package.json
  11. +14
    -14
      webapp/src/App.vue
  12. +28
    -19
      webapp/src/api/algorithm/algorithm.js
  13. +18
    -17
      webapp/src/api/algorithm/algorithmUsage.js
  14. +20
    -19
      webapp/src/api/atlas/index.js
  15. +24
    -23
      webapp/src/api/auth.js
  16. +24
    -23
      webapp/src/api/cloudServing/batch.js
  17. +27
    -26
      webapp/src/api/cloudServing/index.js
  18. +27
    -26
      webapp/src/api/development/notebook.js
  19. +71
    -20
      webapp/src/api/model/model.js
  20. +36
    -18
      webapp/src/api/model/modelVersion.js
  21. +25
    -32
      webapp/src/api/modelOptimize/optimize.js
  22. +20
    -19
      webapp/src/api/modelOptimize/record.js
  23. +21
    -20
      webapp/src/api/preparation/annotation.js
  24. +46
    -19
      webapp/src/api/preparation/datafile.js
  25. +28
    -19
      webapp/src/api/preparation/datalabel.js
  26. +77
    -41
      webapp/src/api/preparation/dataset.js
  27. +35
    -26
      webapp/src/api/preparation/labelGroup.js
  28. +32
    -32
      webapp/src/api/preparation/medical.js
  29. +18
    -14
      webapp/src/api/preparation/textData.js
  30. +58
    -0
      webapp/src/api/system/authCode.js
  31. +19
    -18
      webapp/src/api/system/dict.js
  32. +19
    -18
      webapp/src/api/system/dictDetail.js
  33. +59
    -0
      webapp/src/api/system/menu.js
  34. +34
    -15
      webapp/src/api/system/node.js
  35. +57
    -0
      webapp/src/api/system/permission.js
  36. +37
    -20
      webapp/src/api/system/pod.js
  37. +51
    -0
      webapp/src/api/system/recycle.js
  38. +50
    -0
      webapp/src/api/system/resources.js
  39. +26
    -24
      webapp/src/api/system/role.js
  40. +27
    -19
      webapp/src/api/system/user.js
  41. +109
    -0
      webapp/src/api/system/userGroup.js
  42. +22
    -21
      webapp/src/api/trainingImage/index.js
  43. +34
    -31
      webapp/src/api/trainingJob/job.js
  44. +19
    -18
      webapp/src/api/trainingJob/params.js
  45. +22
    -21
      webapp/src/api/user.js
  46. +14
    -15
      webapp/src/api/visual/index.js
  47. BIN
      webapp/src/assets/images/dataset/annotate.png
  48. BIN
      webapp/src/assets/images/dataset/audioClassify.png
  49. BIN
      webapp/src/assets/images/dataset/body.png
  50. BIN
      webapp/src/assets/images/dataset/classify.png
  51. BIN
      webapp/src/assets/images/dataset/custom.png
  52. BIN
      webapp/src/assets/images/dataset/ner.png
  53. BIN
      webapp/src/assets/images/dataset/nodule.png
  54. BIN
      webapp/src/assets/images/dataset/segmentation.png
  55. BIN
      webapp/src/assets/images/dataset/speechRecognition.png
  56. BIN
      webapp/src/assets/images/dataset/tabular-2.png
  57. BIN
      webapp/src/assets/images/dataset/textclassify.png
  58. BIN
      webapp/src/assets/images/dataset/textsegmentation.png
  59. BIN
      webapp/src/assets/images/dataset/track.png
  60. +64
    -0
      webapp/src/assets/styles/atomic.scss
  61. +51
    -10
      webapp/src/assets/styles/common.scss
  62. +9
    -0
      webapp/src/assets/styles/element-ui.scss
  63. +11
    -0
      webapp/src/assets/styles/index.scss
  64. +20
    -0
      webapp/src/assets/styles/mixin.scss
  65. +5
    -2
      webapp/src/assets/styles/variables.scss
  66. +27
    -24
      webapp/src/boot/errorHandle.js
  67. +14
    -14
      webapp/src/boot/index.js
  68. +165
    -0
      webapp/src/components/BaseForm/index.vue
  69. +42
    -33
      webapp/src/components/BaseModal/index.js
  70. +276
    -0
      webapp/src/components/BaseTable/index.vue
  71. +14
    -14
      webapp/src/components/Card/info.vue
  72. +22
    -2
      webapp/src/components/Crud/UD.operation.vue
  73. +26
    -24
      webapp/src/components/Dict/Dict.js
  74. +14
    -14
      webapp/src/components/Dict/index.js
  75. +25
    -26
      webapp/src/components/Drag/drag.vue
  76. +14
    -14
      webapp/src/components/Drag/index.js
  77. +46
    -23
      webapp/src/components/DropdownHeader/index.vue
  78. +14
    -14
      webapp/src/components/Exception/index.vue
  79. +10
    -17
      webapp/src/components/Hamburger/index.vue
  80. +26
    -24
      webapp/src/components/IconFont/icon.js
  81. +24
    -21
      webapp/src/components/IconFont/iconfont.js
  82. +15
    -15
      webapp/src/components/IconFont/index.js
  83. +14
    -15
      webapp/src/components/IconFont/utils.js
  84. +66
    -66
      webapp/src/components/ImageGallery/index.vue
  85. +44
    -0
      webapp/src/components/InfoAlert/index.vue
  86. +19
    -0
      webapp/src/components/InfoRadio/index.js
  87. +111
    -0
      webapp/src/components/InfoRadio/info-radio.vue
  88. +14
    -14
      webapp/src/components/InfoSelect/index.js
  89. +38
    -35
      webapp/src/components/InfoSelect/info-select.vue
  90. +15
    -15
      webapp/src/components/InfoTable/column.js
  91. +14
    -14
      webapp/src/components/InfoTable/index.js
  92. +38
    -35
      webapp/src/components/InfoTable/info-table.vue
  93. +25
    -21
      webapp/src/components/InlineTableEdit/index.vue
  94. +38
    -37
      webapp/src/components/LogContainer/index.vue
  95. +114
    -103
      webapp/src/components/LogContainer/podLogContainer.vue
  96. +24
    -33
      webapp/src/components/LoginPublic/index.vue
  97. +50
    -0
      webapp/src/components/MsgPopover/index.vue
  98. +498
    -0
      webapp/src/components/PodMonitor/index.vue
  99. +147
    -0
      webapp/src/components/PodMonitor/util.js
  100. +20
    -24
      webapp/src/components/Prism/index.vue

+ 13
- 3
webapp/.env.development View File

@@ -3,8 +3,14 @@ ENV = 'development'
# 默认BASE URL
VUE_APP_BASE_API = ''

# minio
VUE_APP_MINIO_API = 'http://{HOST}/minio'
# 数据管理
VUE_APP_DATA_API = ''

# 训练可视化
VUE_APP_VISUAL_API = ''

# 用户 minio 访问地址
VUE_APP_MINIO_API = ''

# atlas 服务,需要单独部署
VUE_APP_ATLAS_HOST = ''
@@ -14,6 +20,7 @@ VUE_APP_ATLAS_HOST = ''
VUE_APP_DCM_API = 'http://{HOST}/dcm4chee/dcm4chee-arc/aets/DCM4CHEE_ADMIN'

# minIO 服务 IP
# 部署文档参考:http://docs.dubhe.ai/docs/setup/deploy-minio
VUE_APP_MINIO_ENDPOINT = ''

# minIO 服务 端口
@@ -23,4 +30,7 @@ VUE_APP_MINIO_PORT = '9000'
VUE_APP_MINIO_USESSL = 'false'

# bucketName
VUE_APP_MINIO_BUCKETNAME = 'dubhe-dev'
VUE_APP_MINIO_BUCKETNAME = 'dubhe-cloud-dev'

# 文档链接
VUE_APP_DOCS_URL = http://docs.dubhe.ai/docs/

+ 12
- 2
webapp/.env.mock View File

@@ -5,9 +5,16 @@ VUE_APP_MOCK=true

# 默认BASE URL,需要自行配置
VUE_APP_BASE_API = '/mock'
VUE_APP_DATA_API = '/mock'

# 训练可视化
VUE_APP_VISUAL_API = ''

# 用户 minio 访问地址
VUE_APP_MINIO_API = 'http://{HOST}/minio'
VUE_APP_MINIO_API = ''

# atlas
VUE_APP_ATLAS_HOST = ''

# minIO 服务 IP
VUE_APP_MINIO_ENDPOINT = ''
@@ -19,4 +26,7 @@ VUE_APP_MINIO_PORT = '9000'
VUE_APP_MINIO_USESSL = 'false'

# bucketName
VUE_APP_MINIO_BUCKETNAME = 'dubhe-dev'
VUE_APP_MINIO_BUCKETNAME = 'dubhe-cloud-dev'

# 文档链接
VUE_APP_DOCS_URL = http://docs.dubhe.ai/docs/

+ 13
- 4
webapp/.env.production View File

@@ -1,13 +1,19 @@
ENV = 'production'

# 默认BASE URL, 后端服务地址
VUE_APP_BASE_API = 'http://127.0.0.1:8000'
VUE_APP_BASE_API = ''

# 数据管理
VUE_APP_DATA_API = ''

# 训练可视化
VUE_APP_VISUAL_API = ''

# 用户 minio 访问地址
VUE_APP_MINIO_API = 'http://{HOST}/minio'
VUE_APP_MINIO_API = ''

# atlas 服务,需要单独部署
VUE_APP_ATLAS_HOST = 'http://127.0.0.1:8000'
VUE_APP_ATLAS_HOST = ''

# 医疗影像 DCM4CHEE 服务访问地址
# 部署文档参考:http://docs.dubhe.ai/docs/setup/deploy-algorithm
@@ -15,7 +21,7 @@ VUE_APP_DCM_API = 'http://{HOST}/dcm4chee/dcm4chee-arc/aets/DCM4CHEE_ADMIN'

# minIO 服务 IP
# 部署文档参考:http://docs.dubhe.ai/docs/setup/deploy-minio
VUE_APP_MINIO_ENDPOINT = '{IP}'
VUE_APP_MINIO_ENDPOINT = ''

# minIO 服务 端口
VUE_APP_MINIO_PORT = '9000'
@@ -25,3 +31,6 @@ VUE_APP_MINIO_USESSL = 'false'

# bucketName
VUE_APP_MINIO_BUCKETNAME = 'dubhe-prod'

# 文档链接
VUE_APP_DOCS_URL = http://docs.dubhe.ai/docs/

+ 10
- 1
webapp/.env.test View File

@@ -3,6 +3,12 @@ ENV = 'test'
# 默认BASE URL
VUE_APP_BASE_API = ''

# 数据管理
VUE_APP_DATA_API = ''

# 训练可视化
VUE_APP_VISUAL_API = ''

# 用户 minio 访问地址
VUE_APP_MINIO_API = ''

@@ -14,6 +20,7 @@ VUE_APP_ATLAS_HOST = ''
VUE_APP_DCM_API = 'http://{HOST}/dcm4chee/dcm4chee-arc/aets/DCM4CHEE_ADMIN'

# minIO 服务 IP
# 部署文档参考:http://docs.dubhe.ai/docs/setup/deploy-minio
VUE_APP_MINIO_ENDPOINT = ''

# minIO 服务 端口
@@ -23,5 +30,7 @@ VUE_APP_MINIO_PORT = '9000'
VUE_APP_MINIO_USESSL = 'false'

# BucketName
VUE_APP_MINIO_BUCKETNAME = 'dubhe-test'
VUE_APP_MINIO_BUCKETNAME = 'dubhe-cloud-test'

# 文档链接
VUE_APP_DOCS_URL = http://docs.dubhe.ai/docs/

+ 3
- 1
webapp/.eslintignore View File

@@ -3,4 +3,6 @@ src/assets
public
dist
src/components/Crud
mock
mock
src/views/visual
src/store/modules/Visual

+ 21
- 45
webapp/.eslintrc.js View File

@@ -19,53 +19,29 @@ module.exports = {
}
},
rules: {
"comma-dangle": [2, "always-multiline"],
"no-var": "error",
"no-console": [2, { allow: ["warn", "error"] }],
"no-restricted-syntax": "off",
'prettier/prettier': [
'error',
{
printWidth: 100,
semi: true,
singleQuote: true,
trailingComma: 'es5',
endOfLine: 'auto',
arrowParens: 'always',
},
],
'vue/require-default-prop': 'off',
'vue/attribute-hyphenation': 'off',
'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
'no-param-reassign': 'off',
'import/extensions': 'off',
'import/prefer-default-export': 'off',
"no-shadow": "off",
"no-underscore-dangle": "off",
"no-unused-expressions": "off",
"no-restricted-syntax": "off",
"guard-for-in": "off",
"object-shorthand": 2,
"consistent-return": "off",
"camelcase": "off",
"no-multi-assign": "off",
"no-shadow": "off",
"no-restricted-globals": "off",
"no-restricted-properties": "off",
"no-prototype-builtins": "off",
"no-unused-vars": [
2,
{ ignoreRestSiblings: true, argsIgnorePattern: "^h$" }
],
"import/prefer-default-export": "off",
'import/extensions': ['error', 'always', {
'js': 'never',
'vue': 'never'
}],
"no-unused-expressions": "off",
"no-undef": 2,
camelcase: "off",
"no-extra-boolean-cast": "off",
"no-param-reassign":"off",
semi: ["error", "always"],
"vue/require-prop-types": "off",
"vue/require-default-prop": "off",
"vue/no-reserved-keys": "off",
"vue/attribute-hyphenation": "off",
"vue/comment-directive": "off",
"vue/prop-name-casing": "off",
"vue/max-attributes-per-line": [2, {
singleline: 20,
multiline: {
max: 1,
allowFirstLine: false
}}
],
"vue/html-indent": ["error", 2, {
"attribute": 1,
"baseIndent": 1,
"closeBracket": 0,
"alignAttributesVertically": true,
"ignores": []
}]
}
};

webapp/mock/api/data/datasets/count.js → webapp/mock/api/v1/data/datasets/count.js View File

@@ -2,7 +2,7 @@ module.exports = {
code: 200,
msg: null,
data: {
"finished": 10,
"unfinished": 0
"publicCount": 10,
"privateCount": 0
}
}

+ 8
- 0
webapp/mock/api/v1/train/trainJobDelete.js View File

@@ -0,0 +1,8 @@
module.exports = {
code: 200,
msg: null,
data: {
"trainId": 607,
"id": 1204
},
}

+ 2
- 1
webapp/mock/mock-map.js View File

@@ -1,4 +1,5 @@
// 定义 RESTful 接口和实际代码的映射
module.exports = {
'GET::/api/data/datasets/(\\d+)/count': 'api/data/datasets/count',
'GET::/api/v1/data/datasets/(\\d+)/count': 'api/v1/data/datasets/count',
'DELETE::/api/v1/train/trainJob': 'api/v1/train/trainJobDelete',
};

+ 11
- 3
webapp/package.json View File

@@ -13,6 +13,8 @@
"scripts": {
"mock": "vue-cli-service serve --mode mock --open",
"dev": "vue-cli-service serve --open",
"serve": "vue-cli-service serve --host 0.0.0.0",
"serve:test": "vue-cli-service serve --mode test --open",
"build:prod": "vue-cli-service build",
"build:test": "vue-cli-service build --mode test",
"build:dev": "vue-cli-service build --mode development",
@@ -40,9 +42,10 @@
"dependencies": {
"@riophae/vue-treeselect": "0.1.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
"@vue/composition-api": "^0.5.0",
"@vue/composition-api": "^1.0.0-rc.1",
"@wulucxy/dwv": "0.28.1-beta.9",
"add-dom-event-listener": "^1.1.0",
"assert": "^2.0.0",
"axios": "0.18.1",
"chroma-js": "^2.1.0",
"classnames": "^2.2.6",
@@ -59,11 +62,11 @@
"element-ui": "2.13.2",
"file-saver": "^2.0.2",
"filereader-stream": "^2.0.0",
"immutability-helper": "^3.1.1",
"jquery": "^3.5.1",
"jquery-contextmenu": "^2.9.1",
"js-beautify": "^1.13.0",
"js-cookie": "2.2.0",
"jschardet": "^2.2.1",
"jsencrypt": "^3.0.0-rc.1",
"json2csv": "^5.0.1",
"lodash": "^4.17.15",
@@ -72,8 +75,10 @@
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"p-map": "^4.0.0",
"papaparse": "^5.3.0",
"path-to-regexp": "^6.2.0",
"portal-vue": "^2.1.7",
"prism-themes": "^1.5.0",
"prismjs": "^1.20.0",
"promise.allsettled": "^1.0.2",
"qs": "^6.9.1",
@@ -88,7 +93,10 @@
"vue-prism-component": "^1.2.0",
"vue-prism-editor": "^1.2.2",
"vue-router": "^3.0.2",
"vuex": "3.1.0"
"vuex": "3.1.0",
"wavesurfer.js": "^4.6.0",
"web-highlighter": "^0.7.1",
"xlsx": "^0.16.9"
},
"devDependencies": {
"@babel/core": "7.0.0",


+ 14
- 14
webapp/src/App.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div id="app">


+ 28
- 19
webapp/src/api/algorithm/algorithm.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/algorithm',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithms`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/algorithm',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithms`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/v1/algorithm',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithms`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(ids) {
return request({
url: 'api/v1/algorithm',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithms`,
method: 'delete',
data: ids,
});
@@ -50,7 +51,15 @@ export function del(ids) {

export function myAlgorithmCount() {
return request({
url: `api/v1/algorithm/myAlgorithmCount`,
url: `/${API_MODULE_NAME.ALGORITHM}/algorithms/myAlgorithmCount`,
method: 'get',
});
}

// 获取可推理算法列表
export function getInferenceAlgorithm() {
return request({
url: `/${API_MODULE_NAME.ALGORITHM}/algorithms/getInferenceAlgorithm`,
method: 'get',
});
}


+ 18
- 17
webapp/src/api/algorithm/algorithmUsage.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/algorithmUsage',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithmUsage`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/algorithmUsage',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithmUsage`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function del(ids) {
return request({
url: 'api/v1/algorithmUsage',
url: `/${API_MODULE_NAME.ALGORITHM}/algorithmUsage`,
method: 'delete',
data: ids,
});


+ 20
- 19
webapp/src/api/atlas/index.js View File

@@ -1,25 +1,26 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

/* eslint-disable no-unreachable */
import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/ptMeasure',
url: `/${API_MODULE_NAME.ATLAS}/ptMeasure`,
method: 'get',
params,
});
@@ -27,7 +28,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/ptMeasure',
url: `/${API_MODULE_NAME.ATLAS}/ptMeasure`,
method: 'post',
data,
});
@@ -35,7 +36,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/v1/ptMeasure',
url: `/${API_MODULE_NAME.ATLAS}/ptMeasure`,
method: 'put',
data,
});
@@ -43,7 +44,7 @@ export function edit(data) {

export function del(ids) {
return request({
url: 'api/v1/ptMeasure',
url: `/${API_MODULE_NAME.ATLAS}/ptMeasure`,
method: 'delete',
data: { ids },
});
@@ -51,7 +52,7 @@ export function del(ids) {

export function getGraphs(name) {
return request({
url: 'api/v1/ptMeasure/byName',
url: `/${API_MODULE_NAME.ATLAS}/ptMeasure/byName`,
method: 'get',
params: { name },
});


+ 24
- 23
webapp/src/api/auth.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function login(data) {
return request({
url: '/auth/login',
url: `/${API_MODULE_NAME.ADMIN}/auth/login`,
method: 'post',
data,
});
@@ -26,7 +27,7 @@ export function login(data) {

export function registerUser(data) {
return request({
url: 'auth/userRegister',
url: `/${API_MODULE_NAME.ADMIN}/auth/userRegister`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function registerUser(data) {

export function resetPassword(data) {
return request({
url: 'auth/resetPassword',
url: `/${API_MODULE_NAME.ADMIN}/auth/resetPassword`,
method: 'post',
data,
});
@@ -42,7 +43,7 @@ export function resetPassword(data) {

export function getCodeBySentEmail(data) {
return request({
url: 'auth/getCodeBySentEmail',
url: `/${API_MODULE_NAME.ADMIN}/auth/getCodeBySentEmail`,
method: 'post',
data,
});
@@ -50,28 +51,28 @@ export function getCodeBySentEmail(data) {

export function getInfo() {
return request({
url: 'auth/info',
url: `/${API_MODULE_NAME.ADMIN}/auth/info`,
method: 'get',
});
}

export function getCodeImg() {
return request({
url: '/auth/code',
url: `/${API_MODULE_NAME.ADMIN}/auth/code`,
method: 'get',
});
}

export function getPublicKey() {
return request({
url: '/auth/getPublicKey',
url: `/${API_MODULE_NAME.ADMIN}/auth/getPublicKey`,
method: 'get',
});
}

export function logout() {
return request({
url: 'auth/logout',
url: `/${API_MODULE_NAME.ADMIN}/auth/logout`,
method: 'delete',
});
}
@@ -79,6 +80,6 @@ export function logout() {
// 获取minIO 秘钥
export function getMinIOAuth() {
return request({
url: 'api/data/datasets/minio/info',
url: `/${API_MODULE_NAME.DATA}/datasets/minio/info`,
});
}

+ 24
- 23
webapp/src/api/cloudServing/batch.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/batchServing',
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/batchServing',
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/batchServing',
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(id) {
return request({
url: `api/batchServing`,
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices`,
method: 'delete',
data: { id },
});
@@ -50,7 +51,7 @@ export function del(id) {

export function detail(id) {
return request({
url: `api/batchServing/detail`,
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices/detail`,
method: 'get',
params: { id },
});
@@ -58,7 +59,7 @@ export function detail(id) {

export function start(id) {
return request({
url: `api/batchServing/start`,
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices/start`,
method: 'post',
data: { id },
});
@@ -66,7 +67,7 @@ export function start(id) {

export function stop(id) {
return request({
url: `api/batchServing/stop`,
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices/stop`,
method: 'post',
data: { id },
});
@@ -74,14 +75,14 @@ export function stop(id) {

export function getBatchServingPods(id) {
return request({
url: `api/batchServing/pod/${id}`,
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices/pod/${id}`,
method: 'get',
});
}

export function getServiceProgress(id) {
return request({
url: `api/batchServing/queryById/${id}`,
url: `/${API_MODULE_NAME.BATCH_SERVING}/batchServices/queryById/${id}`,
method: 'get',
});
}


+ 27
- 26
webapp/src/api/cloudServing/index.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/serving',
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/serving',
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/serving',
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(id) {
return request({
url: `api/serving`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services`,
method: 'delete',
data: { id },
});
@@ -50,7 +51,7 @@ export function del(id) {

export function detail(id) {
return request({
url: `api/serving/detail`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/detail`,
method: 'get',
params: { id },
});
@@ -58,7 +59,7 @@ export function detail(id) {

export function start(id) {
return request({
url: `api/serving/start`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/start`,
method: 'post',
data: { id },
});
@@ -66,7 +67,7 @@ export function start(id) {

export function stop(id) {
return request({
url: `api/serving/stop`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/stop`,
method: 'post',
data: { id },
});
@@ -74,7 +75,7 @@ export function stop(id) {

export function getPredictParam(id) {
return request({
url: `api/serving/predictParam`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/predictParam`,
method: 'get',
params: { id },
});
@@ -82,28 +83,28 @@ export function getPredictParam(id) {

export function getMetrics(id) {
return request({
url: `api/serving/metrics/${id}`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/metrics/${id}`,
method: 'get',
});
}

export function getServingPods(configId) {
return request({
url: `api/serving/servingConfig/pod/${configId}`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/servingConfig/pod/${configId}`,
method: 'get',
});
}

export function getRollbackList(servingId) {
return request({
url: `api/serving/rollback/${servingId}`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/rollback/${servingId}`,
method: 'get',
});
}

export function predict(data, params) {
return request({
url: `api/serving/predict`,
url: `/${API_MODULE_NAME.CLOUD_SERVING}/services/predict`,
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
params,


+ 27
- 26
webapp/src/api/development/notebook.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/notebook/notebooks',
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/notebook/notebooks',
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function del(ids) {
return request({
url: 'api/v1/notebook',
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks`,
method: 'delete',
data: ids,
});
@@ -42,7 +43,7 @@ export function del(ids) {

export function start(params) {
return request({
url: 'api/v1/notebook/start',
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/start`,
method: 'put',
params,
});
@@ -50,7 +51,7 @@ export function start(params) {

export function stop(params) {
return request({
url: 'api/v1/notebook/stop',
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/stop`,
method: 'put',
params,
});
@@ -58,35 +59,35 @@ export function stop(params) {

export function open(id) {
return request({
url: `api/v1/notebook/${id}`,
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/${id}`,
method: 'get',
});
}

export function getStatus() {
return request({
url: `api/v1/notebook/status`,
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/status`,
method: 'get',
});
}

export function getModels() {
return request({
url: `api/v1/notebook/notebook-model`,
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/notebook-model`,
method: 'get',
});
}

export function myNotebookCount() {
return request({
url: `api/v1/notebook/run-number`,
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/run-number`,
method: 'get',
});
}

export function createNotebook(source, data) {
return request({
url: `api/v1/notebook/create/${source}`,
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/create/${source}`,
method: 'post',
data,
});
@@ -94,14 +95,14 @@ export function createNotebook(source, data) {

export function getNotebookAddress(id) {
return request({
url: `api/v1/notebook/${id}/get-address`,
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/${id}/get-address`,
method: 'get',
});
}

export function detail(data) {
return request({
url: 'api/v1/notebook/detail',
url: `/${API_MODULE_NAME.NOTEBOOK}/notebooks/detail`,
method: 'post',
data,
});


+ 71
- 20
webapp/src/api/model/model.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/ptModelInfo',
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/ptModelInfo',
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/ptModelInfo',
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo`,
method: 'put',
data,
});
@@ -42,18 +43,68 @@ export function edit(data) {

export function del(data) {
return request({
url: 'api/ptModelInfo',
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo`,
method: 'delete',
data,
});
}

export function getModelByResource(modelResource) {
export function getModelByResource(modelResource, packaged) {
return request({
url: 'api/ptModelInfo/byResource',
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo/byResource`,
method: 'get',
params: { modelResource, packaged },
});
}

export function packageAtlasModel(data) {
return request({
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo/package`,
method: 'post',
data,
});
}

export function getServingModel(modelResource) {
return request({
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo/servingModel`,
method: 'get',
params: { modelResource },
});
}

export function addOptimizeModel(data) {
return request({
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo/uploadModel`,
method: 'post',
data,
});
}

// 获取框架与模型格式之间的对应关系
export function getModelTypeMap() {
return request({
url: `/${API_MODULE_NAME.MODEL}/ptModelType`,
method: 'get',
});
}

// 获取模型格式与模型文件后缀之间的对应关系
export function getModelSuffix(params) {
return request({
url: `/${API_MODULE_NAME.MODEL}/ptModelSuffix`,
method: 'get',
params,
});
}

// 根据模型 ID 查询模型信息
export function getModelById(id) {
return request({
url: `/${API_MODULE_NAME.MODEL}/ptModelInfo/byModelId`,
method: 'get',
params: { id },
});
}

export default { list, add, edit, del };

+ 36
- 18
webapp/src/api/model/modelVersion.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/ptModelBranch',
url: `/${API_MODULE_NAME.MODEL}/ptModelBranch`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/ptModelBranch',
url: `/${API_MODULE_NAME.MODEL}/ptModelBranch`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/ptModelBranch',
url: `/${API_MODULE_NAME.MODEL}/ptModelBranch`,
method: 'put',
data,
});
@@ -42,10 +43,27 @@ export function edit(data) {

export function del(data) {
return request({
url: 'api/ptModelBranch',
url: `/${API_MODULE_NAME.MODEL}/ptModelBranch`,
method: 'delete',
data,
});
}

export function convertPreset(data) {
return request({
url: `${API_MODULE_NAME.MODEL}/ptModelBranch/convertPreset`,
method: 'post',
data,
});
}

// 模型格式转换,只支持转至 ONNX
export function formatConvert(id) {
return request({
url: `${API_MODULE_NAME.MODEL}/ptModelBranch/convertOnnx`,
method: 'post',
data: { id },
});
}

export default { list, add, edit, del };

+ 25
- 32
webapp/src/api/modelOptimize/optimize.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/modelOpt/task',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/modelOpt/task',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/modelOpt/task',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(data) {
return request({
url: `api/modelOpt/task`,
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task`,
method: 'delete',
data,
});
@@ -50,7 +51,7 @@ export function del(data) {

export function getOptimizeAlgorithms(params) {
return request({
url: 'api/modelOpt/task/getAlgorithm',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task/getAlgorithm`,
method: 'get',
params,
});
@@ -58,7 +59,7 @@ export function getOptimizeAlgorithms(params) {

export function getBuiltInModel(params) {
return request({
url: 'api/modelOpt/task/getBuiltInModel',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task/getBuiltInModel`,
method: 'get',
params,
});
@@ -66,7 +67,7 @@ export function getBuiltInModel(params) {

export function getOptimizeDatasets(params) {
return request({
url: 'api/modelOpt/task/getDataset',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task/getDataset`,
method: 'get',
params,
});
@@ -74,7 +75,7 @@ export function getOptimizeDatasets(params) {

export function getCustomizeDatasets(params) {
return request({
url: 'api/modelOpt/task/MyDataset',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task/myDataset`,
method: 'get',
params,
});
@@ -82,15 +83,7 @@ export function getCustomizeDatasets(params) {

export function addCustomizeDatasets(data) {
return request({
url: 'api/modelOpt/task/MyDataset',
method: 'post',
data,
});
}

export function addCustomizeModel(data) {
return request({
url: 'api/ptModelInfo/uploadModel',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task/myDataset`,
method: 'post',
data,
});
@@ -98,7 +91,7 @@ export function addCustomizeModel(data) {

export function submit(data) {
return request({
url: `api/modelOpt/task/submit`,
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/task/submit`,
method: 'post',
data,
});


+ 20
- 19
webapp/src/api/modelOptimize/record.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/modelOpt/taskInstance',
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/taskInstance`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function del(data) {
return request({
url: `api/modelOpt/taskInstance`,
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/taskInstance`,
method: 'delete',
data,
});
@@ -34,7 +35,7 @@ export function del(data) {

export function getInstance(params) {
return request({
url: `api/modelOpt/taskInstance/detail`,
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/taskInstance/detail`,
method: 'get',
params,
});
@@ -42,7 +43,7 @@ export function getInstance(params) {

export function cancel(data) {
return request({
url: `api/modelOpt/taskInstance/cancel`,
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/taskInstance/cancel`,
method: 'put',
data,
});
@@ -50,7 +51,7 @@ export function cancel(data) {

export function resubmit(data) {
return request({
url: `api/modelOpt/taskInstance/resubmit`,
url: `/${API_MODULE_NAME.MODEL_OPTIMIZE}/taskInstance/resubmit`,
method: 'post',
data,
});


+ 21
- 20
webapp/src/api/preparation/annotation.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function batchFinishAnnotation(data, datasetId) {
return request({
url: `api/data/datasets/files/${datasetId}/annotations`,
url: `/${API_MODULE_NAME.DATA}/datasets/files/${datasetId}/annotations`,
method: 'post',
data,
});
@@ -27,7 +28,7 @@ export function batchFinishAnnotation(data, datasetId) {
export function delAnnotation(id) {
const delData = { datasetId: id };
return request({
url: 'api/data/datasets/files/annotations',
url: `/${API_MODULE_NAME.DATA}/datasets/files/annotations`,
method: 'delete',
data: delData,
});
@@ -35,7 +36,7 @@ export function delAnnotation(id) {

export function track(id) {
return request({
url: `api/data/datasets/files/annotations/auto/track/${id}`,
url: `/${API_MODULE_NAME.DATA}/datasets/files/annotations/auto/track/${id}`,
method: 'get',
});
}
@@ -43,7 +44,7 @@ export function track(id) {
export function autoAnnotate(ids) {
const data = { datasetIds: ids };
return request({
url: 'api/data/datasets/files/annotations/auto',
url: `/${API_MODULE_NAME.DATA}/datasets/files/annotations/auto`,
method: 'post',
data,
});
@@ -51,7 +52,7 @@ export function autoAnnotate(ids) {

export function annotateStatus(id) {
return request({
url: `api/data/datasets/${id}`,
url: `/${API_MODULE_NAME.DATA}/datasets/${id}`,
method: 'get',
});
}
@@ -59,7 +60,7 @@ export function annotateStatus(id) {
// 发布版本
export function publish(data = {}) {
return request({
url: 'api/data/datasets/versions',
url: `/${API_MODULE_NAME.DATA}/datasets/versions`,
method: 'post',
data,
});


+ 46
- 19
webapp/src/api/preparation/datafile.js View File

@@ -1,26 +1,27 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
const {datasetId} = params;
const { datasetId } = params;
delete params.datasetId;
return request({
url: `api/data/datasets/${datasetId}/files`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files`,
method: 'get',
params,
});
@@ -31,7 +32,7 @@ export function del(params) {
delete params.datasetIds;
params.datasetIds = [datasetId];
return request({
url: 'api/data/datasets/files',
url: `/${API_MODULE_NAME.DATA}/datasets/files`,
method: 'delete',
data: params,
});
@@ -39,7 +40,7 @@ export function del(params) {

export function submit(id, files) {
return request({
url: `api/data/datasets/${id}/files`,
url: `/${API_MODULE_NAME.DATA}/datasets/${id}/files`,
method: 'post',
data: { files },
});
@@ -47,10 +48,36 @@ export function submit(id, files) {

export function submitVideo(id, data) {
return request({
url: `api/data/datasets/${id}/video`,
url: `/${API_MODULE_NAME.DATA}/datasets/${id}/video`,
method: 'post',
data,
});
}

export function tableImport(data) {
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/tableImport`,
method: 'post',
data,
});
}

export function getAudioDetail(params) {
const { datasetId } = params;
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/audio`,
method: 'get',
params,
});
}

export function getCustomFileList(params) {
const { datasetId } = params;
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/filePage`,
method: 'post',
data: { ...params },
});
}

export default { list, del };

+ 28
- 19
webapp/src/api/preparation/datalabel.js View File

@@ -1,39 +1,41 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function getLabels(id) {
return request({
url: `api/data/datasets/${id}/labels`,
url: `/${API_MODULE_NAME.DATA}/datasets/${id}/labels`,
method: 'get',
});
}

export function createLabel(id, label) {
return request({
url: `api/data/datasets/${id}/labels`,
url: `/${API_MODULE_NAME.DATA}/datasets/${id}/labels`,
method: 'post',
data: label,
});
}

export function editLabel(id, label) {
export function editLabel(labelId, label) {
label.labelId = labelId;
return request({
url: `api/data/datasets/labels/${id}`,
url: `/${API_MODULE_NAME.DATA}/datasets/labels`,
method: 'put',
data: label,
});
@@ -41,8 +43,15 @@ export function editLabel(id, label) {

export function getAutoLabels(labelGroupType) {
return request({
url: `api/data/datasets/labels/auto/${labelGroupType}`,
url: `/${API_MODULE_NAME.DATA}/datasets/labels/auto/${labelGroupType}`,
method: 'get',
});
}

export function deleteLabel(datasetId, labelId) {
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/labels`,
method: 'delete',
data: { datasetId, labelId },
});
}

+ 77
- 41
webapp/src/api/preparation/dataset.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: '/api/data/datasets',
url: `/${API_MODULE_NAME.DATA}/datasets`,
method: 'get',
params,
});
@@ -27,7 +28,7 @@ export function list(params) {
// 数据集详情
export function detail(id) {
return request({
url: `/api/data/datasets/${id}`,
url: `/${API_MODULE_NAME.DATA}/datasets/${id}`,
method: 'get',
});
}
@@ -35,7 +36,7 @@ export function detail(id) {
// 数据集状态(导入数据集轮询使用)
export function queryDatasetStatus(ids) {
return request({
url: `/api/data/datasets/status`,
url: `/${API_MODULE_NAME.DATA}/datasets/status`,
method: 'get',
params: { datasetIds: ids },
});
@@ -43,7 +44,7 @@ export function queryDatasetStatus(ids) {

export function add(data) {
return request({
url: 'api/data/datasets',
url: `/${API_MODULE_NAME.DATA}/datasets`,
method: 'post',
data,
});
@@ -52,7 +53,7 @@ export function add(data) {
export function del(ids) {
const delData = { ids };
return request({
url: 'api/data/datasets',
url: `/${API_MODULE_NAME.DATA}/datasets`,
method: 'delete',
data: delData,
});
@@ -60,7 +61,7 @@ export function del(ids) {

export function editDataset(data) {
return request({
url: `api/data/datasets/${data.id}`,
url: `/${API_MODULE_NAME.DATA}/datasets/${data.id}`,
method: 'put',
data,
});
@@ -68,15 +69,33 @@ export function editDataset(data) {

export function topDataset(data) {
return request({
url: `api/data/datasets/${data.id}/top`,
url: `/${API_MODULE_NAME.DATA}/datasets/${data.id}/top`,
method: 'get',
});
}

// 用普通数据集生成预置数据集
export function convertPreset(data) {
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/convertPreset`,
method: 'post',
data,
});
}

// 查询数据集是否已转预置
export function getConvertInfo(id) {
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/getConvertInfoByDatasetId`,
method: 'get',
params: { datasetId: id },
});
}

// 导入自定义数据集
export function addCustomDataset(data) {
return request({
url: `api/data/datasets/custom`,
url: `/${API_MODULE_NAME.DATA}/datasets/custom`,
method: 'post',
data,
});
@@ -85,7 +104,16 @@ export function addCustomDataset(data) {
// 切换版本
export function toggleVersion({ datasetId, versionName }) {
return request({
url: `api/data/datasets/versions/${datasetId}`,
url: `/${API_MODULE_NAME.DATA}/datasets/versions/${datasetId}`,
method: 'put',
params: { versionName },
});
}

// 切换OfRecord
export function shiftOfRecord({ datasetId, versionName }) {
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/versions/${datasetId}/ofRecord`,
method: 'put',
params: { versionName },
});
@@ -94,7 +122,7 @@ export function toggleVersion({ datasetId, versionName }) {
// 删除版本
export function deleteVersion({ datasetId, versionName }) {
return request({
url: `api/data/datasets/versions`,
url: `/${API_MODULE_NAME.DATA}/datasets/versions`,
method: 'delete',
data: { datasetId, versionName },
});
@@ -102,7 +130,7 @@ export function deleteVersion({ datasetId, versionName }) {

export function getDatasetVersions(datasetId) {
return request({
url: `/api/data/datasets/versions/${datasetId}/list`,
url: `/${API_MODULE_NAME.DATA}/datasets/versions/${datasetId}/list`,
method: 'get',
});
}
@@ -110,14 +138,14 @@ export function getDatasetVersions(datasetId) {
// 查询下一个发布版本号
export function queryNextVersion(datasetId) {
return request({
url: `/api/data/datasets/versions/${datasetId}/nextVersionName`,
url: `/${API_MODULE_NAME.DATA}/datasets/versions/${datasetId}/nextVersionName`,
});
};
}

// 目标检测文件列表
export function detectFileList(datasetId, params) {
return request({
url: `api/data/datasets/${datasetId}/files/detection`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/detection`,
method: 'get',
params,
});
@@ -125,7 +153,7 @@ export function detectFileList(datasetId, params) {

export function getPublishedDatasets(params) {
return request({
url: '/api/data/datasets/versions/filter',
url: `/${API_MODULE_NAME.DATA}/datasets/versions/filter`,
method: 'get',
params,
});
@@ -134,7 +162,7 @@ export function getPublishedDatasets(params) {
// 查询文件偏移值
export function queryFileOffset(datasetId, fileId, query = {}) {
return request({
url: `api/data/datasets/${datasetId}/files/${fileId}/offset`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/${fileId}/offset`,
params: query,
});
}
@@ -142,16 +170,16 @@ export function queryFileOffset(datasetId, fileId, query = {}) {
// 查询数据集标签
export function queryLabels(datasetId, params) {
return request({
url: `api/data/datasets/${datasetId}/labels`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/labels`,
method: 'get',
params,
});
}

// 创建数据集标签
export function createLabel (datasetId, data) {
export function createLabel(datasetId, data) {
return request({
url: `api/data/datasets/${datasetId}/labels`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/labels`,
method: 'post',
data,
});
@@ -160,7 +188,7 @@ export function createLabel (datasetId, data) {
// 查询预置标签
export function queryPresetLabels() {
return request({
url: `api/data/datasets/presetLabels`,
url: `/${API_MODULE_NAME.DATA}/datasets/presetLabels`,
method: 'get',
});
}
@@ -168,8 +196,7 @@ export function queryPresetLabels() {
// 查询数据增强字典
export function queryDataEnhanceList() {
return request({
baseURL: process.env.VUE_APP_BASE_API,
url: `api/v1/user/dict/dataset_enhance`,
url: `/${API_MODULE_NAME.ADMIN}/user/dict/dataset_enhance`,
method: 'get',
});
}
@@ -177,7 +204,7 @@ export function queryDataEnhanceList() {
// 数据增强
export function postDataEnhance(datasetId, types = []) {
return request({
url: `api/data/datasets/enhance`,
url: `/${API_MODULE_NAME.DATA}/datasets/enhance`,
data: {
datasetId,
types,
@@ -189,28 +216,37 @@ export function postDataEnhance(datasetId, types = []) {
// 指定原始文件,获取增强文件列表
export function getEnhanceFileList(datasetId, fileId) {
return request({
url: `api/data/datasets/${datasetId}/${fileId}/enhanceFileList`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/${fileId}/enhanceFileList`,
});
}

// 根据数据集版本,获取原始文件数量
export function getOriginFileCount(datasetId) {
return request({
url: `api/data/datasets/versions/${datasetId}/originFileCount`,
url: `/${API_MODULE_NAME.DATA}/datasets/versions/${datasetId}/originFileCount`,
});
}

// 预置数据集和我的数据集的数量查询
export function queryDatasetsCount() {
return request({
url: `/api/data/datasets/count`,
url: `/${API_MODULE_NAME.DATA}/datasets/count`,
});
}

// 查询数据集状态
export function queryDatasetsProgress(params) {
return request({
url: `/api/data/datasets/progress`,
url: `/${API_MODULE_NAME.DATA}/datasets/progress`,
method: 'get',
params,
});
}

// 查询数据集该搜索条件下的文件数量
export function count(datasetId, params) {
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/count`,
method: 'get',
params,
});


+ 35
- 26
webapp/src/api/preparation/labelGroup.js View File

@@ -1,52 +1,62 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

// 创建标签组
export function add(data) {
return request({
url: `/api/data/labelGroup`,
url: `/${API_MODULE_NAME.DATA}/labelGroup`,
method: 'post',
data,
});
}
// 编辑标签组
export function edit(data) {
return request({
url: `/api/data/labelGroup/${data.id}`,
url: `/${API_MODULE_NAME.DATA}/labelGroup/${data.id}`,
method: 'put',
data,
});
}
// 删除标签组
export function del(ids) {
return request({
url: `/api/data/labelGroup`,
url: `/${API_MODULE_NAME.DATA}/labelGroup`,
method: 'delete',
data: {ids},
data: { ids },
});
}

// 复制标签组
export function copy(data) {
return request({
url: `/api/data/labelGroup/copy`,
url: `/${API_MODULE_NAME.DATA}/labelGroup/copy`,
method: 'post',
data,
});
}

// 将普通标签组转为预置标签组
export function convertPreset(data) {
return request({
url: `/${API_MODULE_NAME.DATA}/labelGroup/convertPreset`,
method: 'post',
data,
});
@@ -55,7 +65,7 @@ export function copy(data) {
// 标签组列表分页查询
export function list(params) {
return request({
url: `/api/data/labelGroup/query`,
url: `/${API_MODULE_NAME.DATA}/labelGroup/query`,
method: 'get',
params,
});
@@ -64,7 +74,7 @@ export function list(params) {
// 标签组列表的简况查询 用于详情页选择标签组列举
export function getLabelGroupList(params) {
return request({
url: `/api/data/labelGroup/getList`,
url: `/${API_MODULE_NAME.DATA}/labelGroup/getList`,
method: 'get',
params,
});
@@ -73,13 +83,13 @@ export function getLabelGroupList(params) {
// 获取标签组详情
export function getLabelGroupDetail(id) {
return request({
url: `/api/data/labelGroup/${id}`,
url: `/${API_MODULE_NAME.DATA}/labelGroup/${id}`,
method: 'get',
});
}

export function importLabelGroup(form) {
return request.post(`api/data/labelGroup/import`, form, {
return request.post(`/${API_MODULE_NAME.DATA}/labelGroup/import`, form, {
headers: {
'Content-Type': 'multipart/form-data',
},
@@ -87,4 +97,3 @@ export function importLabelGroup(form) {
}

export default { list, add, del, edit };


+ 32
- 32
webapp/src/api/preparation/medical.js View File

@@ -1,25 +1,26 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

// 获取数据集对应的 studyInstanceUID 和 seriesInstanceUID
export function getCaseInfo(datasetId) {
return request({
url: `api/data/datasets/medical/detail/${datasetId}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/detail/${datasetId}`,
method: 'get',
});
}
@@ -27,7 +28,7 @@ export function getCaseInfo(datasetId) {
// 获取自动标注详情
export const queryAutoResult = (datasetId) => {
return request({
url: `api/data/datasets/medical/getAuto/${datasetId}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/getAuto/${datasetId}`,
method: 'get',
});
};
@@ -35,14 +36,14 @@ export const queryAutoResult = (datasetId) => {
// 获取手动标注详情
export const queryManualResult = (datasetId) => {
return request({
url: `api/data/datasets/medical/getFinished/${datasetId}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/getFinished/${datasetId}`,
method: 'get',
});
};

export function list(params) {
return request({
url: '/api/data/datasets/medical',
url: `/${API_MODULE_NAME.DCM}/datasets/medical`,
method: 'get',
params,
});
@@ -51,7 +52,7 @@ export function list(params) {
// 数据集详情
export function detail(id) {
return request({
url: `/api/data/datasets/medical/${id}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/${id}`,
method: 'get',
});
}
@@ -59,7 +60,7 @@ export function detail(id) {
// 创建数据集
export function add(data) {
return request({
url: 'api/data/datasets/medical',
url: `/${API_MODULE_NAME.DCM}/datasets/medical`,
method: 'post',
data,
});
@@ -68,7 +69,7 @@ export function add(data) {
// 保存标注
export function save(data) {
return request({
url: '/api/data/datasets/medical/annotation/save',
url: `/${API_MODULE_NAME.DCM}/datasets/medical/annotation/save`,
method: 'post',
data,
});
@@ -77,7 +78,7 @@ export function save(data) {
// 上传文件
export function upload(datasetId, params) {
return request({
url: '/api/data/datasets/medical/files',
url: `/${API_MODULE_NAME.DCM}/datasets/medical/files`,
method: 'post',
data: {
id: datasetId,
@@ -89,7 +90,7 @@ export function upload(datasetId, params) {
export function del(ids) {
const delData = { ids };
return request({
url: 'api/data/datasets/medical',
url: `/${API_MODULE_NAME.DCM}/datasets/medical`,
method: 'delete',
data: delData,
});
@@ -97,7 +98,7 @@ export function del(ids) {

export function editDataset(data) {
return request({
url: `api/data/datasets/medical/${data.medicalId}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/${data.medicalId}`,
method: 'put',
data,
});
@@ -106,7 +107,7 @@ export function editDataset(data) {
// 导入自定义数据集
export function addCustomDataset(data) {
return request({
url: `api/data/datasets/medical/custom`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/custom`,
method: 'post',
data,
});
@@ -115,7 +116,7 @@ export function addCustomDataset(data) {
export function autoAnnotate(id) {
const data = { medicalId: id };
return request({
url: 'api/data/datasets/medical/annotation/auto',
url: `/${API_MODULE_NAME.DCM}/datasets/medical/annotation/auto`,
method: 'post',
data,
});
@@ -124,7 +125,7 @@ export function autoAnnotate(id) {
// 查询数据集状态
export function queryDatasetsProgress(params) {
return request({
url: `/api/data/datasets/medical/annotation/schedule`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/annotation/schedule`,
method: 'get',
params,
});
@@ -133,7 +134,7 @@ export function queryDatasetsProgress(params) {
// 保存病灶信息
export function saveLesions(medicalId, data) {
return request({
url: `/api/data/datasets/medical/lesion/${medicalId}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/lesion/${medicalId}`,
method: 'post',
data,
});
@@ -142,7 +143,7 @@ export function saveLesions(medicalId, data) {
// 查询病灶信息
export function queryLesions(medicalId, params) {
return request({
url: `/api/data/datasets/medical/lesion/${medicalId}`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/lesion/${medicalId}`,
method: 'get',
params,
});
@@ -151,7 +152,7 @@ export function queryLesions(medicalId, params) {
// 删除病灶信息
export function deleteLesion(id) {
return request({
url: `/api/data/datasets/medical/lesion`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/lesion`,
method: 'delete',
data: { id },
});
@@ -160,11 +161,10 @@ export function deleteLesion(id) {
// 修改病灶信息
export function updateLesion(id) {
return request({
url: `/api/data/datasets/medical/lesion`,
url: `/${API_MODULE_NAME.DCM}/datasets/medical/lesion`,
method: 'put',
data: { id },
});
}

export default { list, add, del };


+ 18
- 14
webapp/src/api/preparation/textData.js View File

@@ -15,26 +15,21 @@
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
const { datasetId } = params;
return request({
url: `api/data/datasets/${datasetId}/files/txt`,
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/txt`,
method: 'get',
params,
});
}

export function count(datasetId) {
return request({
url: `/api/data/datasets/${datasetId}/count`,
});
}

// 获取分页信息
// 获取分页信息 deprecated
export function queryFiles(datasetId, params) {
return request({
url: `/api/data/datasets/${datasetId}/files/txt`,
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/txt`,
params,
});
}
@@ -42,7 +37,7 @@ export function queryFiles(datasetId, params) {
// 删除文件
export function deleteFile(datasetId, fileId) {
return request({
url: `/api/data/datasets/files`,
url: `/${API_MODULE_NAME.DATA}/datasets/files`,
method: 'delete',
data: {
datasetIds: [Number(datasetId)],
@@ -52,12 +47,21 @@ export function deleteFile(datasetId, fileId) {
}

// 保存
export function save(datasetId, fileId, data){
export function save(datasetId, fileId, data) {
return request({
url: `/api/data/datasets/files/${datasetId}/${fileId}/annotations/finish`,
url: `/${API_MODULE_NAME.DATA}/datasets/files/${datasetId}/${fileId}/annotations/finish`,
method: 'post',
data,
});
}

export default { list };
export function search(params) {
const { datasetId } = params;
return request({
url: `/${API_MODULE_NAME.DATA}/datasets/${datasetId}/files/content`,
method: 'get',
params,
});
}

export default { list };

+ 58
- 0
webapp/src/api/system/authCode.js View File

@@ -0,0 +1,58 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/authCode`,
method: 'get',
params,
});
}

export function add(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/authCode`,
method: 'post',
data,
});
}

export function del(ids) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/authCode`,
method: 'delete',
data: { ids },
});
}

export function edit(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/authCode`,
method: 'put',
data,
});
}

// 不分页的列表接口,用于角色权限管理
export function getAuthCodeList() {
return request({
url: `/${API_MODULE_NAME.ADMIN}/authCode/list`,
method: 'get',
});
}

+ 19
- 18
webapp/src/api/system/dict.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/dict',
url: `/${API_MODULE_NAME.ADMIN}/dict`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/dict',
url: `/${API_MODULE_NAME.ADMIN}/dict`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function del(ids) {
return request({
url: 'api/v1/dict/',
url: `/${API_MODULE_NAME.ADMIN}/dict`,
method: 'delete',
data: { ids },
});
@@ -42,7 +43,7 @@ export function del(ids) {

export function edit(data) {
return request({
url: 'api/v1/dict',
url: `/${API_MODULE_NAME.ADMIN}/dict`,
method: 'put',
data,
});


+ 19
- 18
webapp/src/api/system/dictDetail.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/dictDetail',
url: `/${API_MODULE_NAME.ADMIN}/dictDetail`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/dictDetail',
url: `/${API_MODULE_NAME.ADMIN}/dictDetail`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function del(ids) {
return request({
url: 'api/v1/dictDetail',
url: `/${API_MODULE_NAME.ADMIN}/dictDetail`,
method: 'delete',
data: { ids },
});
@@ -42,7 +43,7 @@ export function del(ids) {

export function edit(data) {
return request({
url: 'api/v1/dictDetail',
url: `/${API_MODULE_NAME.ADMIN}/dictDetail`,
method: 'put',
data,
});


+ 59
- 0
webapp/src/api/system/menu.js View File

@@ -0,0 +1,59 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function getMenusTree() {
return request({
url: `/${API_MODULE_NAME.ADMIN}/menus/tree`,
method: 'get',
});
}

export function list(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/menus`,
method: 'get',
params,
});
}

export function add(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/menus`,
method: 'post',
data,
});
}

export function del(ids) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/menus`,
method: 'delete',
data: { ids },
});
}

export function edit(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/menus`,
method: 'put',
data,
});
}

export default { list, add, edit, del, getMenusTree };

+ 34
- 15
webapp/src/api/system/node.js View File

@@ -1,25 +1,44 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function getNodes(params) {
return request({
url: 'api/v1/node/findAllNode',
url: `/${API_MODULE_NAME.K8S}/node/findAllNode`,
method: 'get',
params,
});
}

// 创建资源隔离
export function addNodeIsolation(data) {
return request({
url: `/${API_MODULE_NAME.K8S}/node/isolation`,
method: 'post',
data,
});
}

// 移除资源隔离
export function removeNodeIsolation(nodeNames) {
return request({
url: `/${API_MODULE_NAME.K8S}/node/isolation`,
method: 'delete',
data: { nodeNames },
});
}

+ 57
- 0
webapp/src/api/system/permission.js View File

@@ -0,0 +1,57 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/permission`,
method: 'get',
params,
});
}

export function add(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/permission`,
method: 'post',
data,
});
}

export function del(ids) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/permission`,
method: 'delete',
data: { ids },
});
}

export function edit(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/permission`,
method: 'put',
data,
});
}

export function getPermissionTree() {
return request({
url: `/${API_MODULE_NAME.ADMIN}/permission/tree`,
method: 'get',
});
}

+ 37
- 20
webapp/src/api/system/pod.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function getPodLog(params) {
return request({
url: 'api/v1/pod/log',
url: `/${API_MODULE_NAME.K8S}/pod/log`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function getPodLog(params) {

export function downloadPodLog(params) {
return request({
url: 'api/v1/pod/log/download',
url: `/${API_MODULE_NAME.K8S}/pod/log/download`,
method: 'get',
params,
});
@@ -34,17 +35,33 @@ export function downloadPodLog(params) {

export function batchDownloadPodLog(data) {
return request({
url: 'api/v1/pod/log/download',
url: `/${API_MODULE_NAME.K8S}/pod/log/download`,
method: 'post',
responseType: 'blob',
data,
});
}

export function countPodLogs(podVOList) {
export function countPodLogs(namespace, podVOList) {
return request({
url: 'api/v1/pod/log/count',
url: `/${API_MODULE_NAME.K8S}/pod/log/count`,
method: 'post',
data: { podVOList },
data: { namespace, podVOList },
});
}

export function getMetrics(params) {
return request({
url: `/${API_MODULE_NAME.K8S}/pod/realtimeMetrics`,
method: 'get',
params,
});
}

export function getHistoryMetrics(params) {
return request({
url: `/${API_MODULE_NAME.K8S}/pod/rangeMetrics`,
method: 'get',
params,
});
}

+ 51
- 0
webapp/src/api/system/recycle.js View File

@@ -0,0 +1,51 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/recycleTask`,
method: 'get',
params,
});
}

export function del(ids) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/recycleTask`,
method: 'delete',
data: { recycleTaskIdList: ids },
});
}

export function restoreTask(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/recycleTask`,
method: 'put',
params,
});
}

export function getRecycleModuleMap() {
return request({
url: `/${API_MODULE_NAME.ADMIN}/recycleTask/recycleModuleMap`,
method: 'get',
});
}

export default { list, del };

+ 50
- 0
webapp/src/api/system/resources.js View File

@@ -0,0 +1,50 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/resourceSpecs`,
method: 'get',
params,
});
}

export function add(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/resourceSpecs`,
method: 'post',
data,
});
}

export function del(ids) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/resourceSpecs`,
method: 'delete',
data: { ids },
});
}

export function edit(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/resourceSpecs`,
method: 'put',
data,
});
}

+ 26
- 24
webapp/src/api/system/role.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/roles',
url: `/${API_MODULE_NAME.ADMIN}/roles`,
method: 'get',
params,
});
@@ -27,14 +28,14 @@ export function list(params) {
// 获取所有的Role
export function getAll() {
return request({
url: 'api/v1/roles/all',
url: `/${API_MODULE_NAME.ADMIN}/roles/all`,
method: 'get',
});
}

export function add(data) {
return request({
url: 'api/v1/roles',
url: `/${API_MODULE_NAME.ADMIN}/roles`,
method: 'post',
data,
});
@@ -42,14 +43,14 @@ export function add(data) {

export function get(id) {
return request({
url: `api/v1/roles/${ id}`,
url: `/${API_MODULE_NAME.ADMIN}/roles/${id}`,
method: 'get',
});
}

export function del(ids) {
return request({
url: 'api/v1/roles',
url: `/${API_MODULE_NAME.ADMIN}/roles`,
method: 'delete',
data: { ids },
});
@@ -57,7 +58,7 @@ export function del(ids) {

export function edit(data) {
return request({
url: 'api/v1/roles',
url: `/${API_MODULE_NAME.ADMIN}/roles`,
method: 'put',
data,
});
@@ -65,16 +66,17 @@ export function edit(data) {

export function editMenu(data) {
return request({
url: 'api/v1/roles/menu',
url: `/${API_MODULE_NAME.ADMIN}/roles/menu`,
method: 'put',
data,
});
}

export function getMenusTree() {
export function editOperations(data) {
return request({
url: 'api/v1/menus/tree',
method: 'get',
url: `/${API_MODULE_NAME.ADMIN}/roles/auth`,
method: 'put',
data,
});
}



+ 27
- 19
webapp/src/api/system/user.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/users',
url: `/${API_MODULE_NAME.ADMIN}/users`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/users',
url: `/${API_MODULE_NAME.ADMIN}/users`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function del(ids) {
return request({
url: 'api/v1/users',
url: `/${API_MODULE_NAME.ADMIN}/users`,
method: 'delete',
data: { ids },
});
@@ -42,11 +43,18 @@ export function del(ids) {

export function edit(data) {
return request({
url: 'api/v1/users',
url: `/${API_MODULE_NAME.ADMIN}/users`,
method: 'put',
data,
});
}

export default { list, add, edit, del };
// 根据用户名模糊搜索用户列表
export function findByNickName() {
return request({
url: `/${API_MODULE_NAME.ADMIN}/users/findByNickName`,
method: 'get',
});
}

export default { list, add, edit, del };

+ 109
- 0
webapp/src/api/system/userGroup.js View File

@@ -0,0 +1,109 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group`,
method: 'get',
params,
});
}

export function add(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group`,
method: 'post',
data,
});
}

export function edit(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group`,
method: 'put',
data,
});
}

export function del(id) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group`,
method: 'delete',
data: { ids: [id] },
});
}

export function getUserListByGroup(groupId) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/byGroupId`,
method: 'get',
params: { groupId },
});
}

export function deleteUserFromGroup(userIds, groupId) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/deleteUser`,
method: 'delete',
data: { groupId, userIds },
});
}

export function getUngroupedUsers() {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/findUser`,
method: 'get',
});
}

// 更新用户组成员列表
export function updateGroupUsers(data) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/updateUser`,
method: 'post',
data,
});
}

// 批量激活/锁定用户组成员
export function updateUserState(groupId, enabled) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/userState`,
method: 'put',
data: { groupId, enabled },
});
}

// 批量修改用户组成员角色
export function updateUserRoles(groupId, roleIds) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/userRoles`,
method: 'put',
data: { groupId, roleIds },
});
}

// 批量删除用户组成员
export function deleteGroupUsers(groupId) {
return request({
url: `/${API_MODULE_NAME.ADMIN}/group/delete`,
method: 'delete',
data: { groupId },
});
}

+ 22
- 21
webapp/src/api/trainingImage/index.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/ptImage/info',
url: `/${API_MODULE_NAME.IMAGE}/ptImage/info`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/ptImage/uploadImage',
url: `/${API_MODULE_NAME.IMAGE}/ptImage/uploadImage`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/v1/ptImage',
url: `/${API_MODULE_NAME.IMAGE}/ptImage`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(ids) {
return request({
url: 'api/v1/ptImage',
url: `/${API_MODULE_NAME.IMAGE}/ptImage`,
method: 'delete',
data: ids,
});
@@ -50,7 +51,7 @@ export function del(ids) {

export function getImageNameList(params) {
return request({
url: 'api/v1/ptImage/imageNameList',
url: `/${API_MODULE_NAME.IMAGE}/ptImage/imageNameList`,
method: 'get',
params,
});
@@ -58,7 +59,7 @@ export function getImageNameList(params) {

export function getImageTagList(params) {
return request({
url: 'api/v1/ptImage',
url: `/${API_MODULE_NAME.IMAGE}/ptImage`,
method: 'get',
params,
});
@@ -66,7 +67,7 @@ export function getImageTagList(params) {

export function setPrecast(params) {
return request({
url: 'api/v1/ptImage/imageResource',
url: `/${API_MODULE_NAME.IMAGE}/ptImage/imageResource`,
method: 'put',
params,
});


+ 34
- 31
webapp/src/api/trainingJob/job.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/trainJob',
url: `/${API_MODULE_NAME.TRAIN}/trainJob`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/trainJob',
url: `/${API_MODULE_NAME.TRAIN}/trainJob`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/v1/trainJob',
url: `/${API_MODULE_NAME.TRAIN}/trainJob`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(ids) {
return request({
url: 'api/v1/trainJob',
url: `/${API_MODULE_NAME.TRAIN}/trainJob`,
method: 'delete',
data: ids,
});
@@ -50,7 +51,7 @@ export function del(ids) {

export function resumeTrain(data) {
return request({
url: 'api/v1/trainJob/resume',
url: `/${API_MODULE_NAME.TRAIN}/trainJob/resume`,
method: 'post',
data,
});
@@ -58,7 +59,7 @@ export function resumeTrain(data) {

export function stop(data) {
return request({
url: 'api/v1/trainJob/stop',
url: `/${API_MODULE_NAME.TRAIN}/trainJob/stop`,
method: 'post',
data,
});
@@ -66,7 +67,7 @@ export function stop(data) {

export function getJobList(params) {
return request({
url: `api/v1/trainJob/trainJobVersionDetail`,
url: `/${API_MODULE_NAME.TRAIN}/trainJob/trainJobVersionDetail`,
method: 'get',
params,
});
@@ -74,7 +75,7 @@ export function getJobList(params) {

export function getJobDetail(jobId) {
return request({
url: `api/v1/trainJob/jobDetail`,
url: `/${API_MODULE_NAME.TRAIN}/trainJob/jobDetail`,
method: 'get',
params: { id: jobId },
});
@@ -82,7 +83,7 @@ export function getJobDetail(jobId) {

export function getTrainLog(params) {
return request({
url: `api/v1/trainLog`,
url: `/${API_MODULE_NAME.TRAIN}/trainLog`,
method: 'get',
params,
});
@@ -90,35 +91,37 @@ export function getTrainLog(params) {

export function myTrainJobCount() {
return request({
url: `api/v1/trainJob/mine`,
url: `/${API_MODULE_NAME.TRAIN}/trainJob/mine`,
method: 'get',
});
}

export function getTrainJobSpecs(params) {
return request({
url: `api/v1/trainJob/trainJobSpecs`,
url: `/${API_MODULE_NAME.TRAIN}/trainJob/trainJobSpecs`,
method: 'get',
params,
});
}

export function getGarafanaInfo(jobId) {
export function getPods(jobId) {
return request({
url: `api/v1/trainJob/grafanaUrl/${jobId}`,
url: `/${API_MODULE_NAME.TRAIN}/trainLog/pod/${jobId}`,
method: 'get',
});
}

export function getPods(jobId) {
export function getTrainModel(params) {
return request({
url: `api/v1/trainLog/pod/${jobId}`,
url: `/${API_MODULE_NAME.TRAIN}/trainJob/model`,
method: 'get',
params,
});
}

export function getTrainModel(params) {
export function getTrainingVisualList(params) {
return request({
url: `api/v1/trainJob/model`,
url: `/${API_MODULE_NAME.TRAIN}/trainJob/visualTrain`,
method: 'get',
params,
});


+ 19
- 18
webapp/src/api/trainingJob/params.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function list(params) {
return request({
url: 'api/v1/trainParams',
url: `/${API_MODULE_NAME.TRAIN}/trainParams`,
method: 'get',
params,
});
@@ -26,7 +27,7 @@ export function list(params) {

export function add(data) {
return request({
url: 'api/v1/trainParams',
url: `/${API_MODULE_NAME.TRAIN}/trainParams`,
method: 'post',
data,
});
@@ -34,7 +35,7 @@ export function add(data) {

export function edit(data) {
return request({
url: 'api/v1/trainParams',
url: `/${API_MODULE_NAME.TRAIN}/trainParams`,
method: 'put',
data,
});
@@ -42,7 +43,7 @@ export function edit(data) {

export function del(ids) {
return request({
url: 'api/v1/trainParams',
url: `/${API_MODULE_NAME.TRAIN}/trainParams`,
method: 'delete',
data: ids,
});


+ 22
- 21
webapp/src/api/user.js View File

@@ -1,24 +1,25 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import request from '@/utils/request';
import { API_MODULE_NAME } from '@/config';

export function userMenus(params) {
return request({
url: 'api/v1/user/menus',
url: `/${API_MODULE_NAME.ADMIN}/user/menus`,
method: 'get',
params,
});
@@ -26,14 +27,14 @@ export function userMenus(params) {

export function dictDetail(name) {
return request({
url: `api/v1/user/dict/${name}`,
url: `/${API_MODULE_NAME.ADMIN}/user/dict/${name}`,
method: 'get',
});
}

export function userInfo(data) {
return request({
url: 'api/v1/user/info',
url: `/${API_MODULE_NAME.ADMIN}/user/info`,
method: 'get',
data,
});
@@ -41,7 +42,7 @@ export function userInfo(data) {

export function editUser(data) {
return request({
url: 'api/v1/user/info',
url: `/${API_MODULE_NAME.ADMIN}/user/info`,
method: 'put',
data,
});
@@ -49,7 +50,7 @@ export function editUser(data) {

export function updateAvatar(data) {
return request({
url: 'api/v1/user/updateAvatar',
url: `/${API_MODULE_NAME.ADMIN}/user/updateAvatar`,
method: 'post',
data,
});
@@ -57,7 +58,7 @@ export function updateAvatar(data) {

export function updatePass(data) {
return request({
url: 'api/v1/user/updatePass',
url: `/${API_MODULE_NAME.ADMIN}/user/updatePass`,
method: 'post',
data,
});
@@ -65,7 +66,7 @@ export function updatePass(data) {

export function resetEmail(data) {
return request({
url: 'api/v1/user/resetEmail',
url: `/${API_MODULE_NAME.ADMIN}/user/resetEmail`,
method: 'post',
data,
});


+ 14
- 15
webapp/src/api/visual/index.js View File

@@ -1,23 +1,22 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
// eslint-disable-next-line import/no-cycle
import request, { useGet } from '@/utils/request';

const baseURL = process.env.VUE_APP_BASE_API;
// 这个文件没用起来

export function initVisual(params) {
return request({


BIN
webapp/src/assets/images/dataset/annotate.png View File

Before After
Width: 368  |  Height: 275  |  Size: 53 kB

BIN
webapp/src/assets/images/dataset/audioClassify.png View File

Before After
Width: 736  |  Height: 562  |  Size: 33 kB

BIN
webapp/src/assets/images/dataset/body.png View File

Before After
Width: 512  |  Height: 512  |  Size: 11 kB

BIN
webapp/src/assets/images/dataset/classify.png View File

Before After
Width: 368  |  Height: 288  |  Size: 50 kB

BIN
webapp/src/assets/images/dataset/custom.png View File

Before After
Width: 346  |  Height: 246  |  Size: 6.7 kB

BIN
webapp/src/assets/images/dataset/ner.png View File

Before After
Width: 736  |  Height: 547  |  Size: 29 kB

BIN
webapp/src/assets/images/dataset/nodule.png View File

Before After
Width: 1024  |  Height: 1024  |  Size: 38 kB

BIN
webapp/src/assets/images/dataset/segmentation.png View File

Before After
Width: 368  |  Height: 274  |  Size: 48 kB

BIN
webapp/src/assets/images/dataset/speechRecognition.png View File

Before After
Width: 225  |  Height: 225  |  Size: 2.6 kB

BIN
webapp/src/assets/images/dataset/tabular-2.png View File

Before After
Width: 736  |  Height: 547  |  Size: 24 kB

BIN
webapp/src/assets/images/dataset/textclassify.png View File

Before After
Width: 736  |  Height: 547  |  Size: 31 kB

BIN
webapp/src/assets/images/dataset/textsegmentation.png View File

Before After
Width: 736  |  Height: 490  |  Size: 86 kB

BIN
webapp/src/assets/images/dataset/track.png View File

Before After
Width: 368  |  Height: 274  |  Size: 45 kB

+ 64
- 0
webapp/src/assets/styles/atomic.scss View File

@@ -24,6 +24,10 @@
display: block;
}

.di {
display: inline;
}

.dib {
display: inline-block;
}
@@ -113,6 +117,10 @@
padding-right: 5px;
}

.pr-20 {
padding-right: 20px;
}

.pl-0 {
padding-left: 0;
}
@@ -129,6 +137,21 @@
padding-bottom: 10px;
}

.py-4 {
padding-top: 4px;
padding-bottom: 4px;
}

.py-10 {
padding-top: 10px;
padding-bottom: 10px;
}

.px-20 {
padding-right: 20px;
padding-left: 20px;
}

.mt-0 {
margin-top: 0 !important;
}
@@ -169,6 +192,10 @@
margin-left: 40px;
}

.ml-auto {
margin-left: auto;
}

.mb-50 {
margin-bottom: 50px;
}
@@ -190,6 +217,11 @@
margin-left: 10px;
}

.my-5 {
margin-top: 5px;
margin-bottom: 5px;
}

.my-10 {
margin-top: 10px;
margin-bottom: 10px;
@@ -205,6 +237,10 @@
margin-bottom: auto;
}

.w-100 {
width: 100px;
}

.w-150 {
width: 150px;
}
@@ -213,14 +249,34 @@
width: 200px;
}

.w-300 {
width: 300px;
}

.w-500 {
width: 500px;
}

.h-100 {
height: 100px;
}

.lh-1 {
line-height: 1;
}

.lh-20 {
line-height: 20px;
}

.bold {
font-weight: bold;
}

.normal {
font-weight: normal;
}

img.responsive {
display: inline-block;
max-width: 100%;
@@ -290,6 +346,10 @@ img.responsive {
border-color: $borderColor;
}

.no-border {
border: none;
}

.g3 {
color: #333;
}
@@ -318,6 +378,10 @@ img.responsive {
font-size: 18px;
}

.f22 {
font-size: 22px;
}

.ellipsis {
@include text-overflow;
}


+ 51
- 10
webapp/src/assets/styles/common.scss View File

@@ -20,6 +20,15 @@
//main-container全局样式
.app-container {
padding: 10px 20px 70px 20px;

.wrapper.fixed {
width: 1080px;
min-width: 60vw;
max-width: calc(100vw - 80px);
max-height: 100%;
padding: 20px 0 0;
margin: 0 auto;
}
}

.head-container {
@@ -69,22 +78,18 @@
margin-left: auto;
}

.my-code {
position: relative;
padding: 15px;
font-family: Courier New, serif;
font-size: 12px;
line-height: 20px;
color: #333;
border-left: 5px solid #ddd;
}

// 自定义search-bar样式
.search-bar {
float: right;
margin-top: 8px;
}

.disabled {
color: $infoColor;
pointer-events: none;
cursor: not-allowed;
}

// 自定义drawer样式
.ts-drawer {
margin: 30px 20px 0 0;
@@ -250,3 +255,39 @@ pre {
background: rgb(30, 30, 30);
border-radius: 5px;
}

.field-extra {
font-size: 14px;
line-height: 1.5;
color: $infoColor;
}

.app-result-content {
padding: 24px 40px;
margin-top: 24px;
text-align: left;
background-color: #fafafa;
}

.app-result-title {
font-size: 24px;
line-height: 1.8;
color: rgba(0, 0, 0, 0.85);
text-align: center;
}

.app-result-subtitle {
font-size: 14px;
line-height: 1.6;
color: rgba(0, 0, 0, 0.45);
text-align: center;
}

.rotate {
@include rotate(3s);
}

.ts-tip {
color: $tipColor;
background-color: $tipBgColor;
}

+ 9
- 0
webapp/src/assets/styles/element-ui.scss View File

@@ -44,6 +44,15 @@
}
}

.el-button.danger {
color: $red;

&:hover,
&:active {
color: $red;
}
}

// el-radio border
.el-radio.is-bordered {
&.is-checked,


+ 11
- 0
webapp/src/assets/styles/index.scss View File

@@ -22,12 +22,23 @@
@import 'sidebar';
@import 'common';

@media screen and (max-width: 768px) {
.mb-dn {
display: none !important;
}

.mb-w100 {
width: 100% !important;
}
}

body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
color: rgba(0, 0, 0, 0.85);
}

label {


+ 20
- 0
webapp/src/assets/styles/mixin.scss View File

@@ -102,4 +102,24 @@
border-right: $color-border-style;
border-bottom: $transparent-border-style;
}

@else if $direction==right-up {
border: $width solid $color;
border-top: $transparent-border-style;
border-left: $transparent-border-style;
}
}

@mixin rotate($duration) {
animation: spin infinite $duration linear;
}

@keyframes spin {
from {
transform: rotate(330deg);
}

to {
transform: rotate(-30deg);
}
}

+ 5
- 2
webapp/src/assets/styles/variables.scss View File

@@ -40,13 +40,16 @@ $menuBg: #f3f7ff;
$menuText: $commonTextColor;
$menuActiveText: $primaryColor;

$menuHoverBg:#d8dfff;
$menuHoverBg: #d8dfff;
$subMenuBg: #edf0ff;
$menuActiveBg:#d8dfff;
$menuActiveBg: #d8dfff;
$sideBarWidth: 205px;
$iconBarWidth: 64px;
$navBarHeight: 50px;

$tipBgColor: #ffe9cc;
$tipColor: #f38900;

:export {
menuBg: $menuBg;
menuText: $menuText;


+ 27
- 24
webapp/src/boot/errorHandle.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import Vue from 'vue';
import { Message, MessageBox } from 'element-ui';
@@ -24,7 +24,7 @@ const TOKENEXPIRE = 20012; // Token 失效
let isMsgOn = false;

// 全局未捕获异常处理(包括普通异常和 await 未被捕获的异常)
Vue.config.errorHandler = (err) =>{
Vue.config.errorHandler = (err) => {
console.error(err);
// 未授权只提示一次
if (err.code === UNAUTHORIZED) {
@@ -46,7 +46,7 @@ Vue.config.errorHandler = (err) =>{
// 只针对 promise 异步捕获
// eslint-disable-next-line func-names
window.addEventListener('unhandledrejection', function(event) {
const {reason} = event;
const { reason } = event;
if (reason) {
// 未授权
if (reason.code === TOKENEXPIRE) {
@@ -58,16 +58,19 @@ window.addEventListener('unhandledrejection', function(event) {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 此处调用 store lotout
store.dispatch('LogOut').then(() => {
location.pathname !== '/login' && location.reload();
})
.then(() => {
// 此处调用 store lotout
store.dispatch('LogOut').then(() => {
window.location.pathname !== '/login' && window.location.reload();
});
})
.finally(() => {
isMsgOn = false;
});
}).finally(() => {
isMsgOn = false;
});
return;
} if (reason.code === UNAUTHORIZED) {
}
if (reason.code === UNAUTHORIZED) {
// 未授权提醒只展示一次
if (isMsgOn === true) return;
isMsgOn = true;


+ 14
- 14
webapp/src/boot/index.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import './errorHandle';



+ 165
- 0
webapp/src/components/BaseForm/index.vue View File

@@ -0,0 +1,165 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<el-form ref="formRef" :model="model" v-bind="attrs" v-on="$listeners" @submit.native.prevent>
<template v-for="item of mergedFormItems">
<el-form-item
v-if="!hideItem(item)"
:key="item.prop"
:label="item.label"
:label-width="item.labelWidth"
:prop="item.prop"
>
<!-- 输入框/文本域 -->
<template v-if="item.type === 'input'">
<el-input
v-model="model[item.prop]"
:type="item.inputType"
v-bind="item"
@change="(value) => runFunc(item.change, value)"
/>
</template>
<!-- 下拉框 -->
<template v-else-if="item.type === 'select'">
<el-select
v-model="model[item.prop]"
v-bind="item"
@change="(value) => runFunc(item.change, value)"
>
<el-option
v-for="option of item.options"
:key="option.value"
:value="option.value"
:label="option.label"
:disabled="option.disabled"
/>
</el-select>
</template>
<!-- 时间选择器 -->
<el-date-picker
v-else-if="item.type === 'date'"
v-model="model[item.prop]"
:type="item.dateType"
v-bind="item"
@change="(value) => runFunc(item.change, value)"
/>
<!-- 按钮 -->
<template v-else-if="item.type === 'button'">
<el-button
:type="item.btnType"
:disabled="item.disabled"
v-bind="item"
@click="runFunc(item.func)"
>
<template v-if="!item.circle">{{ item.btnText }}</template>
</el-button>
</template>
</el-form-item>
</template>
</el-form>
</template>

<script>
import { computed, reactive, ref } from '@vue/composition-api';

import { runFunc } from '@/utils';

// 默认表单属性
const defaultFormAttrs = {
// TODO: 确认是否添加表单默认属性
};

// 默认表单项定义
const defaultItemDefinition = {
type: 'input',
clearable: true,
rows: 4,
};

export default {
name: 'BaseForm',
inheritAttrs: false,
props: {
formItems: {
type: Array,
required: true,
},
model: {
type: Object,
required: true,
},
},
setup(props, ctx) {
const { model } = reactive(props);
// 表单组件 ref
const formRef = ref(null);

// 合并表单默认属性和 $attrs
const attrs = computed(() => {
return { ...defaultFormAttrs, ...ctx.attrs };
});

const hideItem = (item) => {
if (item.hidden) return true;
if (typeof item.hiddenFunc === 'function') return item.hiddenFunc();
return false;
};

// 表单项预处理
const mergedFormItems = computed(() => {
return props.formItems.map((item) => {
return { ...defaultItemDefinition, ...item };
});
});

// 表单校验方法
const validate = (resolve, reject) => {
let valid;
formRef.value.validate((isValid) => {
valid = isValid;
if (isValid) {
if (typeof resolve === 'function') {
return resolve(model);
}
return true;
}
if (typeof reject === 'function') {
return reject(model);
}
return false;
});
return valid;
};

// 清空表单校验
const clearValidate = () => {
formRef.value.clearValidate();
};

return {
formRef,
attrs,
mergedFormItems,
runFunc,
hideItem,

validate,
clearValidate,
};
},
};
</script>

+ 42
- 33
webapp/src/components/BaseModal/index.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import { isNil } from 'lodash';
import { reactive, watch, ref } from '@vue/composition-api';
@@ -74,19 +74,20 @@ const BaseModal = {
ctx.emit('ok', e);
};

const handleClose = e => {
const handleClose = (e) => {
// 这里只针对状态变更进行控制,只转发 element close 事件
ctx.emit('close', e);
ctx.emit('change', false);
};

watch(() => props.visible, (next) => {
Object.assign(state, {
sVisible: next,
});
}, {
lazy: true,
});
watch(
() => props.visible,
(next) => {
Object.assign(state, {
sVisible: next,
});
}
);

return {
state,
@@ -99,15 +100,23 @@ const BaseModal = {
render() {
const renderFooter = () => {
return (
<div class='modal-footer'>
{ this.showCancel && (
<el-button id="cancel" onClick={this.handleCancel}>{this.cancelText}</el-button>
)
}
{ this.showOk && (
<el-button id="ok" type='primary' disabled={this.disabled} onClick={this.handleOk} loading={this.loading}>{this.okText}</el-button>
)
}
<div class="modal-footer">
{this.showCancel && (
<el-button id="cancel" onClick={this.handleCancel}>
{this.cancelText}
</el-button>
)}
{this.showOk && (
<el-button
id="ok"
type="primary"
disabled={this.disabled}
onClick={this.handleOk}
loading={this.loading}
>
{this.okText}
</el-button>
)}
</div>
);
};
@@ -130,9 +139,9 @@ const BaseModal = {
};

return (
<el-dialog {...dialogProps} ref='dialogRef'>
<el-dialog {...dialogProps} ref="dialogRef">
{this.$slots.default}
<div slot='footer'>{footer}</div>
<div slot="footer">{footer}</div>
</el-dialog>
);
},


+ 276
- 0
webapp/src/components/BaseTable/index.vue View File

@@ -0,0 +1,276 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<el-table ref="table" v-loading="loading" :data="data" v-bind="attrs" v-on="$listeners">
<template v-for="column in mergedColumns">
<el-table-column
v-if="!column.hide"
:key="column.prop"
:type="column.columnType"
v-bind="column"
>
<template #header>
<template v-if="headerSlots.includes(column.prop)">
<slot :name="`header-${column.prop}`" />
</template>
<DropdownHeader
v-else-if="headerOptions[column.prop]"
:title="column.label"
:list="headerOptions[column.prop]"
:filterFunc="column.filterFunc"
@command="column.func"
/>
<span v-else>
{{ column.label }}
</span>
</template>
<template v-if="column.type !== 'selection'" #default="scope">
<template v-if="defaultSlots.includes(column.prop)">
<slot :row="scope.row" :name="column.prop" />
</template>
<!-- 时间列 -->
<span v-else-if="column.type === 'time'">
{{ parseTime(scope.row[column.prop]) }}
</span>
<!-- 操作列 -->
<div v-else-if="column.type === 'operation'">
<template v-for="operation in column.operations">
<!-- 更多操作下拉 -->
<el-dropdown
v-if="
operation.type === 'more' &&
!getOperationStatus('hide', 'hideFunc', operation, scope.row)
"
:key="operation.key"
>
<el-button type="text" class="ml-10" @click.stop
>{{ column.moreText }}<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="moreOp in operation.operations"
:key="moreOp.key"
:disabled="getOperationStatus('disabled', 'disableFunc', moreOp, scope.row)"
@click.native="() => runFunc(moreOp.func, scope.row)"
>
<el-button
type="text"
:disabled="getOperationStatus('disabled', 'disableFunc', moreOp, scope.row)"
>
{{ moreOp.label }}
<IconFont v-if="moreOp.iconAfter" :type="moreOp.iconAfter" />
</el-button>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button
v-else-if="!getOperationStatus('hide', 'hideFunc', operation, scope.row)"
:id="operation.label + scope.$index"
:key="operation.key"
type="text"
:disabled="getOperationStatus('disabled', 'disableFunc', operation, scope.row)"
@click.stop="() => runFunc(operation.func, scope.row)"
>
{{ operation.label }}
<IconFont v-if="operation.iconAfter" :type="operation.iconAfter" />
</el-button>
</template>
</div>
<!-- tag 展示列 -->
<el-tag v-else-if="column.type === 'tag'" v-bind="getTagAttrs(column, scope.row)">{{
getContent(column, scope.row)
}}</el-tag>
<!-- 其他展示列 -->
<span v-else>
{{ getContent(column, scope.row) }}
</span>
</template>
</el-table-column>
</template>
</el-table>
</template>

<script>
import { computed, ref } from '@vue/composition-api';

import { parseTime, noop, runFunc } from '@/utils';
import DropdownHeader from '@/components/DropdownHeader';

const defaultColunmDefinition = {
columnType: 'default',
hide: false, // 是否展示该列
fixed: false, // 是否为固定列
sortable: false, // 是否可排序
showOverflowTooltip: true, // 是否在过长时展示 tooltip,默认为 true
moreText: '更多', // 用于替换操作数超限时 “更多” 按钮的文本
operationLimit: 4, // 超过限制数量时自动压缩
};

const defaultTableAttrs = {
'highlight-current-row': true,
};

const elTableColumnTypes = ['default', 'selection', 'expand', 'index'];

export default {
name: 'BaseTable',
components: { DropdownHeader },
inheritAttrs: false,
props: {
columns: {
type: Array,
required: true,
},
data: {
type: Array,
required: true,
},
loading: {
type: Boolean,
default: false,
},
},
setup(props, ctx) {
// 合并表格默认属性和 $attrs
const attrs = computed(() => {
return { ...defaultTableAttrs, ...ctx.attrs };
});

// 设置默认属性
const mergedColumns = computed(() => {
return props.columns.map((originColumn) => {
// 赋默认值
const column = { ...defaultColunmDefinition, ...originColumn };

if (elTableColumnTypes.includes(column.type)) {
column.columnType = column.type;
}

// 过滤不需要展示的 operation,生成折叠结构
if (column.type === 'operation') {
const displayOperations = column.operations.filter((op) => !op.hide);
let moreOperation = displayOperations.find((operation) => operation.type === 'more');
if (moreOperation) {
moreOperation.operations = moreOperation.operations.filter((op) => !op.hide);
} else if (displayOperations.length > column.operationLimit) {
moreOperation = {
label: column.moreText,
type: 'more',
operations: displayOperations.splice(column.operationLimit - 1),
};
displayOperations.push(moreOperation);
}
// operation 设置默认值为 noop,添加 key
displayOperations.forEach((operation, index) => {
operation.func = operation.func || noop;
operation.key = operation.label + index;
if (operation.type === 'more') {
operation.operations.forEach((moreOp, moreIndex) => {
moreOp.func = moreOp.func || noop;
moreOp.key = moreOp.label + moreIndex;
});
}
});
column.operations = displayOperations;
}

// 处理下拉表头
if (column.dropdownList && typeof column.func !== 'function') {
column.func = noop;
}
return column;
});
});

// 计算生成下拉表头
// 如果直接传入 column.dropdownList 会导致表头选项不可响应
const headerOptions = computed(() => {
const result = Object.create(null);
mergedColumns.value.forEach((column) => {
if (column.dropdownList) {
result[column.prop] = column.dropdownList;
}
});
return result;
});

// 展示文本格式化
const getContent = (column, row) => {
if (typeof column.formatter === 'function') {
return column.formatter(row[column.prop]);
}
return row[column.prop];
};

// 判断操作属性名和函数名返回布尔值
const getOperationStatus = (propName, funcName, operation, row, defaultResult = false) => {
if (operation[propName] !== undefined) {
return operation[propName];
}
if (typeof operation[funcName] === 'function') {
return operation[funcName](row);
}
return defaultResult;
};

// 根据列的 tagAttrFunc/tagAttr/tagMap 计算返回 el-tag 的属性
const getTagAttrs = (column, row) => {
if (typeof column.tagAttrFunc === 'function') {
return column.tagAttrFunc(row[column.prop], row);
}
const tagAttr = column.tagAttr || {};
const tagMap = column.tagMap || {};
return {
type: tagMap[row[column.prop]],
effect: 'plain',
...tagAttr,
};
};

// 插槽名列表
const headerRe = /^header-([a-zA-Z]+)$/;
const defaultSlots = ref([]);
const headerSlots = ref([]);
let headerSlotName;
Object.keys(ctx.slots).forEach((slot) => {
headerSlotName = slot.match(headerRe);
if (headerSlotName) {
headerSlots.value.push(headerSlotName[1]);
} else {
defaultSlots.value.push(slot);
}
});

return {
attrs,
mergedColumns,
headerOptions,
getContent,
getOperationStatus,
getTagAttrs,

// slots
defaultSlots,
headerSlots,

// Utils 方法
parseTime,
runFunc,
};
},
};
</script>

+ 14
- 14
webapp/src/components/Card/info.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template functional>
<div class="info-card" @click="props.handleClick">


+ 22
- 2
webapp/src/components/Crud/UD.operation.vue View File

@@ -16,10 +16,22 @@

<template>
<span>
<el-button :loading="crud.status.cu === 2" :disabled="disabledEdit" type="text" @click="crud.toEdit(data)">
<el-button
v-if="showEdit"
:loading="crud.status.cu === 2"
:disabled="disabledEdit"
type="text"
@click="crud.toEdit(data)"
>
{{ crud.props.optText.edit }}
</el-button>
<el-button slot="reference" :disabled="disabledDle" type="text" @click="toDelete">
<el-button
v-if="showDelete"
slot="reference"
:disabled="disabledDle"
type="text"
@click="toDelete"
>
{{ crud.props.optText.del }}
</el-button>
</span>
@@ -42,6 +54,14 @@ export default {
type: Boolean,
default: false,
},
showEdit: {
type: Boolean,
default: true,
},
showDelete: {
type: Boolean,
default: true,
},
msg: {
type: String,
default: '确定删除本条数据吗?',


+ 26
- 24
webapp/src/components/Dict/Dict.js View File

@@ -1,18 +1,18 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Vue from 'vue';
import { dictDetail } from '@/api/user';
@@ -23,22 +23,24 @@ export default class Dict {
}

async init(names, completeCallback) {
if (names === undefined || name === null) {
if (names === undefined || names === null) {
throw new Error('need Dict names');
}
const ps = [];
names.forEach(n => {
names.forEach((n) => {
Vue.set(this.dict.dict, n, {});
Vue.set(this.dict.label, n, {});
Vue.set(this.dict, n, []);
ps.push(dictDetail(n).then(data => {
const details = data && data.dictDetails || [];
this.dict[n].splice(0, 0, ...details);
details.forEach(d => {
Vue.set(this.dict.dict[n], d.value, d);
Vue.set(this.dict.label[n], d.value, d.label);
});
}));
ps.push(
dictDetail(n).then((data) => {
const details = (data && data.dictDetails) || [];
this.dict[n].splice(0, 0, ...details);
details.forEach((d) => {
Vue.set(this.dict.dict[n], d.value, d);
Vue.set(this.dict.label[n], d.value, d.label);
});
})
);
});
await Promise.all(ps);
completeCallback();


+ 14
- 14
webapp/src/components/Dict/index.js View File

@@ -1,18 +1,18 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Dict from './Dict';



+ 25
- 26
webapp/src/components/Drag/drag.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<script>
import { reactive } from '@vue/composition-api';
@@ -43,7 +43,7 @@ export default {
});

function getPoint(event) {
// 容器尺寸
// 容器尺寸
const bound = findAncestorSvg(event).getBoundingClientRect();
const { clientX, clientY } = event;

@@ -64,14 +64,14 @@ export default {
y: resetOnStart ? point.y : -state.dy + point.y,
};
Object.assign(state, nextState);
if (typeof onDragStart === 'function') onDragStart(nextState, event);
if (typeof onDragStart === 'function') onDragStart(nextState, event);
}

function dragMove(event) {
if (!state.isDragging) return;
const point = getPoint(event);
// 避免无效移动
if(Math.abs(point.x - state.x) < 2 && Math.abs(point.y - state.y) < 2) return;
if (Math.abs(point.x - state.x) < 2 && Math.abs(point.y - state.y) < 2) return;
const nextState = {
isDragging: true,
isMoving: true,
@@ -90,9 +90,10 @@ export default {
const prevState = { ...state };
Object.assign(state, nextState);
// 传递 prevState
if (typeof onDragEnd === 'function') onDragEnd(state, event, {
prevState,
});
if (typeof onDragEnd === 'function')
onDragEnd(state, event, {
prevState,
});
}

return {
@@ -108,24 +109,22 @@ export default {

return (
<g>
{this.state.isDragging &&
(
{this.state.isDragging && (
<rect
width={this.width}
height={this.height}
onMousemove={this.dragMove}
onMouseup={this.dragEnd}
fill='transparent'
fill="transparent"
/>
)}
{ typeof children === 'function' && (
{typeof children === 'function' &&
children({
state: this.state,
dragStart: this.dragStart,
dragMove: this.dragMove,
dragEnd: this.dragEnd,
})
) }
})}
</g>
);
},


+ 14
- 14
webapp/src/components/Drag/index.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import Drag from './drag';



+ 46
- 23
webapp/src/components/DropdownHeader/index.vue View File

@@ -1,37 +1,39 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<el-dropdown trigger="click" placement="bottom-start" @command="onCommand">
<div>
<span :class="{primary: filtered}">{{ title }}</span>
<span :class="{ primary: dropdownSelected }">{{ title }}</span>
<i class="el-icon-arrow-down el-icon--right" />
</div>
<el-dropdown-menu slot="dropdown" :style="dropdownStyle">
<el-dropdown-item
v-for="(item, index) in list"
:key="index"
:command="item[valueTag]"
>{{ item[labelTag] }}</el-dropdown-item>
<el-dropdown-item v-for="(item, index) in list" :key="index" :command="item[valueTag]">{{
item[labelTag]
}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>

<script>
import { computed, ref } from '@vue/composition-api';
import { isNil } from 'lodash';

export default {
name: 'DropdownHeader',
props: {
title: {
type: String,
@@ -54,19 +56,40 @@ export default {
// filtered 用于标识是否处于筛选状态
filtered: {
type: Boolean,
default: false,
default: undefined,
},
filterFunc: {
type: Function,
default(value) {
return !isNil(value);
},
},
// 下拉框样式可配置
dropdownStyle: {
type: String,
default: "",
default: '',
},
},
setup(props, ctx) {
// 记录当前选择值
const currentValue = ref(null);

const onCommand = (value) => {
currentValue.value = value;
ctx.emit('command', value);
};
return { onCommand };

const dropdownSelected = computed(() => {
if (!isNil(props.filtered)) {
return props.filtered;
}
return props.filterFunc(currentValue.value);
});

return {
onCommand,
dropdownSelected,
};
},
};
</script>

+ 14
- 14
webapp/src/components/Exception/index.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template functional>
<div class="exception">


+ 10
- 17
webapp/src/components/Hamburger/index.vue View File

@@ -1,30 +1,23 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* * Copyright 2019-2020 Zheng Jie * * Licensed under the Apache License, Version 2.0 (the
"License"); * you may not use this file except in compliance with the License. * You may obtain a
copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by
applicable law or agreed to in writing, software * distributed under the License is distributed on
an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See
the License for the specific language governing permissions and * limitations under the License. */

<template>
<div @click="toggleClick">
<svg
:class="{'is-active':isActive}"
:class="{ 'is-active': isActive }"
class="hamburger"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
width="64"
height="64"
>
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
<path
d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"
/>
</svg>
</div>
</template>


+ 26
- 24
webapp/src/components/IconFont/icon.js View File

@@ -1,20 +1,20 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import { createElement } from '@vue/composition-api';
import { h } from '@vue/composition-api';
import { svgBaseProps } from './utils';

const Icon = {
@@ -29,13 +29,17 @@ const Icon = {
...svgBaseProps,
},
};
return createElement('svg', {
style: {
// verticalAlign: 'text-bottom'
verticalAlign: '-0.15em',
return h(
'svg',
{
style: {
// verticalAlign: 'text-bottom'
verticalAlign: '-0.15em',
},
...svgProps,
},
...svgProps,
}, ctx.slots.default());
ctx.slots.default()
);
};

// 事件
@@ -50,9 +54,7 @@ const Icon = {
},
render() {
const { iProps } = this;
return (
<i {...iProps}>{this.renderInnerNode()}</i>
);
return <i {...iProps}>{this.renderInnerNode()}</i>;
},
};



+ 24
- 21
webapp/src/components/IconFont/iconfont.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import cx from 'classnames';
import { mergeProps } from '@/utils';
@@ -23,7 +23,7 @@ const scriptUrlCache = new Set();
const iconList = [];

const create = (options = {}) => {
const { scriptUrl, extraIconProps = {}} = options;
const { scriptUrl, extraIconProps = {} } = options;

if (!scriptUrlCache.has(scriptUrl)) {
const script = document.createElement('script');
@@ -32,8 +32,8 @@ const create = (options = {}) => {
document.body.appendChild(script);

fetch(scriptUrl)
.then(response => response.text())
.then(params => {
.then((response) => response.text())
.then((params) => {
params.replace(/id="([^"]+)"/gi, (...item) => {
iconList.push(item[1].replace(/icon-/, ''));
});
@@ -65,11 +65,14 @@ const create = (options = {}) => {
[`${extraIconProps.class}-${type}`]: !!extraIconProps.class,
});
// 合并 vue 参数
const iconProps = mergeProps(extraIconProps, data, { class: classString }, { props: restProps, on: listeners });

return (
<Icon {...iconProps}>{content}</Icon>
const iconProps = mergeProps(
extraIconProps,
data,
{ class: classString },
{ props: restProps, on: listeners }
);

return <Icon {...iconProps}>{content}</Icon>;
},
};



+ 15
- 15
webapp/src/components/IconFont/index.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

/**
* 使用方式:
@@ -26,7 +26,7 @@
import create from './iconfont';

const IconFont = create({
scriptUrl: '//at.alicdn.com/t/font_1756495_6jl45md8krp.js',
scriptUrl: '//at.alicdn.com/t/font_1756495_qucjcrwy5rm.js',
extraIconProps: { class: 'svg-icon' },
});



+ 14
- 15
webapp/src/components/IconFont/utils.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

// Reference: https://blog.prototypr.io/align-svg-icons-to-text-and-say-goodbye-to-font-icons-d44b3d7b26b4
export const svgBaseProps = {
@@ -22,4 +22,3 @@ export const svgBaseProps = {
'aria-hidden': 'true',
focusable: 'false',
};


+ 66
- 66
webapp/src/components/ImageGallery/index.vue View File

@@ -1,42 +1,27 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div :class="rootClass" class="img-gallery">
<ul v-if="dataImagesLocal.length" :class="rootClass + '__wrapper'">
<li
v-for="(dataImage) in dataImagesLocal"
:key="dataImage.id"
:class="rootClass + '__item'"
>
<li v-for="dataImage in dataImagesLocal" :key="dataImage.id" :class="rootClass + '__item'">
<div v-if="!isMultiple" :class="classThumbnail(singleSelected.id, dataImage.id)">
<img :src="formatUrl(dataImage.url)" :alt="dataImage.alt" :class="rootClass + '__img'" />

<div
v-if="!isMultiple"
:class="classThumbnail(singleSelected.id, dataImage.id)"
>
<img
:src="formatUrl(dataImage.url)"
:alt="dataImage.alt"
:class="rootClass + '__img'"
>

<label
v-if="useLabel"
:class="rootClass + '__lbl'"
>
<label v-if="useLabel" :class="rootClass + '__lbl'">
{{ dataImage.alt }}
</label>
</div>
@@ -52,17 +37,25 @@
:alt="dataImage.alt"
:class="rootClass + '__img'"
@click="onClickImg(dataImage)"
/>
<el-tag
v-if="imageTagVisible && !isStatus(dataImage, 'UNANNOTATED')"
:hit="false"
class="image-tag"
:color="imageLabelTag[dataImage.id]['color']"
>{{ imageLabelTag[dataImage.id]['text'] }}</el-tag
>
<el-tag v-if="imageTagVisible && statusCodeMap[dataImage.status] !== 'UNANNOTATED'" :hit="false" class="image-tag" :color="imageLabelTag[dataImage.id]['color']">{{ imageLabelTag[dataImage.id]['text'] }}</el-tag>
<el-checkbox v-show="showOption(dataImage.id)" :value="selectedMap[dataImage.id]" class="image-checkbox" @change="checked => handleCheck(dataImage, checked)" />
<el-checkbox
v-show="showOption(dataImage.id)"
:value="selectedMap[dataImage.id]"
class="image-checkbox"
@change="(checked) => handleCheck(dataImage, checked)"
/>
<div v-show="showOption(dataImage.id)" :title="dataImage.name" class="img-name-row">
<div class="img-name">{{ basename(dataImage.url) }}</div>
</div>

<label
v-if="useLabel"
:class="rootClass + '__lbl'"
>
<label v-if="useLabel" :class="rootClass + '__lbl'">
{{ dataImage.alt }}
</label>
</div>
@@ -74,7 +67,7 @@
<script>
import Vue from 'vue';
import { bucketHost } from '@/utils/minIO';
import { fileCodeMap, findKey, statusCodeMap } from '@/views/dataset/util';
import { fileCodeMap, findKey, isStatus } from '@/views/dataset/util';

// eslint-disable-next-line import/no-extraneous-dependencies
const path = require('path');
@@ -119,13 +112,13 @@ export default {
multipleSelected: [],
imageTagVisible: true,
imgStatusMap: {
'UNRECOGNIZED': {'text': '未识别', 'color': '#FFFFFF'},
'UNANNOTATED': {'text': '未标注', 'color': '#FFFFFF'},
'AUTO_ANNOTATED': { 'text': '自动', 'color': '#468CFF' },
'MANUAL_ANNOTATED': { 'text': '人工', 'color': '#FF9943' },
UNRECOGNIZED: { text: '未识别', color: '#FFFFFF' },
UNANNOTATED: { text: '未标注', color: '#FFFFFF' },
AUTO_ANNOTATED: { text: '自动', color: '#468CFF' },
MANUAL_ANNOTATED: { text: '人工', color: '#FF9943' },
},
hoverImg: null,
statusCodeMap,
isStatus,
};
},
computed: {
@@ -142,21 +135,28 @@ export default {
},
imageLabelTag() {
const labelTag = {};
this.dataImages.forEach((item) => {
const statusInfo = this.imgStatusMap[findKey(item.status, fileCodeMap)];
const annotation = JSON.parse(item.annotation);
let categoryName = '未识别';
let tagColor = '#db2a2a';
if (statusInfo && (annotation instanceof Array) && annotation.length > 0) {
const categoryId = annotation[0].category_id;
categoryName = this.categoryId2Name[categoryId];
tagColor = statusInfo.color;
}
labelTag[item.id] = {
'text': `${statusInfo.text} | ${categoryName}`,
'color': tagColor,
};
});
try {
this.dataImages.forEach((item) => {
const statusInfo = this.imgStatusMap[findKey(item.status, fileCodeMap)];
const annotation = JSON.parse(item.annotation);
let categoryName = '未识别';
let tagColor = '#db2a2a';
if (statusInfo && Array.isArray(annotation) && annotation.length > 0) {
annotation.sort((a, b) => b.score - a.score); // 标注按照score降序排序
const categoryId = annotation[0].category_id; // 取score最高的标注标签予以显示
categoryName = this.categoryId2Name[categoryId] || '';
tagColor = statusInfo.color;
}
const divider = categoryName && `| ${categoryName}`;
labelTag[item.id] = {
text: `${statusInfo.text} ${divider}`,
color: tagColor,
};
});
} catch (err) {
console.error(err);
throw err;
}
return labelTag;
},
},
@@ -187,7 +187,7 @@ export default {
return `${baseMultipleClass}`;
},
onSelectImage(objectImage) {
this.singleSelected = { ...this.singleSelected, ...objectImage};
this.singleSelected = { ...this.singleSelected, ...objectImage };
this.$emit('onselectimage', objectImage);
},
onClickImg(objectImage) {
@@ -211,7 +211,7 @@ export default {
return this.hoverImg?.id === id;
},
hasSelected(id) {
return this.multipleSelected.find(item => id === item);
return this.multipleSelected.find((item) => id === item);
},
showOption(id) {
return this.isHover(id) || this.hasSelected(id);
@@ -234,7 +234,7 @@ export default {
this.$emit('onselectmultipleimage', this.multipleSelected);
},
selectAll() {
this.multipleSelected = this.dataImages.map(d => d.id);
this.multipleSelected = this.dataImages.map((d) => d.id);
for (const key in this.selectedMap) {
this.selectedMap[key] = true;
}
@@ -257,7 +257,7 @@ export default {
setInitialSelection() {
if (this.selectImgsId) {
if (!this.isMultiple && this.selectImgsId.length === 1) {
this.singleSelected = { ...this.selectImgsId[0]};
this.singleSelected = { ...this.selectImgsId[0] };
} else {
this.multipleSelected = [].concat(this.selectImgsId);
}
@@ -271,8 +271,8 @@ export default {
</script>

<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
@import "~@/assets/styles/mixin.scss";
@import '~@/assets/styles/variables.scss';
@import '~@/assets/styles/mixin.scss';

.img-gallery {
min-height: 200px;


+ 44
- 0
webapp/src/components/InfoAlert/index.vue View File

@@ -0,0 +1,44 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template functional>
<div class="el-alert el-alert--primary is-dark">
<div class="el-alert-content">
<slot />
</div>
</div>
</template>
<script>
export default {
name: 'InfoAlert',
};
</script>
<style scoped lang="scss">
@import '~@/assets/styles/variables.scss';

.el-alert--primary {
padding-top: 7px;
padding-bottom: 7px;
line-height: 30px;
color: #2e4fde;
background-color: $primaryPlainBgColor;
border: 1px solid $primaryBorderColor;

.el-alert-content {
width: 100%;
}
}
</style>

+ 19
- 0
webapp/src/components/InfoRadio/index.js View File

@@ -0,0 +1,19 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import InfoRadio from './info-radio';

export default InfoRadio;

+ 111
- 0
webapp/src/components/InfoRadio/info-radio.vue View File

@@ -0,0 +1,111 @@
<template>
<div class="info-data-radio">
<el-radio-group ref="radioRef" v-model="state.sValue" v-bind="attrs" v-on="listeners">
<component
:is="radioElement"
v-for="item in state.list"
:key="item.value"
:label="item.value"
:disabled="item.disabled"
:title="item.label"
>
{{ item.label }}
</component>
</el-radio-group>
</div>
</template>
<script>
import { reactive, computed, watch, ref } from '@vue/composition-api';
import { isNil } from 'lodash';

export default {
name: 'InfoRadio',
inheritAttrs: false,
model: {
prop: 'value',
event: 'change',
},
props: {
request: Function, // 预留
value: {
type: [String, Number],
},
type: {
type: String,
},
labelKey: {
type: String,
default: 'label',
},
valueKey: {
type: String,
default: 'value',
},
dataSource: {
type: Array,
default: () => [],
},
transformOptions: Function,
innerRef: Function,
},
setup(props, ctx) {
const { labelKey, valueKey, innerRef, transformOptions } = props;

const elementRef = !isNil(innerRef) ? innerRef() : ref(null);

const buildOptions = (list) =>
list.map((d) => ({
...d,
label: d[labelKey],
value: d[valueKey],
}));

const rawList = buildOptions(props.dataSource);

const list = typeof transformOptions === 'function' ? transformOptions(rawList) : rawList;

const state = reactive({
list,
sValue: !isNil(props.value) ? props.value : undefined,
});

const handleChange = (value) => {
ctx.emit('change', value);
};

watch(
() => props.value,
(next) => {
Object.assign(state, {
sValue: next,
});
}
);

watch(
() => props.dataSource,
(next) => {
Object.assign(state, {
list: buildOptions(next),
});
}
);

const radioElement = computed(() => (props.type === 'button' ? 'el-radio-button' : 'el-radio'));
const attrs = computed(() => ctx.attrs);
const listeners = computed(() => ({
...ctx.listeners,
change: handleChange,
}));

return {
state,
attrs,
elementRef,
listeners,
radioElement,
handleChange,
};
},
};
</script>

+ 14
- 14
webapp/src/components/InfoSelect/index.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import InfoSelect from './info-select';



+ 38
- 35
webapp/src/components/InfoSelect/info-select.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div class="info-data-select">
@@ -62,7 +62,7 @@ export default {
},
dataSource: {
type: Array,
default: () => ([]),
default: () => [],
},
innerRef: Function,
},
@@ -71,11 +71,12 @@ export default {

const selectRef = !isNil(innerRef) ? innerRef() : ref(null);

const buildOptions = (list) => list.map(d => ({
...d,
label: d[labelKey],
value: d[valueKey],
}));
const buildOptions = (list) =>
list.map((d) => ({
...d,
label: d[labelKey],
value: d[valueKey],
}));

const state = reactive({
list: buildOptions(props.dataSource),
@@ -86,24 +87,26 @@ export default {
ctx.emit('change', value);
};

watch(() => props.value, (next) => {
Object.assign(state, {
sValue: next,
});
}, {
lazy: true,
});
watch(
() => props.value,
(next) => {
Object.assign(state, {
sValue: next,
});
}
);

watch(() => props.dataSource, (next) => {
Object.assign(state, {
list: buildOptions(next),
});
}, {
lazy: true,
});
watch(
() => props.dataSource,
(next) => {
Object.assign(state, {
list: buildOptions(next),
});
}
);

const attrs = computed(() => ctx.attrs);
const selectEleWidth =computed(() => props.width || '100%');
const selectEleWidth = computed(() => props.width || '100%');
const listeners = computed(() => ({
...ctx.listeners,
change: handleChange,


+ 15
- 15
webapp/src/components/InfoTable/column.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

export default {
name: 'info-table-column',
@@ -24,7 +24,7 @@ export default {

if (typeof props.render === 'function') {
columnProps.scopedSlots = {
default: d => {
default: (d) => {
return props.render(d, { refresh: props.refresh });
},
};


+ 14
- 14
webapp/src/components/InfoTable/index.js View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import InfoTable from './info-table';



+ 38
- 35
webapp/src/components/InfoTable/info-table.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div class="info-data-table">
@@ -135,7 +135,7 @@ export default {
});
};

const queryList = async(cfg = {}) => {
const queryList = async (cfg = {}) => {
if (state.loading) {
return;
}
@@ -149,7 +149,7 @@ export default {
...cfg,
});
// 这边按照统一的 result, page 来进行管理
const { result = [], page = {}} = res || {};
const { result = [], page = {} } = res || {};
setPageInfo({ total: page.total });
setData(result);
} finally {
@@ -159,44 +159,47 @@ export default {

onMounted(() => {
// 首先判断是否为异步请求
if(typeof request === 'function') {
if (typeof request === 'function') {
queryList();
if (typeof actionRef === 'function') {
actionRef().value = {
refresh: queryList,
};
}
} else if(Array.isArray(props.dataSource)) {
} else if (Array.isArray(props.dataSource)) {
// 检测是否为静态数据源
setData(props.dataSource);
}
});

watch(() => pageInfo.pageSize, () => {
setPageInfo({ ...pageInfo, current: 1 });
queryList();
}, {
lazy: true,
});
watch(
() => pageInfo.pageSize,
() => {
setPageInfo({ ...pageInfo, current: 1 });
queryList();
}
);

watch(() => props.dataSource, (next) => {
setData(next);
}, {
lazy: true,
});
watch(
() => props.dataSource,
(next) => {
setData(next);
}
);

watch(() => pageInfo.current, () => {
queryList();
}, {
lazy: true,
});
watch(
() => pageInfo.current,
() => {
queryList();
}
);

return {
state,
pageAttrs,
pageInfo,
refresh: queryList,
setPageInfo: info =>
setPageInfo: (info) =>
setPageInfo({
...pageInfo,
...info,


+ 25
- 21
webapp/src/components/InlineTableEdit/index.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<ValidationObserver ref="observerRef">
@@ -93,12 +93,12 @@ export default {

// 编辑标注名称
const handleOk = () => {
observerRef.value.validate().then(success => {
observerRef.value.validate().then((success) => {
if (!success) {
return;
}
// 判断是否发生过变更
if(String(state.value) !== String(props.row[valueBy])) {
if (String(state.value) !== String(props.row[valueBy])) {
ctx.emit('handleOk', state.value, props.row);
}
handleCancel();
@@ -109,16 +109,20 @@ export default {
// onShow 的时候重置
state.value = props.row[valueBy];
Vue.nextTick(() => {
const input = inputRef && inputRef.value.$refs.input || inputRef && inputRef.value.$refs.textarea;
const input =
(inputRef && inputRef.value.$refs.input) || (inputRef && inputRef.value.$refs.textarea);
input && input.focus();
});
};

watch(() => props.row, (next) => {
if (next) {
state.value = next[valueBy];
watch(
() => props.row,
(next) => {
if (next) {
state.value = next[valueBy];
}
}
});
);

return {
props,


+ 38
- 37
webapp/src/components/LogContainer/index.vue View File

@@ -1,23 +1,21 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div
v-mouse-wheel="getLog"
>
<div v-mouse-wheel="getLog">
<prism-render :code="logTxt" />
</div>
</template>
@@ -86,28 +84,31 @@ export default {
...this.options,
startLine: this.currentLogLine,
lines: this.logLines,
}).then(res => {
this.logList = this.logList.concat(res.content);
this.currentLogLine = res.endLine + 1;
})
.then((res) => {
this.logList = this.logList.concat(res.content);
this.currentLogLine = res.endLine + 1;

// 当请求到的行数小于请求行数时,冻结请求一秒
if (res.lines < this.logLines) {
this.pauseRequest();
// 当返回行数小于三行时提示日志已到达底部
// TODO: logMsgInstance 到达底部提示是否应该设为,当有新的提示出现,关闭旧的提示,而不是等三秒后自动消失?
if (!noWarning && res.lines < 3 && !this.logMsgInstance) {
this.logMsgInstance = this.$message.warning({
message: '已经到达日志底部了。',
onClose: this.onLogMsgClose,
});
// 当请求到的行数小于请求行数时,冻结请求一秒
if (res.lines < this.logLines) {
this.pauseRequest();
// 当返回行数小于三行时提示日志已到达底部
// TODO: logMsgInstance 到达底部提示是否应该设为,当有新的提示出现,关闭旧的提示,而不是等三秒后自动消失?
if (!noWarning && res.lines < 3 && !this.logMsgInstance) {
this.logMsgInstance = this.$message.warning({
message: '已经到达日志底部了。',
onClose: this.onLogMsgClose,
});
}
}
}
}).catch(err => {
this.pauseRequest();
throw err;
}).finally(() => {
this.logLoading = false;
});
})
.catch((err) => {
this.pauseRequest();
throw err;
})
.finally(() => {
this.logLoading = false;
});
},
reset(getLog = false) {
this.logList = [];


+ 114
- 103
webapp/src/components/LogContainer/podLogContainer.vue View File

@@ -1,37 +1,27 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div class="rel pod-log-container-inside">
<div
v-if="showFunctional"
>
<div v-if="showFunctional">
<el-tooltip effect="dark" content="日志置顶" placement="left">
<el-button
class="log-left-btn"
icon="el-icon-caret-top"
@click="onToTop"
/>
<el-button class="log-left-btn" icon="el-icon-caret-top" @click="onToTop" />
</el-tooltip>
<el-tooltip effect="dark" content="日志置底" placement="left">
<el-button
class="log-left-btn"
icon="el-icon-caret-bottom"
@click="onToBottom"
/>
<el-button class="log-left-btn" icon="el-icon-caret-bottom" @click="onToBottom" />
</el-tooltip>
<el-tooltip effect="dark" content="自动跟随" placement="left">
<el-button
@@ -42,18 +32,10 @@
/>
</el-tooltip>
<el-tooltip effect="dark" content="清空日志" placement="left">
<el-button
icon="el-icon-delete"
class="log-left-btn"
@click="onClearLogs"
/>
<el-button icon="el-icon-delete" class="log-left-btn" @click="onClearLogs" />
</el-tooltip>
</div>
<div
ref="logContent"
v-mouse-wheel="params"
class="log-content"
>
<div ref="logContent" v-mouse-wheel="params" class="log-content">
<prism-render :code="logTxt" />
</div>
</div>
@@ -76,9 +58,9 @@ export default {
PrismRender,
},
props: {
// 包含podName的pod对象, 用于请求日志总行数
podName: {
type: String,
// 包含 podName、namespace podVO 对象
pod: {
type: Object,
required: true,
},
// 查询日志需要用到的其他参数
@@ -96,15 +78,6 @@ export default {
type: Number,
default: 200,
},
// 顶部展示特定信息
showMsg: {
type: Boolean,
default: false,
},
msg: {
type: String,
default: '',
},
disabled: {
type: Boolean,
default: false,
@@ -123,16 +96,15 @@ export default {
logBottomLine: 0, // 当前日志数组最后一行的行号

autoFollow: false, // 自动跟随
topWarning: true, // 向上滚动请求时,如果已经到顶了,会提示一次日志到顶;每次请求日志时刷新
noRenderTag: false, // 自动跟随中点击清空时,对于下一次的结果不进行处理
};
},
computed: {
params() {
return {up: throttle(1000, this.mouseUp), down: throttle(1000, this.mouseDown)};
return { up: throttle(1000, this.mouseUp), down: throttle(1000, this.mouseDown) };
},
// 传入的 msg 信息会展示在所有日志的最前面
logTxt() {
return `${this.showMsg ? `${this.msg}\n` : ''}${this.logList.join('\n')}`;
return this.logList.length ? this.logList.join('\n') : '暂无日志\n';
},
// 确保存放日志的数组上限至少为两倍日志请求行数。
localLineLimit() {
@@ -148,17 +120,25 @@ export default {
this.mouseDownThrottle = throttle(1000, this.mouseDown);
this.mouseUpThrottle = throttle(1000, this.mouseUp);
},
deactivated() {
// 切出时停止跟随轮询
this.stopPolling();
},
methods: {
getLog(startLine, lines) {
if (!this.podName) {
this.message('没有传入 podName, 无法查询日志');
return;
if (!this.pod.namespace) {
this.message('缺少 namespace 信息, 无法查询日志');
return Promise.reject();
}
if (!this.pod.podName) {
this.message('缺少 podName 信息, 无法查询日志');
return Promise.reject();
}
startLine = startLine || 1;
lines = lines || this.logLines;
this.topWarning = true;
return getPodLog({
podName: this.podName,
podName: this.pod.podName,
namespace: this.pod.namespace,
startLine,
lines,
...this.options,
@@ -169,18 +149,13 @@ export default {
async mouseUp() {
// 如果已处于第一行或没有日志, 不向上请求
if (this.logTopLine <= 1) {
// 只进行一次到达顶部提示;任意请求日志后刷新
if (this.topWarning) {
this.topWarning = false;
if(!this.logMsgInstance) {
this.message('已经到达日志顶部.');
}
}
return;
}

// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }
if (!this.$refs.logContent) {
return;
}

// 向上滚动时,起始行为 logTopLine 减去请求行数
let reqStartLine = this.logTopLine - this.logLines;
@@ -189,19 +164,24 @@ export default {
// 请求前日志区高度
const beforeHeight = this.$refs.logContent.scrollHeight;

const { content, startLine: resStartLine } = await this.getLog(reqStartLine, this.logTopLine - reqStartLine);
const result = await this.getLog(reqStartLine, this.logTopLine - reqStartLine);
if (!result) return;
const { content, startLine: resStartLine } = result;

this.logList = content.concat(this.logList);

this.$nextTick(() => {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }
if (!this.$refs.logContent) {
return;
}

// 请求后日志区高度,从而设置顶部高度差
const afterHeight = this.$refs.logContent.scrollHeight;
this.$refs.logContent.scrollTop = afterHeight - beforeHeight;

// 限制总行数为 localLineLimit
if(this.logList.length > this.localLineLimit) {
if (this.logList.length > this.localLineLimit) {
this.logList.splice(this.localLineLimit);
}

@@ -211,42 +191,71 @@ export default {
},

// 滚轮向上滚动到底部时的事件
async mouseDown(disableWarning) {
async mouseDown(toBottom = false) {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }
if (!this.$refs.logContent) {
return;
}

// 不进行请求,同时重置 tag
if (this.noRenderTag) {
this.noRenderTag = false;
return;
}

// 请求前日志区顶部高度
const beforeTop = this.$refs.logContent.scrollTop;

const { content, endLine, lines } = await this.getLog(this.logBottomLine + 1);
const result = await this.getLog(this.logBottomLine + 1);
if (!result) return;
const { content, endLine } = result;
this.logList = this.logList.concat(content);
this.logBottomLine = endLine; // 向下滚动时, 返回的 endLine 就是最后一行的行号

if (toBottom) {
if (this.logList.length > this.localLineLimit) {
this.logList.splice(0, this.logList.length - this.localLineLimit);
}
// 将进度条拉到底部
this.$nextTick(() => {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) {
return;
}

this.$refs.logContent.scrollTop = this.$refs.logContent.scrollHeight;
});
return;
}

this.$nextTick(() => {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }
if (!this.$refs.logContent) {
return;
}

// 请求后日志区高度
const afterReqHeight = this.$refs.logContent.scrollHeight;

// 限制总行数为 localLineLimit
if(this.logList.length > this.localLineLimit) {
if (this.logList.length > this.localLineLimit) {
this.logList.splice(0, this.logList.length - this.localLineLimit);
}

this.$nextTick(() => {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }
// 剪切后日志区高度,计算高度变化差,设置去掉高度差后的 scrollTop
if (!this.$refs.logContent) {
return;
}

// 剪切后日志区高度,计算高度变化差,设置去掉高度差后的 scrollTop
const afterSpliceHeight = this.$refs.logContent.scrollHeight;
this.$refs.logContent.scrollTop = Math.max(0, beforeTop - (afterReqHeight - afterSpliceHeight));
this.$refs.logContent.scrollTop = Math.max(
0,
beforeTop - (afterReqHeight - afterSpliceHeight)
);

this.logBottomLine = endLine; // 向下滚动时, 返回的 endLine 就是最后一行的行号
this.logTopLine = this.logBottomLine - this.logList.length + 1; // 此时第一行的行号需要通过 logList 的长度进行计算

if (lines < 3 && !this.logMsgInstance && !this.autoFollow && disableWarning !== true) {
this.message('已经到达日志底部.');
}
});
});
},
@@ -257,7 +266,7 @@ export default {
this.logList = [];
this.logTopLine = this.logBottomLine = 0;
this.$nextTick(() => {
this.mouseDown(true);
this.mouseDown();
});
},

@@ -292,6 +301,10 @@ export default {

// 清空当前日志内容
async onClearLogs() {
if (this.autoFollow) {
// 如果已经在自动跟随中,则设置 tag
this.noRenderTag = true;
}
await this.changeAutoFollow(true);
// 开启自动跟随请求最底部日志之后,清空当前日志列表
this.logList = [];
@@ -306,34 +319,28 @@ export default {
return;
}
this.logList = [];
const countObj = await countPodLogs([{ podName: this.podName }]); // 获取对应pod日志总行数
const linesCount = countObj[this.podName];
const countObj = await countPodLogs(this.pod.namespace, [this.pod]); // 获取对应pod日志总行数
const linesCount = countObj[this.pod.podName];

// 请求最后的 logLines 行
this.logBottomLine = Math.max(linesCount - this.logLines, 0);
await this.mouseDown();
// 将进度条拉到底部
this.$nextTick(() => {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }

this.$refs.logContent.scrollTop = this.$refs.logContent.scrollHeight;
});
await this.mouseDown(true);
},

// 日志跟随实现
async logPolling() {
if (!this.autoFollow) { return; }
if (!this.autoFollow) {
return;
}

await this.mouseDownThrottle();
// 将进度条拉到底部
this.$nextTick(() => {
// 如果此时元素已不存在,则不进行任何其他操作
if (!this.$refs.logContent) { return; }
await this.mouseDownThrottle(true);

this.$refs.logContent.scrollTop = this.$refs.logContent.scrollHeight;
});
setTimeout(this.logPolling, 1000);
},
// 停止跟随
stopPolling() {
this.autoFollow = false;
},

// 判断在自动跟随滚轮是否向上
watchScroll(event) {
@@ -361,4 +368,8 @@ export default {
overflow: auto;
border: #ccc solid 1px;
}

::v-deep pre[class*='language-'] {
margin: 0;
}
</style>

+ 24
- 33
webapp/src/components/LoginPublic/index.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div style="height: 100%;">
@@ -21,12 +21,8 @@
<div class="right" />
</div>
<div id="content">
<div class="left">
<div
class="image"
@mouseenter="stopSlider"
@mouseleave="startSlider"
>
<div class="left mb-dn">
<div class="image" @mouseenter="stopSlider" @mouseleave="startSlider">
<transition-group ref="loginList" name="login-list" tag="ul">
<li
v-for="item in loginImageList"
@@ -35,25 +31,21 @@
class="image-item"
>
<!-- 文本介绍 -->
<div class="carousel-title">{{item.title}}</div>
<div class="carousel-text">{{item.text}}</div>
<div class="carousel-title">{{ item.title }}</div>
<div class="carousel-text">{{ item.text }}</div>
</li>
</transition-group>
<!-- 翻页指示器 -->
<ul class="indicator-item">
<li
v-for="(item,index) in loginImageList.length"
v-for="(item, index) in loginImageList.length"
:key="index"
:class="{'active': index === currentIndex}"
:class="{ active: index === currentIndex }"
@click="currentIndex = index"
>
</li>
></li>
</ul>
<!-- 底部 -->
<div
v-if="$store.state.settings.showFooter"
id="el-login-footer"
>
<div v-if="$store.state.settings.showFooter" id="el-login-footer">
<span>{{ $store.state.settings.footerTxt }}</span>
<template v-if="$store.state.settings.caseNumber">
<span>⋅</span>
@@ -62,11 +54,11 @@
</div>
</div>
</div>
<div class="right">
<div class="right mb-w100">
<!-- 左侧部分 -->
<slot />
<div class="footer-logo">
<img src="@/assets/images/dubhe-logo.svg" width="74" alt>
<img src="@/assets/images/dubhe-logo.svg" width="74" alt />
</div>
</div>
</div>
@@ -282,4 +274,3 @@ export default {
transition: all 0.5s linear;
}
</style>


+ 50
- 0
webapp/src/components/MsgPopover/index.vue View File

@@ -0,0 +1,50 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved. * * Licensed under the Apache License,
Version 2.0 (the "License"); * you may not use state file except in compliance with the License. *
You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless
required by applicable law or agreed to in writing, software * distributed under the License is
distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. * See the License for the specific language governing permissions and * limitations under
the License. * ============================================================= */

<template>
<el-popover v-if="show" placement="right" width="400" trigger="hover" :offset="20">
<el-table :data="msgList" :show-header="false" :empty-text="emptyText">
<el-table-column prop="name" show-overflow-tooltip />
<el-table-column prop="message" show-overflow-tooltip />
</el-table>
<i slot="reference" class="el-icon-warning-outline primary f16 v-text-top" />
</el-popover>
</template>

<script>
import { computed } from '@vue/composition-api';

export default {
props: {
show: Boolean,
statusDetail: {
type: String,
require: true,
},
emptyText: {
type: String,
default: '暂无提示信息',
},
},
setup(props) {
const msgList = computed(() => {
try {
const msg = JSON.parse(props.statusDetail);
const list = Object.keys(msg).map((m) => ({ name: m, message: msg[m] }));
return list;
} catch (e) {
return [];
}
});

return {
msgList,
};
},
};
</script>

+ 498
- 0
webapp/src/components/PodMonitor/index.vue View File

@@ -0,0 +1,498 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div v-loading="loadingHistory" class="pod-monitor-container">
<div v-if="displayCpu" :id="cpuId" class="charts" />
<div v-if="displayMem" :id="memId" class="charts" />
<div v-if="displayGpu && !usePodName" class="gpu-select-container">
<label class="pr-20">GPU 节点</label>
<el-select
v-model="selectedPod"
placeholder="请选择展示的节点"
class="my-10"
filterable
@change="onPodSelectChange"
>
<el-option label="全部" :value="null" />
<el-option v-for="pod in gpuPodList" :key="pod" :label="pod" :value="pod" />
</el-select>
</div>
<div v-if="displayGpu" :id="gpuId" class="charts" />
</div>
</template>

<script>
import { nanoid } from 'nanoid';
import echarts from 'echarts';

import { parseTime, cpuPercentage, memNormalize, ONE_HOUR, toUnixTimestamp } from '@/utils';
import { getMetrics, getHistoryMetrics } from '@/api/system/pod';

import { defaultOption, cpuOption, memOption, gpuOption } from './util';

export default {
name: 'PodMonitor',
props: {
namespace: {
type: String,
default: null,
},
resourceName: {
type: String,
default: null,
},
podName: [Array, String], // podName 支持直接传入或以数组传入
// idTag 用于构成 echarts 元素的唯一 ID,避免同页面多个监控组件导致 ID 重复
idTag: {
type: String,
default: nanoid(4),
},
// timeStep 用于指定多久轮询一次,单位毫秒,k8s 五秒更新一次数据,建议不小于 5000
timeStep: {
type: Number,
default: 5000,
},
// timePoints 用于指定保持的时间点个数
timePoints: {
type: Number,
default: 12 * 60 * 4, // 默认保留 5秒/次-四小时 的数据
},
// timeFormat 用于格式化 X 轴时间展示,规则详见 @/utils -> parseTime
timeFormat: {
type: String,
default: '{h}:{i}:{s}',
},
displayCpu: {
type: Boolean,
default: true,
},
displayMem: {
type: Boolean,
default: true,
},
displayGpu: {
type: Boolean,
default: true,
},
},
data() {
return {
pollId: 1,
loadingHistory: false,
polling: false, // 是否正在查询状态

cpuData: {}, // 以 pod 为键的一个对象
memData: {},
gpuData: {},

cpuHistoryTimeArray: [], // 拉取历史数据时,CPU、内存、GPU 使用独立的时间点数组
memHistoryTimeArray: [],
gpuHistoryTimeArray: [],
pollTimeArray: [], // 轮询期间使用统一的时间点数组

cpuChart: null, // CPU 折线图实例
memChart: null, // 内存折线图实例
gpuChart: null, // GPU 折线图实例

podNameSet: new Set(),
selectedPod: null,
};
},
computed: {
usePodName() {
// 如果 podName 传入数组,则验证数组是否有成员
if (Array.isArray(this.podName)) return this.podName.length > 0;
return Boolean(this.podName);
},
cpuId() {
return `pod-monitor-cpu-${this.idTag}`;
},
memId() {
return `pod-monitor-mem-${this.idTag}`;
},
gpuId() {
return `pod-monitor-gpu-${this.idTag}`;
},
gpuPodList() {
return Object.keys(this.gpuData);
},
monitorParam() {
const param = {
namespace: this.namespace,
};
if (this.usePodName) {
param.podNames = this.podName;
} else {
param.resourceName = this.resourceName || undefined;
}
return param;
},
},
beforeDestroy() {
this.stop();
},
methods: {
async getMetrics(option = {}) {
// 如果 namespace 不存在,或者 resourceName 和 podName 都不存在,则停止查询直接返回
if (!this.namespace || (!this.resourceName && !this.usePodName)) {
return;
}
// 如果不存在 pollId,或者 pollId 与当前 pollId 不一致,说明已经不是同一轮查询,则不继续查询直接返回
if (!option.pollId || option.pollId !== this.pollId) return;

const datas = await getMetrics(this.monitorParam);

this.pushTime();

datas.forEach(this.parseData);

this.drawCharts();

setTimeout(() => {
this.getMetrics(option);
}, this.timeStep);
},
async getHistoryMetrics() {
if (!this.namespace) {
this.$message.warning('命名空间为空,无法获取监控信息');
return;
}
if (!this.resourceName && !this.usePodName) {
this.$message.warning('资源名称或节点名为空,无法获取监控信息');
return;
}
const params = { ...this.monitorParam };

const now = new Date().getTime();

params.startTime = toUnixTimestamp(now - 4 * ONE_HOUR);
params.endTime = toUnixTimestamp(now - this.timeStep);
params.step = Math.round(this.timeStep / 1000);

this.loadingHistory = true;
const datas = await getHistoryMetrics(params).finally(() => {
this.loadingHistory = false;
});

datas.forEach(this.parseHistoryData);
},
pushTime() {
// 获取当前时间,并且整理时间列表
const now = parseTime(new Date(), this.timeFormat);
this.pollTimeArray.push(now);

// 如果 pollTimeArray 超过了限制,此时各指标 HistoryTimeArray 应当已经清空,直接清理 pollTimeArray 即可
if (this.pollTimeArray.length > this.timePoints) {
this.pollTimeArray.splice(0, 1);
return;
}

// gap 为 CPU/Mem/GPU 总时间节点超过时间点上限的数量,超过则清除最前面的 gap 个时间点
let gap = this.cpuHistoryTimeArray.length + this.pollTimeArray.length - this.timePoints;
if (gap > 0) {
this.cpuHistoryTimeArray.splice(0, gap);
}

gap = this.memHistoryTimeArray.length + this.pollTimeArray.length - this.timePoints;
if (gap > 0) {
this.memHistoryTimeArray.splice(0, gap);
}

gap = this.gpuHistoryTimeArray.length + this.pollTimeArray.length - this.timePoints;
if (gap > 0) {
this.gpuHistoryTimeArray.splice(0, gap);
}
},
parseHistoryData(pod) {
const { podName } = pod;

// 如果出现了重复的 podName, 则忽略重复数据
if (this.podNameSet.has(podName)) return;
this.podNameSet.add(podName);

if (this.displayCpu) {
this.cpuData[podName] = {};
pod.cpuMetrics.forEach((data) => {
const time = parseTime(data.time, this.timeFormat);
this.cpuHistoryTimeArray.push(time);
this.cpuData[podName][time] = data.value;
});
this.cpuHistoryTimeArray = Array.from(new Set(this.cpuHistoryTimeArray)).sort((a, b) =>
a.localeCompare(b)
);
}

if (this.displayMem) {
this.memData[podName] = {};
pod.memoryMetrics.forEach((data) => {
const time = parseTime(data.time, this.timeFormat);
this.memHistoryTimeArray.push(time);
this.memData[podName][time] = Math.round(memNormalize(data.value, 'Ki') * 10) / 10;
});
this.memHistoryTimeArray = Array.from(new Set(this.memHistoryTimeArray)).sort((a, b) =>
a.localeCompare(b)
);
}

if (this.displayGpu) {
this.$set(this.gpuData, podName, {});

let isFirstCard = true; // 只针对第一张 GPU 卡插入时间点
this.gpuData[podName].cardSet = new Set();

pod.gpuMetrics.forEach((card) => {
// 如果存在重复的卡,则忽略重复数据
if (this.gpuData[podName].cardSet.has(card.accId)) return;

this.gpuData[podName].cardSet.add(card.accId);
this.gpuData[podName][card.accId] = {};
card.values.forEach((data) => {
const time = parseTime(data.time, this.timeFormat);
// 只针对第一张 GPU 卡插入时间点
isFirstCard && this.gpuHistoryTimeArray.push(time);
this.gpuData[podName][card.accId][time] = data.value;
});
isFirstCard && (isFirstCard = false);
});
this.gpuHistoryTimeArray = Array.from(new Set(this.gpuHistoryTimeArray)).sort((a, b) =>
a.localeCompare(b)
);
}
},
parseData(data) {
const {
podName,

cpuRequestAmount,
cpuRequestFormat,
cpuUsageAmount,
cpuUsageFormat,

memoryUsageAmount,
memoryUsageFormat,
} = data;
// 必须先插入时间,然后进行数据解析
const now = this.pollTimeArray[this.pollTimeArray.length - 1];

if (!this.podNameSet.has(podName)) {
this.podNameSet.add(podName);
this.displayCpu && (this.cpuData[podName] = {});
this.displayMem && (this.memData[podName] = {});
this.displayGpu && this.$set(this.gpuData, podName, { cardSet: new Set() });
}

// 解析 CPU 数据
this.displayCpu &&
(this.cpuData[podName][now] = cpuPercentage(
cpuUsageAmount,
cpuUsageFormat,
cpuRequestAmount,
cpuRequestFormat
));

// 解析内存数据
this.displayMem &&
(this.memData[podName][now] =
Math.round(memNormalize(memoryUsageAmount, memoryUsageFormat) * 10) / 10);

// 解析 GPU 数据
if (this.displayGpu) {
data.gpuUsagePersent.forEach((card) => {
if (!this.gpuData[podName].cardSet.has(card.accId)) {
this.gpuData[podName].cardSet.add(card.accId);
this.gpuData[podName][card.accId] = {};
}
this.gpuData[podName][card.accId][now] = card.usage;
});
}
},

// 出口方法
stop() {
this.pollId += 1; // 退出时自增,避免轮询干扰
this.cpuChart && this.cpuChart.clear();
this.memChart && this.memChart.clear();
this.gpuChart && this.gpuChart.clear();

this.podNameSet.clear();
this.cpuChart = this.memChart = this.gpuChart = null;
this.cpuHistoryTimeArray.length = 0;
this.memHistoryTimeArray.length = 0;
this.gpuHistoryTimeArray.length = 0;
this.pollTimeArray.length = 0;
this.cpuData = {};
this.memData = {};
this.gpuData = {};

this.polling = false;
},

// 入口方法
async init() {
if (this.polling) {
this.stop();
}

this.initCharts();
this.polling = true;

await this.getHistoryMetrics();
this.getMetrics({ pollId: this.pollId });
},
initCharts() {
if (this.displayCpu) {
this.initCpu();
}
if (this.displayMem) {
this.initMem();
}
if (this.displayGpu) {
this.initGpu();
}
},
initCpu() {
this.cpuChart = echarts.init(document.getElementById(this.cpuId));
this.cpuChart.setOption(defaultOption);
this.cpuChart.setOption(cpuOption);
},
initMem() {
this.memChart = echarts.init(document.getElementById(this.memId));
this.memChart.setOption(defaultOption);
this.memChart.setOption(memOption);
},
initGpu() {
this.gpuChart = echarts.init(document.getElementById(this.gpuId));
this.gpuChart.setOption(defaultOption);
this.gpuChart.setOption(gpuOption);
},
drawCharts() {
if (this.displayCpu) {
this.drawCpu();
}
if (this.displayMem) {
this.drawMem();
}
if (this.displayGpu) {
this.drawGpu();
}
},
drawCpu() {
// 数据计算放在画图的地方来做,在不需要画图时就无需计算
const timeArray = this.cpuHistoryTimeArray.concat(this.pollTimeArray);
const seriesData = [];
Object.keys(this.cpuData).forEach((podName) => {
const data = timeArray.map((time) => this.cpuData[podName][time]);
seriesData.push({
name: podName,
type: 'line',
data,
});
});

this.cpuChart &&
this.cpuChart.setOption({
xAxis: {
type: 'category',
boundaryGap: false,
data: timeArray,
},
series: seriesData,
legend: {
data: Object.keys(this.cpuData),
},
});
},
drawMem() {
// 数据计算放在画图的地方来做,在不需要画图时就无需计算
const timeArray = this.memHistoryTimeArray.concat(this.pollTimeArray);
const seriesData = [];
Object.keys(this.memData).forEach((podName) => {
const data = timeArray.map((time) => this.memData[podName][time]);
seriesData.push({
name: podName,
type: 'line',
data,
});
});

this.memChart &&
this.memChart.setOption({
xAxis: {
type: 'category',
boundaryGap: false,
data: timeArray,
},
series: seriesData,
legend: {
data: Object.keys(this.memData),
},
});
},
drawGpu(noMerge) {
// 数据计算放在画图的地方来做,在不需要画图时就无需计算
const timeArray = this.gpuHistoryTimeArray.concat(this.pollTimeArray);
const seriesData = [];
const legendList = [];
let name;
Object.keys(this.gpuData).forEach((pod) => {
if (this.selectedPod && this.selectedPod !== pod) return;
Array.from(this.gpuData[pod].cardSet).forEach((card) => {
name = `${pod}: ${card
.split('-')
.slice(0, 2)
.join('-')}`; // 由于卡名的构成是 UUID,为缩减长度,画图时只截取前两段
legendList.push(name);
const data = timeArray.map((time) => this.gpuData[pod][card][time]);
seriesData.push({
name,
type: 'line',
data,
});
});
});
// noMerge 模式下完全重新绘制
if (noMerge) {
this.gpuChart.clear();
this.gpuChart.setOption(defaultOption);
this.gpuChart.setOption(gpuOption);
}
this.gpuChart &&
this.gpuChart.setOption({
xAxis: {
type: 'category',
boundaryGap: false,
data: timeArray,
},
series: seriesData,
legend: {
data: legendList,
},
});
},

onPodSelectChange() {
this.drawGpu(true);
},
},
};
</script>

<style lang="scss" scoped>
.charts {
min-height: 300px;
}
</style>

+ 147
- 0
webapp/src/components/PodMonitor/util.js View File

@@ -0,0 +1,147 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

import { round } from 'lodash';

// 公共默认配置
export const defaultOption = {
// x轴
xAxis: {
type: 'category',
boundaryGap: false,
},
// y轴
yAxis: {
splitLine: {
show: false,
},
min(value) {
// 如果图中没有值,y轴最小值默认设为 0
if (value.min === Infinity) {
return 0;
}
// y轴最小值不小于 0; y轴最小值与数据最小值的距离不大于 10,且不大于数据最大值与 100 之间的距离
return round(Math.max(value.min - Math.min(100 - value.max, 10), 0), 2);
},
max(value) {
// 如果图中没有值,y轴最大值默认设为 100
if (value.max === -Infinity) {
return 100;
}
// y轴最大值不大于 100; y轴最大值与数据最大值的距离不大于 10,且不大于数据最小值与 0 之间的距离
return round(Math.min(value.max + Math.min(value.min, 10), 100), 2);
},
},
grid: {
right: '5%',
},
// 图例,涉及多节点展示
legend: {
show: true,
width: 400,
data: [],
},
series: {
type: 'line',
data: [],
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(245, 245, 245, 0.8)',
borderWidth: 1,
borderColor: '#ccc',
textStyle: {
color: '#000',
},
formatter(params) {
const toolTips = params.map(({ seriesName, value }) => {
return `${seriesName}: <strong>${value === undefined ? '-' : value}</strong>`;
});
return toolTips.join('<br />');
},
},
toolbox: {
right: 30,
feature: {
dataZoom: {
yAxisIndex: 'none',
},
restore: {},
},
},
dataZoom: [
{
start: 0,
},
{
type: 'inside',
},
],
};

export const cpuOption = {
title: {
text: 'CPU',
},
// y轴
yAxis: {
name: 'CPU 占用率(%)',
},
};

export const memOption = {
title: {
text: '内存',
},
// y轴
yAxis: {
name: '内存使用量(Gi)',
min(value) {
if (value.min === Infinity) {
return 0;
}
// 内存 y轴最小值不小于 0; y轴最小值与数据最小值的距离不大于 1。内存理论上不设置内存上限
return round(Math.max(value.min - 1, 0), 2);
},
max(value) {
// 内存无数据时默认设置 y 轴上限为 8
if (value.max === -Infinity) {
return 8;
}
// 内存 y轴最大值与数据最大值的距离不大于 1,且不大于数据最小值与 0 之间的距离; 理论上不设置上限
return round(value.max + Math.min(1, value.min), 2);
},
},
};

export const gpuOption = {
title: {
text: 'GPU',
},
// y轴
yAxis: {
name: 'GPU 占用率(%)',
},
tooltip: {
formatter(params) {
const toolTips = params.map(({ seriesName, value }) => {
const [podName, accId] = seriesName.split(': ');
return `${podName}: <br />${accId}: <strong>${value === undefined ? '-' : value}</strong>`;
});
return toolTips.join('<br />');
},
},
};

+ 20
- 24
webapp/src/components/Prism/index.vue View File

@@ -1,18 +1,18 @@
/** Copyright 2020 Tianshu AI Platform. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================
*/

<template>
<div class="prism-wrapper">
@@ -22,7 +22,7 @@

<script>
import 'prismjs';
import 'prismjs/themes/prism.css';
import 'prism-themes/themes/prism-atom-dark.css';
import 'prismjs/components/prism-python';
import Prism from 'vue-prism-component';

@@ -41,13 +41,9 @@ export default {
};
</script>
<style lang="scss" scoped>
.prism-wrapper .prism-content {
background: none;
}

code[class*="language-"],
pre[class*="language-"] {
word-wrap: break-word;
white-space: pre-wrap;
}
code[class*='language-'],
pre[class*='language-'] {
word-wrap: break-word;
white-space: pre-wrap;
}
</style>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save