diff --git a/webapp/.env.mock b/webapp/.env.mock
new file mode 100644
index 0000000..f913c6a
--- /dev/null
+++ b/webapp/.env.mock
@@ -0,0 +1,4 @@
+ENV='development'
+VUE_APP_MOCK=true
+VUE_APP_BASE_API = ''
+VUE_APP_DATA_API = '/mock'
diff --git a/webapp/.eslintignore b/webapp/.eslintignore
index 71a5886..5f8e217 100644
--- a/webapp/.eslintignore
+++ b/webapp/.eslintignore
@@ -2,4 +2,5 @@ build/*.js
src/assets
public
dist
-src/components/Crud
\ No newline at end of file
+src/components/Crud
+mock
\ No newline at end of file
diff --git a/webapp/.npmrc b/webapp/.npmrc
new file mode 100644
index 0000000..cafe685
--- /dev/null
+++ b/webapp/.npmrc
@@ -0,0 +1 @@
+package-lock=true
diff --git a/webapp/CHANGELOG.md b/webapp/CHANGELOG.md
index 4de36e2..b01e4c4 100644
--- a/webapp/CHANGELOG.md
+++ b/webapp/CHANGELOG.md
@@ -1,3 +1,18 @@
+## 0.2.1 (2020-11-16)
+
+### Features
+
+- 页面布局中的footer可配置
+- 新增前端开发时mock后端接口的功能
+- [数据管理] 创建数据集时选择标签组、标签组管理查看标签详情体验优化
+- [训练管理] 提取前端参数配置到公共配置文件 (config/index.js)
+
+### Bug Fixs
+
+- 锁定Element UI版本,修复其新版不兼容升级导致的功能异常
+- [训练管理] 分布式训练默认节点数调整, 节点数下限改为2
+- [训练管理] 修复模型下载、模型保存、断点续训目录树弹窗loading效果
+
## 0.2.0 (2020-10-26)
### Breaking Change
diff --git a/webapp/README.md b/webapp/README.md
index b189f9e..5eddbc3 100644
--- a/webapp/README.md
+++ b/webapp/README.md
@@ -79,6 +79,15 @@ npm install
npm run dev
```
+## 接口 Mock
+
+当前项目自动集成了接口 mock 服务,用户可以通过 `npm run mock` 启动数据 mock 服务。
+
+- 普通接口:在 `mock` 目录下创建根据请求 url 创建对应文件,比如请求路径是`api/data/datasets`,在就直接创建 `mock/api/data/datasets.js` 文件,并导出 mock 文件
+- RESTful 风格接口:在 `mock/mock-map` 文件下创建对应的文件 map, key 为符合[path-to-regexp](https://github.com/pillarjs/path-to-regexp) 风格的路径,value 为对应的实际 mock 文件地址
+
+如果用户未创建 mock 文件,请求会转发到 `development` 环境指定的 api 地址。
+
## 项目结构
```
diff --git a/webapp/mock/api/data/datasets.js b/webapp/mock/api/data/datasets.js
new file mode 100644
index 0000000..0a90cac
--- /dev/null
+++ b/webapp/mock/api/data/datasets.js
@@ -0,0 +1,56 @@
+module.exports = {
+ "code": 200,
+ "msg": null,
+ "data": {
+ "result": [{
+ "id": 56,
+ "name": "bag_data",
+ "remark": "不可删除,不可删除",
+ "type": 0,
+ "uri": null,
+ "dataType": 0,
+ "annotateType": 2,
+ "status": 104,
+ "createTime": "2020-10-21 15:39:01",
+ "updateTime": "2020-10-22 14:13:10",
+ "team": null,
+ "createUser": null,
+ "updateUser": null,
+ "progress": null,
+ "currentVersionName": null,
+ "decompressState": 0,
+ "labelGroupId": 1,
+ "labelGroupName": "COCO",
+ "labelGroupType": 1,
+ "import": false,
+ "top": true
+ }, {
+ "id": 346,
+ "name": "test432",
+ "remark": "test432",
+ "type": 0,
+ "uri": null,
+ "dataType": 0,
+ "annotateType": 1,
+ "status": 101,
+ "createTime": "2020-10-27 15:20:58",
+ "updateTime": "2020-10-27 15:20:58",
+ "team": null,
+ "createUser": null,
+ "updateUser": null,
+ "progress": null,
+ "currentVersionName": null,
+ "decompressState": 0,
+ "labelGroupId": 468,
+ "labelGroupName": "test432",
+ "labelGroupType": 0,
+ "import": false,
+ "top": false
+ }],
+ "page": {
+ "size": 10,
+ "current": 1,
+ "total": 218
+ },
+ }
+}
diff --git a/webapp/mock/api/data/labelGroup/getList/id.js b/webapp/mock/api/data/labelGroup/getList/id.js
new file mode 100644
index 0000000..0a68b30
--- /dev/null
+++ b/webapp/mock/api/data/labelGroup/getList/id.js
@@ -0,0 +1,5 @@
+module.exports = {
+ "code": 200,
+ "msg": null,
+ "data": []
+}
\ No newline at end of file
diff --git a/webapp/mock/mock-map.js b/webapp/mock/mock-map.js
new file mode 100644
index 0000000..ee14253
--- /dev/null
+++ b/webapp/mock/mock-map.js
@@ -0,0 +1,4 @@
+// 定义 RESTful 接口和实际代码的映射
+module.exports = {
+ 'GET::/api/data/labelGroup/getList/(\\d+)': '/api/data/labelGroup/getList/id',
+};
diff --git a/webapp/package.json b/webapp/package.json
index c8eddae..5604797 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -1,6 +1,6 @@
{
"name": "dubhe-web",
- "version": "0.2.0",
+ "version": "0.2.1",
"description": "之江天枢人工智能开源平台",
"author": "zhejianglab",
"keywords": [
@@ -11,6 +11,7 @@
"人工智能"
],
"scripts": {
+ "mock": "vue-cli-service serve --mode mock --open",
"dev": "vue-cli-service serve --open",
"build:prod": "vue-cli-service build",
"build:test": "vue-cli-service build --mode test",
@@ -51,7 +52,7 @@
"date-fns": "^2.13.0",
"echarts": "4.2.1",
"echarts-gl": "^1.1.1",
- "element-ui": "^2.13.2",
+ "element-ui": "2.13.2",
"file-saver": "^2.0.2",
"filereader-stream": "^2.0.0",
"jquery": "^3.5.1",
@@ -66,6 +67,7 @@
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"p-map": "^4.0.0",
+ "path-to-regexp": "^6.2.0",
"prismjs": "^1.20.0",
"promise.allsettled": "^1.0.2",
"qs": "^6.9.1",
@@ -105,6 +107,7 @@
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-vue": "^6.2.2",
+ "express-http-proxy": "^1.6.2",
"html-webpack-plugin": "3.2.0",
"husky": "^4.2.5",
"less": "^3.11.3",
diff --git a/webapp/src/components/Training/jobForm.vue b/webapp/src/components/Training/jobForm.vue
index 2542f0f..5b80ef1 100644
--- a/webapp/src/components/Training/jobForm.vue
+++ b/webapp/src/components/Training/jobForm.vue
@@ -222,8 +222,8 @@
@@ -282,7 +282,7 @@
id="delayCreateTime"
v-model="form.delayCreateTime"
:min="0"
- :max="168"
+ :max="trainConfig.delayCreateTimeMax"
:step-strictly="true"
/> 小时
@@ -295,7 +295,7 @@
id="delayDeleteTime"
v-model="form.delayDeleteTime"
:min="0"
- :max="168"
+ :max="trainConfig.delayDeleteTimeMax"
:step-strictly="true"
/> 小时
@@ -374,6 +374,7 @@ import { list as getAlgorithmList } from '@/api/algorithm/algorithm';
import { harborProjectNames, harborImageNames } from '@/api/system/harbor';
import { list as getModelName } from '@/api/model/model';
import { list as getModelTag } from '@/api/model/modelVersion';
+import { trainConfig } from '@/config';
import RunParamForm from './runParamForm';
import DataSourceSelector from './dataSourceSelector';
@@ -442,6 +443,7 @@ export default {
dictReady: false,
delayCreateDelete: false,
selectedAlgorithm: null,
+ trainConfig,
form: { ...defaultForm },
rules: {
@@ -814,9 +816,7 @@ export default {
this.onResourcesPoolTypeChange();
},
onTrainTypeChange(trainType) {
- if (trainType === 0) {
- this.form.resourcesPoolNode = 1;
- }
+ this.form.resourcesPoolNode = trainType === 0 ? 1 : 2;
},
},
};
diff --git a/webapp/src/config/index.js b/webapp/src/config/index.js
index 6255f1c..ed79491 100644
--- a/webapp/src/config/index.js
+++ b/webapp/src/config/index.js
@@ -14,31 +14,52 @@
* =============================================================
*/
-module.exports = {
- minIO: {
- development: {
- config: {
- endPoint: '', // MinIO 服务地址
- port: 9000,
- useSSL: false,
- },
- bucketName: 'dubhe-dev',
+// minIO 参数配置
+export const minIO = {
+ development: {
+ config: {
+ endPoint: '', // MinIO 服务地址
+ port: 9000,
+ useSSL: false,
},
- test: {
- config: {
- endPoint: '',
- port: 9000,
- useSSL: false,
- },
- bucketName: 'dubhe-test',
+ bucketName: 'dubhe-dev',
+ },
+ test: {
+ config: {
+ endPoint: '',
+ port: 9000,
+ useSSL: false,
},
- production: {
- config: {
- endPoint: '',
- port: 9000,
- useSSL: false,
- },
- bucketName: 'dubhe-prod',
+ bucketName: 'dubhe-test',
+ },
+ production: {
+ config: {
+ endPoint: '',
+ port: 9000,
+ useSSL: false,
},
+ bucketName: 'dubhe-prod',
},
};
+
+// 训练管理模块参数配置
+export const trainConfig = {
+ trainNodeMax: Infinity, // 分布式训练节点上限
+ delayCreateTimeMax: 168, // 延时启动时间上限
+ delayDeleteTimeMax: 168, // 训练时长上限
+};
+
+// 算法管理参数配置
+export const algorithmConfig = {
+ uploadFileAcceptSize: 1024, // 上传算法文件大小限制,单位为 MB,0 表示不限制大小
+};
+
+// 镜像管理参数配置
+export const imageConfig = {
+ uploadFileAcceptSize: 0, // 上传镜像文件大小限制,单位为 MB,0 表示不限制大小
+};
+
+// 模型管理模块参数配置
+export const modelConfig = {
+ uploadFileAcceptSize: 0, // 上传模型文件大小限制,单位为 MB,0 表示不限制大小
+};
diff --git a/webapp/src/layout/BaseLayout.vue b/webapp/src/layout/BaseLayout.vue
index 9bfd700..9ebc7df 100644
--- a/webapp/src/layout/BaseLayout.vue
+++ b/webapp/src/layout/BaseLayout.vue
@@ -26,11 +26,19 @@
+
+
@@ -38,7 +46,7 @@
+
+
diff --git a/webapp/src/layout/components/index.js b/webapp/src/layout/components/index.js
index 590baa5..df87f7e 100644
--- a/webapp/src/layout/components/index.js
+++ b/webapp/src/layout/components/index.js
@@ -17,4 +17,5 @@
export { default as AppMain } from './AppMain';
export { default as Navbar } from './Navbar';
export { default as Sidebar } from './Sidebar';
+export { default as Guideline } from './Guideline';
export { default as Feedback } from './Feedback';
diff --git a/webapp/src/settings.js b/webapp/src/settings.js
index 5813ff8..fdde555 100644
--- a/webapp/src/settings.js
+++ b/webapp/src/settings.js
@@ -58,9 +58,13 @@ module.exports = {
/**
* RSA公钥
*/
- publicKey: 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==',
+ publicKey: '',
/**
* 用户社区
*/
Community: 'http://www.aiiaos.cn/index.php?s=/forum/index/forum/id/45.html',
+ /**
+ * 使用文档
+ */
+ DocLink: 'http://docs.dubhe.ai/docs/' ,
};
diff --git a/webapp/src/utils/minIO.js b/webapp/src/utils/minIO.js
index f0502b7..2981f21 100644
--- a/webapp/src/utils/minIO.js
+++ b/webapp/src/utils/minIO.js
@@ -16,10 +16,10 @@
import { getMinIOAuth } from '@/api/auth';
import { decrypt } from '@/utils/rsaEncrypt';
+import { minIO } from '@/config';
const Minio = require('minio');
const toArray = require('stream-to-array');
-const Config = require('@/config');
const env = process.env.NODE_ENV || 'development';
@@ -36,7 +36,7 @@ const makeBucket = (client, bucketName) => {
});
};
-const minIOConfig = Config.minIO[env];
+const minIOConfig = minIO[env];
// 导出 bucketName
export const {bucketName} = minIOConfig;
diff --git a/webapp/src/utils/utils.js b/webapp/src/utils/utils.js
index fca1c16..d89ed76 100644
--- a/webapp/src/utils/utils.js
+++ b/webapp/src/utils/utils.js
@@ -343,3 +343,11 @@ export const getTreeListFromFilepath = async (filepath) => {
export function getUniqueId() {
return parseTime(new Date(), '{y}{m}{d}{h}{i}{s}{S}') + nanoid(4);
}
+
+// 以 MB 为入参单位,格式化上传大小文本
+export function uploadSizeFomatter(size) {
+ if (size >= 1024) {
+ return `${size / 1024} GB`;
+ }
+ return `${size} MB`;
+}
diff --git a/webapp/src/views/algorithm/index.vue b/webapp/src/views/algorithm/index.vue
index 5e00ac8..0ca4411 100644
--- a/webapp/src/views/algorithm/index.vue
+++ b/webapp/src/views/algorithm/index.vue
@@ -181,8 +181,8 @@
ref="upload"
action="fakeApi"
accept=".zip"
- :acceptSize="1024"
- :acceptSizeFormat="(size) => `${size/1024} GB`"
+ :acceptSize="algorithmConfig.uploadFileAcceptSize"
+ :acceptSizeFormat="uploadSizeFomatter"
list-type="text"
:show-file-count="false"
:params="uploadParams"
@@ -263,7 +263,7 @@
diff --git a/webapp/src/views/dataset/annotate/settingContainer/index.vue b/webapp/src/views/dataset/annotate/settingContainer/index.vue
index fbfacf8..1cfadc9 100644
--- a/webapp/src/views/dataset/annotate/settingContainer/index.vue
+++ b/webapp/src/views/dataset/annotate/settingContainer/index.vue
@@ -240,7 +240,6 @@ export default {