You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by qi...@apache.org on 2022/08/03 12:30:55 UTC

[iotdb-web-workbench] branch master updated (1c98cd8 -> a234f79)

This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git


    from 1c98cd8  Merge pull request #22 from wd94/v1.3pr
     new ff960d2  新增监控指标展示功能
     new 21d9ebe  新增监控指标展示功能
     new 893c934  新增监控指标展示功能
     new 29a7091  hotfix:add the licenses
     new a234f79  Merge pull request #17 from ljn55966005/dev-0.13.0-metircs

The 34 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 backend/pom.xml                                    |    4 +-
 .../iotdb/admin/common/exception/ErrorCode.java    |    4 +
 .../iotdb/admin/controller/FileController.java     |   11 +
 .../iotdb/admin/controller/IotDBController.java    |  110 +-
 .../iotdb/admin/controller/MetricsController.java  |  166 ++
 .../{QueryMapper.java => ViewModeMapper.java}      |    6 +-
 .../admin/model/dto/AuthorityPrivilegeDTO.java     |    1 +
 ...tyPrivilegeDTO.java => DataModelDetailDTO.java} |   12 +-
 .../model/dto/{CountDTO.java => QueryInfoDTO.java} |   10 +-
 .../model/entity/{User.java => ViewMode.java}      |   13 +-
 .../QueryDataDo.java}                              |   12 +-
 .../apache/iotdb/admin/model/vo/DataCountVO.java   |    5 +-
 .../apache/iotdb/admin/model/vo/DataModelVO.java   |   10 +
 .../model/vo/{GroupInfoVO.java => GroupInfo.java}  |    3 +-
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |    6 +-
 ...orageGroupVO.java => JVMMetricsListDataVO.java} |    6 +-
 ...esVO.java => MetircsQueryClassificationVO.java} |   10 +-
 .../vo/{DataVO.java => MetricsChartDataVO.java}    |   17 +-
 .../vo/{QueryVO.java => MetricsConnectionVO.java}  |    8 +-
 .../{DataCountVO.java => MetricsDataCountVO.java}  |   14 +-
 ...{DataInfo.java => MetricsDataForDiagramVO.java} |   11 +-
 ...{UserRolesVO.java => MetricsDataForListVO.java} |   11 +-
 .../{DataCountVO.java => MetricsListDataVO.java}   |   12 +-
 .../apache/iotdb/admin/model/vo/NodeTreeVO.java    |    9 +
 .../{QueryVO.java => QueryClassificationVO.java}   |    7 +-
 .../model/vo/{DataInfo.java => QueryData1VO.java}  |   10 +-
 .../{UserRolesVO.java => QueryDataForListVO.java}  |   11 +-
 .../model/vo/{QueryVO.java => QueryDataStrVO.java} |   11 +-
 .../vo/{DataInfo.java => QueryDataStrVO1.java}     |   10 +-
 .../model/vo/{QueryVO.java => QueryDataVO.java}    |   11 +-
 .../vo/{DeviceInfoVO.java => QueryInfoVO.java}     |    9 +-
 .../model/vo/{QueryVO.java => QueryMetricsVO.java} |   10 +-
 .../apache/iotdb/admin/service/IotDBService.java   |   33 +-
 ...ctionService.java => MetricsResultService.java} |   17 +-
 .../apache/iotdb/admin/service/MetricsService.java |   55 +
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 2029 +++++++++++++++++++-
 .../service/impl/MetricsResultServiceImpl.java     |  297 +++
 .../admin/service/impl/MetricsServiceImpl.java     | 1760 +++++++++++++++++
 backend/src/main/resources/sqlite/iotdb.db         |  Bin 36864 -> 53248 bytes
 39 files changed, 4504 insertions(+), 237 deletions(-)
 create mode 100644 backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java
 copy backend/src/main/java/org/apache/iotdb/admin/mapper/{QueryMapper.java => ViewModeMapper.java} (89%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/dto/{AuthorityPrivilegeDTO.java => DataModelDetailDTO.java} (79%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/dto/{CountDTO.java => QueryInfoDTO.java} (85%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/entity/{User.java => ViewMode.java} (77%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/{dto/AuthorityPrivilegeDTO.java => metricsDo/QueryDataDo.java} (79%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{GroupInfoVO.java => GroupInfo.java} (95%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{StorageGroupVO.java => JVMMetricsListDataVO.java} (88%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{UserRolesVO.java => MetircsQueryClassificationVO.java} (86%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DataVO.java => MetricsChartDataVO.java} (73%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{QueryVO.java => MetricsConnectionVO.java} (90%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DataCountVO.java => MetricsDataCountVO.java} (80%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DataInfo.java => MetricsDataForDiagramVO.java} (85%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{UserRolesVO.java => MetricsDataForListVO.java} (86%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DataCountVO.java => MetricsListDataVO.java} (83%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{QueryVO.java => QueryClassificationVO.java} (89%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DataInfo.java => QueryData1VO.java} (86%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{UserRolesVO.java => QueryDataForListVO.java} (86%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{QueryVO.java => QueryDataStrVO.java} (77%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DataInfo.java => QueryDataStrVO1.java} (86%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{QueryVO.java => QueryDataVO.java} (77%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{DeviceInfoVO.java => QueryInfoVO.java} (83%)
 copy backend/src/main/java/org/apache/iotdb/admin/model/vo/{QueryVO.java => QueryMetricsVO.java} (87%)
 copy backend/src/main/java/org/apache/iotdb/admin/service/{ConnectionService.java => MetricsResultService.java} (63%)
 create mode 100644 backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java
 create mode 100644 backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java
 create mode 100644 backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java


[iotdb-web-workbench] 10/34: Merge pull request #3 from apache/review/initial-commit

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit fd390fdb997bd18410974184f45fd0a31442d56f
Merge: 0ed1b60 12feef0
Author: Julian <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 14:36:20 2021 +0200

    Merge pull request #3 from apache/review/initial-commit
    
    Initial commit from @loveher147 with the backend.

 NOTICE                                             |    5 +-
 README.md                                          |    1 +
 README_zh.md                                       |   19 +-
 backend/.drone.yml                                 |   68 +
 backend/.gitignore                                 |   10 +
 backend/Dockerfile                                 |   24 +
 README.md => backend/README.md                     |   37 +-
 backend/build.gradle                               |   66 +
 backend/build.sh                                   |   20 +
 backend/doc/code-guidelines.zip                    |  Bin 0 -> 9427033 bytes
 README.md => backend/doc/config.md                 |   28 +-
 backend/doc/deploy.md                              |   65 +
 ...57\246\347\273\206\351\205\215\347\275\256.jpg" |  Bin 0 -> 286055 bytes
 .../doc/image/maven\351\205\215\347\275\256.jpg"   |  Bin 0 -> 96532 bytes
 ...05\215\347\275\256\346\226\207\344\273\266.png" |  Bin 0 -> 128969 bytes
 ...26\207\344\273\266\344\275\215\347\275\256.png" |  Bin 0 -> 60565 bytes
 backend/doc/image/pom.PNG                          |  Bin 0 -> 60121 bytes
 ...20\257\345\212\250\346\210\220\345\212\237.PNG" |  Bin 0 -> 153254 bytes
 "backend/doc/image/\346\211\223\345\214\205.png"   |  Bin 0 -> 22644 bytes
 ...05\215\347\275\256\346\226\207\344\273\266.PNG" |  Bin 0 -> 15910 bytes
 backend/doc/intro.md                               |   55 +
 README.md => backend/doc/log.md                    |   10 +-
 backend/doc/maven.md                               |   46 +
 backend/doc/note.md                                |   74 +
 README.md => backend/doc/promise.md                |    9 +-
 README.md => backend/doc/release.md                |    8 +-
 README.md => backend/doc/rest.md                   |   11 +-
 README.md => backend/doc/rule.md                   |   17 +-
 backend/doc/swagger.md                             |   51 +
 backend/doc/validate.md                            |   68 +
 backend/gradlew                                    |  188 ++
 backend/gradlew.bat                                |   89 +
 backend/pom.xml                                    |  267 +++
 backend/settings.gradle                            |   20 +
 .../org/apache/iotdb/admin/AdminApplication.java   |   36 +
 .../iotdb/admin/aop/BaseExceptionAdvice.java       |   42 +
 .../apache/iotdb/admin/aop/ParamValidAspect.java   |   72 +
 .../admin/common/exception/BaseException.java      |   41 +
 .../iotdb/admin/common/exception/ErrorCode.java    |  283 +++
 .../admin/common/utils/AuthenticationUtils.java    |   49 +
 .../apache/iotdb/admin/config/FilterConfig.java    |   44 +
 .../iotdb/admin/config/MybatisPlusConfig.java      |   48 +
 .../apache/iotdb/admin/config/SecurityConfig.java  |   48 +
 .../apache/iotdb/admin/config/SwaggerConfig.java   |   77 +
 .../iotdb/admin/config/ValidatorConfiguration.java |   43 +
 .../admin/controller/ConnectionController.java     |  128 ++
 .../iotdb/admin/controller/HealthController.java   |   46 +
 .../iotdb/admin/controller/IotDBController.java    |  915 +++++++++
 .../iotdb/admin/controller/QueryController.java    |  142 ++
 .../iotdb/admin/controller/UserController.java     |  125 ++
 .../java/org/apache/iotdb/admin/demo/JDBC.java     |  152 ++
 .../org/apache/iotdb/admin/demo/NativeAPI.java     |  113 ++
 .../org/apache/iotdb/admin/filter/TokenFilter.java |   60 +
 .../iotdb/admin/mapper/ConnectionMapper.java       |   28 +
 .../apache/iotdb/admin/mapper/DeviceMapper.java    |   28 +
 .../org/apache/iotdb/admin/mapper/GroupMapper.java |   28 +
 .../iotdb/admin/mapper/MeasurementMapper.java      |   28 +
 .../org/apache/iotdb/admin/mapper/QueryMapper.java |   28 +
 .../org/apache/iotdb/admin/mapper/UserMapper.java  |   28 +
 .../iotdb/admin/model/dto/ConnectionDTO.java       |   55 +
 .../org/apache/iotdb/admin/model/dto/CountDTO.java |   33 +
 .../apache/iotdb/admin/model/dto/DeviceDTO.java    |   36 +
 .../iotdb/admin/model/dto/DeviceInfoDTO.java       |   42 +
 .../org/apache/iotdb/admin/model/dto/GroupDTO.java |   40 +
 .../apache/iotdb/admin/model/dto/IotDBRole.java    |   36 +
 .../apache/iotdb/admin/model/dto/IotDBUser.java    |   44 +
 .../apache/iotdb/admin/model/dto/IotDBUserDTO.java |   31 +
 .../iotdb/admin/model/dto/MeasurementDTO.java      |   37 +
 .../iotdb/admin/model/dto/PrivilegeInfoDTO.java    |   40 +
 .../org/apache/iotdb/admin/model/dto/QueryDTO.java |   35 +
 .../apache/iotdb/admin/model/dto/SearchDTO.java    |   36 +
 .../apache/iotdb/admin/model/dto/Timeseries.java   |   39 +
 .../iotdb/admin/model/entity/Connection.java       |   68 +
 .../apache/iotdb/admin/model/entity/Device.java    |   55 +
 .../iotdb/admin/model/entity/Measurement.java      |   43 +
 .../org/apache/iotdb/admin/model/entity/Query.java |   43 +
 .../iotdb/admin/model/entity/StorageGroup.java     |   53 +
 .../org/apache/iotdb/admin/model/entity/User.java  |   49 +
 .../org/apache/iotdb/admin/model/vo/BaseVO.java    |   48 +
 .../org/apache/iotdb/admin/model/vo/ConnVO.java    |   36 +
 .../apache/iotdb/admin/model/vo/ConnectionVO.java  |   38 +
 .../apache/iotdb/admin/model/vo/DeviceInfo.java    |   34 +
 .../apache/iotdb/admin/model/vo/DeviceInfoVO.java  |   33 +
 .../org/apache/iotdb/admin/model/vo/DeviceVO.java  |   33 +
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |   36 +
 .../org/apache/iotdb/admin/model/vo/GroupVO.java   |   36 +
 .../apache/iotdb/admin/model/vo/IotDBUserVO.java   |   34 +
 .../apache/iotdb/admin/model/vo/MeasurementVO.java |   34 +
 .../iotdb/admin/model/vo/MeasuremtnInfoVO.java     |   33 +
 .../org/apache/iotdb/admin/model/vo/PathVO.java    |   32 +
 .../apache/iotdb/admin/model/vo/PrivilegeInfo.java |   39 +
 .../org/apache/iotdb/admin/model/vo/QueryVO.java   |   31 +
 .../org/apache/iotdb/admin/model/vo/RecordVO.java  |   33 +
 .../iotdb/admin/model/vo/RoleWithPrivilegesVO.java |   32 +
 .../apache/iotdb/admin/model/vo/SqlResultVO.java   |   35 +
 .../iotdb/admin/model/vo/StorageGroupVO.java       |   31 +
 .../iotdb/admin/service/ConnectionService.java     |   41 +
 .../apache/iotdb/admin/service/DeviceService.java  |   43 +
 .../apache/iotdb/admin/service/GroupService.java   |   44 +
 .../apache/iotdb/admin/service/IotDBService.java   |  107 ++
 .../iotdb/admin/service/MeasurementService.java    |   36 +
 .../apache/iotdb/admin/service/QueryService.java   |   39 +
 .../apache/iotdb/admin/service/UserService.java    |   32 +
 .../admin/service/impl/ConnectionServiceImpl.java  |  128 ++
 .../admin/service/impl/DeviceServiceImpl.java      |  146 ++
 .../iotdb/admin/service/impl/GroupServiceImpl.java |  163 ++
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 1967 ++++++++++++++++++++
 .../admin/service/impl/MeasurementServiceImpl.java |  150 ++
 .../iotdb/admin/service/impl/QueryServiceImpl.java |  108 ++
 .../iotdb/admin/service/impl/UserServiceImpl.java  |   81 +
 backend/src/main/resources/META-INF/app.properties |   20 +
 .../src/main/resources/application-dev.properties  |   30 +
 .../src/main/resources/application-prod.properties |   30 +
 .../src/main/resources/application-test.properties |   26 +
 backend/src/main/resources/application.properties  |   21 +
 backend/src/main/resources/log4j2-prod.xml         |  120 ++
 backend/src/main/resources/log4j2.xml              |  120 ++
 backend/src/main/resources/sqlite/iotdb.db         |  Bin 0 -> 36864 bytes
 .../test/java/org/apache/iotdb/admin/DemoJDBC.java |   38 +
 .../admin/controller/ConnectionControllerTest.java |  119 ++
 .../admin/controller/IotDBControllerTest.java      |  387 ++++
 .../admin/controller/QueryControllerTest.java      |  136 ++
 .../iotdb/admin/controller/TestSystemInfo.java     |   45 +
 123 files changed, 9483 insertions(+), 25 deletions(-)


[iotdb-web-workbench] 21/34: enable issue and wiki

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 46bb5df01e7f2bf6a21c3dfd2d2652cbcf7703ee
Author: qiaojialin <64...@qq.com>
AuthorDate: Fri Oct 8 14:02:26 2021 +0800

    enable issue and wiki
---
 .asf.yaml | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 0000000..1366c39
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+github:
+  description: "Apache IoTDB Web Workbench"
+  homepage: https://iotdb.apache.org/
+  labels:
+    - timeseries
+    - workbench
+    - iot
+    - admin
+  features:
+    wiki: true
+    issue: true
\ No newline at end of file


[iotdb-web-workbench] 28/34: 新增监控指标展示功能

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 21d9ebedf396eb936e72fcbbee7ad4d4a12bed3e
Author: loveher147 <lo...@qq.com>
AuthorDate: Mon May 30 10:40:30 2022 +0800

    新增监控指标展示功能
    
    - 该版本适配低于0.13版本的iotdb并提供数据库管理功能,但不提供监控管理(低于0.13版本iotdb不支持监控);
    - 仍然存在部分接口返回后端假数据,等待清华提供接口后替换为真实数据。
---
 .../iotdb/admin/controller/IotDBController.java    |   57 +-
 .../iotdb/admin/controller/MetricsController.java  |  170 ++
 .../apache/iotdb/admin/mapper/ViewModeMapper.java  |   13 +
 .../iotdb/admin/model/dto/DataModelDetailDTO.java  |   15 +
 .../apache/iotdb/admin/model/dto/QueryInfoDTO.java |   19 +
 .../apache/iotdb/admin/model/entity/ViewMode.java  |   30 +
 .../iotdb/admin/model/metricsDo/QueryDataDo.java   |   18 +
 .../apache/iotdb/admin/model/vo/DataModelVO.java   |   10 +
 .../org/apache/iotdb/admin/model/vo/GroupInfo.java |   16 +
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |    6 +-
 .../iotdb/admin/model/vo/JVMMetricsListDataVO.java |   14 +
 .../model/vo/MetircsQueryClassificationVO.java     |   15 +
 .../iotdb/admin/model/vo/MetricsChartDataVO.java   |   23 +
 .../iotdb/admin/model/vo/MetricsConnectionVO.java  |   15 +
 .../iotdb/admin/model/vo/MetricsDataCountVO.java   |   20 +
 .../admin/model/vo/MetricsDataForDiagramVO.java    |   16 +
 .../iotdb/admin/model/vo/MetricsDataForListVO.java |   16 +
 .../iotdb/admin/model/vo/MetricsListDataVO.java    |   17 +
 .../admin/model/vo/QueryClassificationVO.java      |   14 +
 .../apache/iotdb/admin/model/vo/QueryData1VO.java  |   15 +
 .../iotdb/admin/model/vo/QueryDataForListVO.java   |   16 +
 .../iotdb/admin/model/vo/QueryDataStrVO.java       |   21 +
 .../iotdb/admin/model/vo/QueryDataStrVO1.java      |   15 +
 .../apache/iotdb/admin/model/vo/QueryDataVO.java   |   21 +
 .../apache/iotdb/admin/model/vo/QueryInfoVO.java   |   19 +
 .../iotdb/admin/model/vo/QueryMetricsVO.java       |   14 +
 .../apache/iotdb/admin/service/IotDBService.java   |    3 +
 .../iotdb/admin/service/MetricsResultService.java  |   23 +
 .../apache/iotdb/admin/service/MetricsService.java |   41 +
 .../iotdb/admin/service/impl/IotDBServiceImpl.java |   60 +
 .../service/impl/MetricsResultServiceImpl.java     |  283 ++++
 .../admin/service/impl/MetricsServiceImpl.java     | 1746 ++++++++++++++++++++
 32 files changed, 2764 insertions(+), 17 deletions(-)

diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
index 5b4d0d0..8930913 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
@@ -95,28 +95,57 @@ public class IotDBController {
     return BaseVO.success("Get IoTDB data model successfully", dataModelVO);
   }
 
+  @GetMapping("/dataModel/detail")
+  @ApiOperation("Get IoTDB data model in detail")
+  public BaseVO<DataModelVO> getDataModelDetail(
+          @PathVariable("serverId") Integer serverId,
+          @RequestParam(value = "path", required = false, defaultValue = "root") String path,
+          @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
+          @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+          HttpServletRequest request)
+          throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    DataModelVO dataModelVO = iotDBService.getDataModelDetail(connection, path, pageSize, pageNum);
+    return BaseVO.success("Get IoTDB data model successfully", dataModelVO);
+  }
+
   @GetMapping("/storageGroups/info")
   @ApiOperation("Get information of the storage group list")
-  public BaseVO<List<GroupInfoVO>> getAllStorageGroupsInfo(
-      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+  public BaseVO<GroupInfoVO> getAllStorageGroupsInfo(
+          @PathVariable("serverId") Integer serverId,
+          @RequestParam(value = "pageSize", required = false, defaultValue = "15") Integer pageSize,
+          @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+          HttpServletRequest request)
+          throws BaseException {
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
     List<String> groupNames = iotDBService.getAllStorageGroups(connection);
-    List<GroupInfoVO> groupInfoList = new ArrayList<>();
-    if (groupNames == null || groupNames.size() == 0) {
-      return BaseVO.success("Get successfully", groupInfoList);
+    List<String> subGroupNames = new ArrayList<>();
+    int size = groupNames.size();
+    int pageStart = pageNum == 1 ? 0 : (pageNum - 1) * pageSize;
+    int pageEnd = size < pageNum * pageSize ? size : pageNum * pageSize;
+    if (size > pageStart) {
+      subGroupNames = groupNames.subList(pageStart, pageEnd);
+    }
+    List<GroupInfo> groupInfoList = new ArrayList<>();
+    GroupInfoVO groupInfoVO = new GroupInfoVO();
+    if (subGroupNames == null || subGroupNames.size() == 0) {
+      return BaseVO.success("Get successfully", groupInfoVO);
     }
     String host = connection.getHost();
-    List<Integer> deviceCounts = iotDBService.getDevicesCount(connection, groupNames);
-    List<String> descriptions = groupService.getGroupDescription(host, groupNames);
-    for (int i = 0; i < groupNames.size(); i++) {
-      GroupInfoVO groupInfoVO = new GroupInfoVO();
-      groupInfoVO.setGroupName(groupNames.get(i));
-      groupInfoVO.setDeviceCount(deviceCounts.get(i));
-      groupInfoVO.setDescription(descriptions.get(i));
-      groupInfoList.add(groupInfoVO);
+    List<Integer> deviceCounts = iotDBService.getDevicesCount(connection, subGroupNames);
+    List<String> descriptions = groupService.getGroupDescription(host, subGroupNames);
+    for (int i = 0; i < subGroupNames.size(); i++) {
+      GroupInfo groupInfo = new GroupInfo();
+      groupInfo.setGroupName(subGroupNames.get(i));
+      groupInfo.setDeviceCount(deviceCounts.get(i));
+      groupInfo.setDescription(descriptions.get(i));
+      groupInfoList.add(groupInfo);
     }
-    return BaseVO.success("Get successfully", groupInfoList);
+    groupInfoVO.setGroupInfoList(groupInfoList);
+    groupInfoVO.setGroupCount(size);
+    return BaseVO.success("Get successfully", groupInfoVO);
   }
 
   @GetMapping("/storageGroups")
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java
new file mode 100644
index 0000000..5c5a968
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.admin.controller;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.*;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.apache.iotdb.admin.service.IotDBService;
+import org.apache.iotdb.admin.service.MetricsService;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-22-上午 9:55
+ */
+@RestController
+@Api(value = "metrics related")
+public class MetricsController {
+
+  @Autowired private ConnectionService connectionService;
+  @Autowired private IotDBService iotDBService;
+  @Autowired private MetricsService metricsService;
+
+  private static final Logger logger = LoggerFactory.getLogger(MetricsController.class);
+
+  @GetMapping("/servers/metrics/connection")
+  @ApiOperation("[metrics]Get All Connection")
+  public BaseVO<List<MetricsConnectionVO>> getConnectionList(HttpServletRequest request)
+      throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    AuthenticationUtils.userAuthentication(userId, request);
+    List<ConnVO> allConnections = connectionService.getAllConnections(userId);
+    ArrayList<MetricsConnectionVO> metricsConnectionVOS = new ArrayList<>();
+    for (ConnVO connVO : allConnections) {
+      MetricsConnectionVO temp = new MetricsConnectionVO();
+      temp.setId(connVO.getId());
+      temp.setName(connVO.getAlias());
+      metricsConnectionVOS.add(temp);
+    }
+    return BaseVO.success("Get Successfully", metricsConnectionVOS);
+  }
+
+  @GetMapping("/servers/{serverId}/metrics/datacount")
+  @ApiOperation("[metrics]Get Datacount")
+  public BaseVO<MetricsDataCountVO> getMetricsConnectionDataCount(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    MetricsDataCountVO metricsDataCountVO = metricsService.getMetricsDataCount(serverId);
+    return BaseVO.success("Get IoTDB data statistics successfully", metricsDataCountVO);
+  }
+
+  @GetMapping("/servers/{serverId}/metrics/QueryClassification")
+  @ApiOperation("[metrics]Get all query classifications")
+  public BaseVO<MetircsQueryClassificationVO> getAllQueryClassification(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    MetircsQueryClassificationVO metircsQueryClassificationVO =
+        metricsService.getMetircsQueryClassification(serverId);
+    return BaseVO.success("Get IoTDB data statistics successfully", metircsQueryClassificationVO);
+  }
+
+  @GetMapping("/servers/{serverId}/metrics/{queryClassificationId}/selectcount")
+  @ApiOperation("[Metrics]Get detail information of query sql")
+  public BaseVO<QueryInfoVO> getQueryInfo(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("queryClassificationId") Integer queryClassificationId,
+      @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
+      @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+      @RequestParam(value = "filterString", required = false) String filterString,
+      @RequestParam(value = "startTime", required = false, defaultValue = "-1") String startTimeStr,
+      @RequestParam(value = "endTime", required = false, defaultValue = "-1") String endTimeStr,
+      @RequestParam(value = "executionResult", required = false) Integer executionResult,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    QueryInfoVO queryInfoVO =
+        metricsService.getQueryInfo(
+            serverId,
+            queryClassificationId,
+            pageSize,
+            pageNum,
+            filterString,
+            startTimeStr,
+            endTimeStr,
+            executionResult);
+    return BaseVO.success("Get IoTDB query statement data statistics successfully", queryInfoVO);
+  }
+
+  @GetMapping("/servers/{serverId}/metrics/diagram")
+  @ApiOperation("Get metrics data for diagram")
+  public BaseVO<MetricsDataForDiagramVO> getMetricsDataForDiagram(
+      @PathVariable("serverId") Integer serverId,
+      @RequestParam Integer metricId,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    MetricsDataForDiagramVO metricsDataForDiagramVO =
+        iotDBService.getMetricDataByMetricId(connection, metricId);
+    metricsDataForDiagramVO.setServerId(serverId);
+    return BaseVO.success("Get metrics data for diagram successfully", metricsDataForDiagramVO);
+  }
+
+  @GetMapping("/servers/{serverId}/metrics/list/{metricsType}")
+  @ApiOperation("Get metrics data for list")
+  public BaseVO<MetricsDataForListVO> getMetricsDataForList(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("metricsType") Integer metricsType,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    MetricsDataForListVO metricsDataForListVO =
+        metricsService.getMetricsDataForList(serverId, metricsType);
+    return BaseVO.success("Get metrics data for list successfully", metricsDataForListVO);
+  }
+
+  @GetMapping("/servers/{serverId}/metrics/list/query/{mode}")
+  @ApiOperation("Get query metrics data for list")
+  public BaseVO<QueryDataForListVO> getQueryMetricsDataForList(
+      @PathVariable("serverId") Integer serverId, @PathVariable("mode") Integer mode)
+      throws BaseException {
+    QueryDataForListVO queryDataForListVO = new QueryDataForListVO();
+    queryDataForListVO.setMode(mode);
+    queryDataForListVO.setServerId(serverId);
+
+    if (mode == 1) {
+      List<QueryMetricsVO> queryMetricsVOs = iotDBService.getTopQueryMetricsData();
+      queryDataForListVO.setQueryMetricsVOs(queryMetricsVOs);
+
+    } else if (mode == 0) {
+      List<QueryMetricsVO> queryMetricsVOs = iotDBService.getSlowQueryMetricsData();
+      queryDataForListVO.setQueryMetricsVOs(queryMetricsVOs);
+    }
+    return BaseVO.success("Get query metrics data for list successfully", queryDataForListVO);
+  }
+
+  private void check(HttpServletRequest request, Integer serverId) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java
new file mode 100644
index 0000000..66f9ea3
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java
@@ -0,0 +1,13 @@
+package org.apache.iotdb.admin.mapper;
+
+import org.apache.iotdb.admin.model.entity.ViewMode;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Erickin
+ * @create 2022-04-22-上午 10:32
+ */
+@Component
+public interface ViewModeMapper extends BaseMapper<ViewMode> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
new file mode 100644
index 0000000..b33cce1
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
@@ -0,0 +1,15 @@
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+import org.apache.iotdb.admin.model.vo.DataModelVO;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class DataModelDetailDTO implements Serializable {
+  private List<DataModelVO> dataModelVOList;
+  private Integer pageNum;
+  private Integer pageSize;
+  private Integer total;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java
new file mode 100644
index 0000000..7f3210b
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java
@@ -0,0 +1,19 @@
+package org.apache.iotdb.admin.model.dto;
+
+import org.apache.iotdb.admin.model.vo.QueryDataStrVO;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-下午 5:12
+ */
+@Data
+public class QueryInfoDTO {
+  private Long latestRunningTime;
+  private Integer totalCount;
+  private Integer totalPage;
+  List<QueryDataStrVO> filteredQueryDataStrVOSList;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java
new file mode 100644
index 0000000..56c9ae6
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java
@@ -0,0 +1,30 @@
+package org.apache.iotdb.admin.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Null;
+import javax.validation.constraints.Pattern;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-22-上午 10:35
+ */
+@Data
+@TableName("view_mode")
+public class ViewMode implements Serializable {
+  private static final long serialVersionUID = 1L;
+
+  @Null
+  @TableId(type = IdType.AUTO)
+  private Integer id;
+
+  @NotBlank
+  @Pattern(regexp = "^[^ ]+$", message = "The account name cannot contain spaces")
+  private String name;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java b/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java
new file mode 100644
index 0000000..2be1e09
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java
@@ -0,0 +1,18 @@
+package org.apache.iotdb.admin.model.metricsDo;
+
+import org.apache.iotdb.admin.model.vo.QueryDataVO;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-上午 9:28
+ */
+@Data
+public class QueryDataDo {
+  private List<QueryDataVO> QueryDataVOs;
+  private Long latestTimeStamp;
+  private Integer count;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java
index 2763728..60f9a60 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java
@@ -47,6 +47,16 @@ public class DataModelVO implements Serializable {
 
   private List<DataModelVO> children;
 
+  private Integer showNum;
+
+  private Integer pageNum;
+
+  private Integer pageSize;
+
+  private Integer total;
+
+  private Integer totalSonNodeCount;
+
   public DataModelVO(String name) {
     this.name = name;
     this.isGroup = false;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java
new file mode 100644
index 0000000..62e3cb2
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java
@@ -0,0 +1,16 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GroupInfo implements Serializable {
+  private String groupName;
+  private Integer deviceCount;
+  private String description;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
index 512deb7..87f4823 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
@@ -24,12 +24,12 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
+import java.util.List;
 
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 public class GroupInfoVO implements Serializable {
-  private String groupName;
-  private Integer deviceCount;
-  private String description;
+  private Integer groupCount;
+  private List<GroupInfo> groupInfoList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java
new file mode 100644
index 0000000..3661555
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java
@@ -0,0 +1,14 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 5:26
+ */
+@Data
+public class JVMMetricsListDataVO extends MetricsListDataVO implements Serializable {
+  private String metricType;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java
new file mode 100644
index 0000000..851c833
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java
@@ -0,0 +1,15 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-上午 10:00
+ */
+@Data
+public class MetircsQueryClassificationVO {
+  private Integer serverId;
+  private List<QueryClassificationVO> classificationList;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java
new file mode 100644
index 0000000..9bfa81f
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java
@@ -0,0 +1,23 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-上午 10:15
+ */
+@Data
+public class MetricsChartDataVO implements Serializable {
+  private List<String> timeList;
+  private List<String> metricnameList;
+  private List<String> unitList;
+  private HashMap<String, List<String>> dataList;
+}
+
+// List<String> timeList;
+// List<String> metricnameList;
+// HashMap<String, List<Integer> dataList;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java
new file mode 100644
index 0000000..8045fdb
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java
@@ -0,0 +1,15 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-上午 9:12
+ */
+@Data
+public class MetricsConnectionVO implements Serializable {
+  Integer id;
+  String name;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java
new file mode 100644
index 0000000..82f6337
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java
@@ -0,0 +1,20 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-上午 9:38
+ */
+@Data
+public class MetricsDataCountVO {
+  private Integer serverId;
+  private Boolean status;
+  private String url;
+  private Integer port;
+  private Integer storageGroupCount;
+  private Integer deviceCount;
+  private Integer monitorCount;
+  private Integer dataCount;
+  private String version;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java
new file mode 100644
index 0000000..08135e3
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java
@@ -0,0 +1,16 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-上午 10:12
+ */
+@Data
+public class MetricsDataForDiagramVO implements Serializable {
+  private Integer serverId;
+  private Integer metricId;
+  private MetricsChartDataVO chartData;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java
new file mode 100644
index 0000000..269cde1
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java
@@ -0,0 +1,16 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 8:12
+ */
+@Data
+public class MetricsDataForListVO {
+  private Integer serverId;
+  private Integer metricsType;
+  private List<MetricsListDataVO> listInfo;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java
new file mode 100644
index 0000000..7bde7ca
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java
@@ -0,0 +1,17 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 5:24
+ */
+@Data
+public class MetricsListDataVO implements Serializable {
+  private String name;
+  private String latestScratchTime;
+  private String latestResult;
+  private Integer detailAvailable;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java
new file mode 100644
index 0000000..17993c0
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java
@@ -0,0 +1,14 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-上午 10:02
+ */
+@Data
+public class QueryClassificationVO {
+  private Integer id;
+  private String name;
+  private Integer flag;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java
new file mode 100644
index 0000000..b14e3c4
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java
@@ -0,0 +1,15 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-下午 3:56
+ */
+@Data
+public class QueryData1VO extends QueryDataVO implements Serializable {
+  private Integer precompiledTime;
+  private Integer optimizedTime;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java
new file mode 100644
index 0000000..b200a0d
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java
@@ -0,0 +1,16 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 9:22
+ */
+@Data
+public class QueryDataForListVO {
+  private Integer serverId;
+  private Integer mode;
+  private List<QueryMetricsVO> queryMetricsVOs;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java
new file mode 100644
index 0000000..5aecf44
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java
@@ -0,0 +1,21 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-28-下午 10:02
+ */
+@Data
+public class QueryDataStrVO implements Serializable {
+  private Integer id;
+  private String statement;
+  private String runningTime;
+  private Boolean isSlowQuery;
+  private Integer totalTime;
+  private Integer analysisTime;
+  private Integer executionTime;
+  private Integer executionResult;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java
new file mode 100644
index 0000000..a14537a
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java
@@ -0,0 +1,15 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-29-下午 2:10
+ */
+@Data
+public class QueryDataStrVO1 extends QueryDataStrVO implements Serializable {
+  private Integer precompiledTime;
+  private Integer optimizedTime;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java
new file mode 100644
index 0000000..081be81
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java
@@ -0,0 +1,21 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-下午 8:36
+ */
+@Data
+public class QueryDataVO implements Serializable {
+  private Integer id;
+  private String statement;
+  private Long runningTime;
+  private Boolean isSlowQuery;
+  private Integer totalTime;
+  private Integer analysisTime;
+  private Integer executionTime;
+  private Integer executionResult;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java
new file mode 100644
index 0000000..e2b3529
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java
@@ -0,0 +1,19 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-25-下午 5:13
+ */
+@Data
+public class QueryInfoVO {
+  private Integer queryClassificationId;
+  private String latestRunningTime;
+  private Integer totalCount;
+  private Integer totalPage;
+  private Integer serverId;
+  private List<QueryDataStrVO> filteredQueryDataStrVOSList;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java
new file mode 100644
index 0000000..cdf3e12
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java
@@ -0,0 +1,14 @@
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 9:20
+ */
+@Data
+public class QueryMetricsVO {
+  private String SQLStatement;
+  private String runningTime;
+  private Integer executionTime;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
index 0b050d7..2a97117 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
@@ -62,6 +62,9 @@ public interface IotDBService {
 
   void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException;
 
+  DataModelVO getDataModelDetail(
+          Connection connection, String path, Integer pageSize, Integer pageNum) throws BaseException;
+
   UserRolesVO getRolesOfUser(Connection connection, String userName) throws BaseException;
 
   void userGrant(Connection connection, String userName, UserGrantDTO userGrantDTO)
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java
new file mode 100644
index 0000000..1180f23
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java
@@ -0,0 +1,23 @@
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.MetricsListDataVO;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 4:07
+ */
+public interface MetricsResultService {
+  List<MetricsListDataVO> getJVMMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getCPUMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getMemMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getDiskMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getWriteMetricsDataList(Connection connection) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java
new file mode 100644
index 0000000..50f8663
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java
@@ -0,0 +1,41 @@
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.*;
+
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 4:07
+ */
+public interface MetricsService {
+  List<MetricsListDataVO> getJVMMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getCPUMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getMemMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getDiskMetricsDataList(Connection connection) throws BaseException;
+
+  List<MetricsListDataVO> getWriteMetricsDataList(Connection connection) throws BaseException;
+
+  MetircsQueryClassificationVO getMetircsQueryClassification(Integer serverId);
+
+  QueryInfoVO getQueryInfo(
+      Integer serverId,
+      Integer queryClassificationId,
+      Integer pageSize,
+      Integer pageNum,
+      String filterString,
+      String startTimeStr,
+      String endTimeStr,
+      Integer executionResult)
+      throws BaseException;
+
+  MetricsDataCountVO getMetricsDataCount(Integer serverId) throws BaseException;
+
+  MetricsDataForListVO getMetricsDataForList(Integer serverId, Integer metricsType)
+      throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
index e904462..4318825 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
@@ -765,6 +765,66 @@ public class IotDBServiceImpl implements IotDBService {
     }
   }
 
+  @Override
+  public DataModelVO getDataModelDetail(
+          Connection connection, String path, Integer pageSize, Integer pageNum) throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      DataModelVO root = new DataModelVO(path);
+      setNodeInfo(root, sessionPool, path);
+      List<DataModelVO> childrenDataModel = null;
+      DataModelDetailDTO childrenDataModelDetail =
+              getChildrenDataModelDetail(root, path, sessionPool, pageSize, pageNum);
+      childrenDataModel =
+              childrenDataModelDetail == null ? null : childrenDataModelDetail.getDataModelVOList();
+      if (childrenDataModelDetail != null) {
+        root.setPageNum(childrenDataModelDetail.getPageNum());
+        root.setPageSize(childrenDataModelDetail.getPageSize());
+        root.setTotal(childrenDataModelDetail.getTotal());
+      }
+      root.setChildren(childrenDataModel);
+      root.setTotalSonNodeCount(
+              getChildrenNode(path, sessionPool) == null
+                      ? 0
+                      : getChildrenNode(path, sessionPool).size());
+      root.setGroupCount(path.equals("root") ? getGroupCount(sessionPool) : null);
+      root.setPath(path);
+      return root;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private DataModelDetailDTO getChildrenDataModelDetail(
+          DataModelVO root, String path, SessionPool sessionPool, Integer pageSize, Integer pageNum)
+          throws BaseException {
+    Set<String> childrenNode = getChildrenNode(path, sessionPool);
+    if (childrenNode == null) {
+      return null;
+    }
+    List<DataModelVO> childrenlist = new ArrayList<>();
+    List<String> childrenNodeList = new ArrayList<>(childrenNode);
+    List<String> childrenNodeSubList = new ArrayList<>();
+    int size = childrenNode.size();
+    int pageStart = pageNum == 1 ? 0 : (pageNum - 1) * pageSize;
+    int pageEnd = size < pageNum * pageSize ? size : pageNum * pageSize;
+    if (size > pageStart) {
+      childrenNodeSubList = childrenNodeList.subList(pageStart, pageEnd);
+    }
+    for (String child : childrenNodeSubList) {
+      DataModelVO childNode = new DataModelVO(child);
+      setNodeInfo(childNode, sessionPool, path + "." + child);
+      childrenlist.add(childNode);
+    }
+    DataModelDetailDTO dataModelDetailDTO = new DataModelDetailDTO();
+    dataModelDetailDTO.setDataModelVOList(childrenlist);
+    dataModelDetailDTO.setPageNum(pageNum);
+    dataModelDetailDTO.setPageSize(pageSize);
+    dataModelDetailDTO.setTotal(size);
+    return dataModelDetailDTO;
+  }
+
   @Override
   public UserRolesVO getRolesOfUser(Connection connection, String userName) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java
new file mode 100644
index 0000000..de26ba5
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java
@@ -0,0 +1,283 @@
+package org.apache.iotdb.admin.service.impl;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.JVMMetricsListDataVO;
+import org.apache.iotdb.admin.model.vo.MetricsListDataVO;
+import org.apache.iotdb.admin.service.MetricsResultService;
+
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 4:41
+ */
+@Service
+public class MetricsResultServiceImpl implements MetricsResultService {
+
+  public JVMMetricsListDataVO getCurrentThreadsCount(long currentTimeMillis) throws BaseException {
+    String name = "JVM当前线程数";
+    String metricType = "线程";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 1;
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:8086\".\"jvm.threads.daemon\","
+            + " root._metric.\"127.0.0.1:8086\".\"jvm.threads.live\" "
+            + "order by time desc limit 1";
+    try {
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    String latestResult = "[Just Test] 前台:20个,后台:39个,线程总数:59个";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getYGCHappendCountAndCostTime(long currentTimeMillis)
+      throws BaseException {
+    // TODO 暂时写死
+    String name = "YGC发生次数及总耗时";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 2;
+    String latestResult = "[Just Test] 20次 200s";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getUsedBufferSize(long currentTimeMillis) throws BaseException {
+    String name = "已经使用的缓冲区大小";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 3;
+    String latestResult = "[Just Test] 20G";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMTotalUnloadClass(long currentTimeMillis) throws BaseException {
+    String name = "JVM累计卸载的class数量";
+    String metricType = "Classes";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 4;
+    String latestResult = "[Just Test] 30次";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public MetricsListDataVO getCPUUsed(long currentTimeMillis) throws BaseException {
+    String name = "CPU使用率";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 1;
+    String latestResult = "[Just Test] 50%";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getCPUCores(long currentTimeMillis) throws BaseException {
+    String name = "CPU核数";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 0;
+    String latestResult = "[Just Test] 4核";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getIotDBProcessMemUsed(long currentTimeMillis) throws BaseException {
+    String name = "IoTDB进程内存占用比例";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 1;
+    String latestResult = "[Just Test] 70%";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getTotalMem(long currentTimeMillis) throws BaseException {
+    String name = "物理内存大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 0;
+    String latestResult = "[Just Test] 4G";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getDiskAvaliable(long currentTimeMillis) throws BaseException {
+    String name = "磁盘剩余";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 1;
+    String latestResult = "[Just Test] 2G";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getDiskTotalSize(long currentTimeMillis) throws BaseException {
+    String name = "磁盘总大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 0;
+    String latestResult = "[Just Test] 4G";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO writeSucceedProportion(long currentTimeMillis) throws BaseException {
+    String name = "写入成功率";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 0;
+    String latestResult = "[Just Test] 80%";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO writeLatency(long currentTimeMillis) throws BaseException {
+    String name = "写入延迟(最近一分钟)";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    String latestScratchTime = simpleDateFormat.format(currentTimeMillis);
+    Integer detailAvailable = 1;
+    String latestResult = "[Just Test] 90%";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getJVMMetricsDataList(Connection connection) throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    long currentTimeMillis = System.currentTimeMillis();
+    JVMMetricsListDataVO currentThreadsCount = getCurrentThreadsCount(currentTimeMillis);
+    JVMMetricsListDataVO ygcHappendCountAndCostTime =
+        getYGCHappendCountAndCostTime(currentTimeMillis);
+    JVMMetricsListDataVO usedBufferSize = getUsedBufferSize(currentTimeMillis);
+    JVMMetricsListDataVO jvmTotalUnloadClass = getJVMTotalUnloadClass(currentTimeMillis);
+    // TODO 把所有指标都加进来
+    list.add(currentThreadsCount);
+    list.add(ygcHappendCountAndCostTime);
+    list.add(usedBufferSize);
+    list.add(jvmTotalUnloadClass);
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getCPUMetricsDataList(Connection connection) throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    long currentTimeMillis = System.currentTimeMillis();
+    MetricsListDataVO cpuUsed = getCPUUsed(currentTimeMillis);
+    MetricsListDataVO cpuCores = getCPUCores(currentTimeMillis);
+    list.add(cpuUsed);
+    list.add(cpuCores);
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getMemMetricsDataList(Connection connection) throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    long currentTimeMillis = System.currentTimeMillis();
+    MetricsListDataVO iotDBProcessMemUsed = getIotDBProcessMemUsed(currentTimeMillis);
+    MetricsListDataVO totalMem = getTotalMem(currentTimeMillis);
+    list.add(iotDBProcessMemUsed);
+    list.add(totalMem);
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getDiskMetricsDataList(Connection connection)
+      throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    long currentTimeMillis = System.currentTimeMillis();
+    MetricsListDataVO metricsListDataVO = getDiskAvaliable(currentTimeMillis);
+    MetricsListDataVO diskTotalSize = getDiskTotalSize(currentTimeMillis);
+    list.add(metricsListDataVO);
+    list.add(diskTotalSize);
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getWriteMetricsDataList(Connection connection)
+      throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    long currentTimeMillis = System.currentTimeMillis();
+    MetricsListDataVO writeSucceedProportion = writeSucceedProportion(currentTimeMillis);
+    MetricsListDataVO writeLatency = writeLatency(currentTimeMillis);
+    list.add(writeSucceedProportion);
+    list.add(writeLatency);
+    return list;
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java
new file mode 100644
index 0000000..5dd025d
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java
@@ -0,0 +1,1746 @@
+package org.apache.iotdb.admin.service.impl;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.model.dto.QueryInfoDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.*;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.apache.iotdb.admin.service.IotDBService;
+import org.apache.iotdb.admin.service.MetricsService;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.StatementExecutionException;
+import org.apache.iotdb.session.pool.SessionDataSetWrapper;
+import org.apache.iotdb.session.pool.SessionPool;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Erickin
+ * @create 2022-04-26-下午 4:41
+ */
+@Service
+public class MetricsServiceImpl implements MetricsService {
+
+  @Autowired ConnectionService connectionService;
+  @Autowired IotDBService iotDBService;
+
+  private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
+
+  public JVMMetricsListDataVO getCurrentThreadsCount(Connection connection) throws BaseException {
+    String name = "JVM当前线程数";
+    String metricType = "线程";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 1;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.daemon\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.live\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(2);
+    String s2 = values.get(1);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    s2 = s2.substring(0, s2.indexOf('.'));
+    int totalThreadCount = Integer.parseInt(s1);
+    int demoThreadCount = Integer.parseInt(s2);
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult =
+        "前台:"
+            + (totalThreadCount - demoThreadCount)
+            + "个,后台:"
+            + demoThreadCount
+            + "个,线程总数:"
+            + totalThreadCount
+            + "个";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getCurrentDaemonThreadsCount(Connection connection)
+      throws BaseException {
+    String name = "当前daemon线程数";
+    String metricType = "线程";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.daemon\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    int daemonThreadCount = Integer.parseInt(s1);
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = daemonThreadCount + "个";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getPeakThreadsCount(Connection connection) throws BaseException {
+    String name = "峰值线程数";
+    String metricType = "线程";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.peak\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    int daemonThreadCount = Integer.parseInt(s1);
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = daemonThreadCount + "个";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getVariableThreadsCount(Connection connection) throws BaseException {
+    String name = "处于各种状态的线程数";
+    String metricType = "线程";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=new\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=waiting\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=runnable\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=blocked\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=timed-waiting\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=terminated\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    String s2 = values.get(2);
+    String s3 = values.get(3);
+    String s4 = values.get(4);
+    String s5 = values.get(5);
+    String s6 = values.get(6);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    s2 = s2.substring(0, s2.indexOf('.'));
+    s3 = s3.substring(0, s3.indexOf('.'));
+    s4 = s4.substring(0, s4.indexOf('.'));
+    s5 = s5.substring(0, s5.indexOf('.'));
+    s6 = s6.substring(0, s6.indexOf('.'));
+    int newThreadCount = Integer.parseInt(s1);
+    int waitingThreadCount = Integer.parseInt(s2);
+    int runnableThreadCount = Integer.parseInt(s3);
+    int blockedThreadCount = Integer.parseInt(s4);
+    int timedWaitingThreadCount = Integer.parseInt(s5);
+    int terminatedThreadCount = Integer.parseInt(s6);
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult =
+        "新建("
+            + newThreadCount
+            + ")、"
+            + "可运行("
+            + waitingThreadCount
+            + ")、"
+            + "运行("
+            + runnableThreadCount
+            + ")、"
+            + "阻塞("
+            + blockedThreadCount
+            + ")、"
+            + "休眠("
+            + timedWaitingThreadCount
+            + ")、"
+            + "死亡("
+            + terminatedThreadCount
+            + ")";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getYGCHappendCountAndCostTime(Connection connection)
+      throws BaseException {
+    String name = "YGC发生次数及总耗时";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    SessionPool sessionPool = getSessionPool(connection);
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String countSQL =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_count\".\"action=end of minor GC\".\"cause=Allocation Failure\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_count\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\" "
+            + "order by time desc limit 1";
+    String timeSQL =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Allocation Failure\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\" "
+            + "order by time desc limit 1";
+    List<String> countValues = executeQueryOneLine(sessionPool, countSQL);
+    List<String> timeValues = executeQueryOneLine(sessionPool, timeSQL);
+    long lastestTimeStamp = Long.parseLong(countValues.get(0));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    Integer detailAvailable = 2;
+    String s1 = countValues.get(1);
+    String s2 = countValues.get(2);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    s2 = s2.substring(0, s2.indexOf('.'));
+    int count = Integer.parseInt(s1) + Integer.parseInt(s2);
+    double time =
+        (Double.parseDouble(timeValues.get(1)) + Double.parseDouble(timeValues.get(2))) / 1000;
+    String latestResult = count + "次 " + time + "s";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getYGCMaxCostTimeAndReason(Connection connection)
+      throws BaseException {
+    String name = "YGC最大耗时及原因";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    SessionPool sessionPool = getSessionPool(connection);
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String timeSQL =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_max\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_max\".\"action=end of minor GC\".\"cause=Allocation Failure\" "
+            + "order by time desc limit 1";
+    List<String> timeValues = executeQueryOneLine(sessionPool, timeSQL);
+    long lastestTimeStamp = Long.parseLong(timeValues.get(0));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    Integer detailAvailable = 2;
+    String latestResult =
+        Double.parseDouble(timeValues.get(1)) / 1000
+            + "s(Metadata GC Threshold)、"
+            + Double.parseDouble(timeValues.get(2)) / 1000
+            + "s(Allocation Failure)";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getFGCHappendCountAndCostTime(Connection connection)
+      throws BaseException {
+    String name = "FGC发生次数及总耗时";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    SessionPool sessionPool = getSessionPool(connection);
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String countSQL =
+        "select * from "
+            +
+            //            "root._metric.\"127.0.0.1:8086\".\"jvm.gc.pause_count\".\"action=end of
+            // major GC\".\"cause=Allocation Failure\", " +
+            "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_count\".\"action=end of major GC\".\"cause=Metadata GC Threshold\" "
+            +
+            //            "root._metric.\"127.0.0.1:8086\".\"jvm.gc.pause_count\".\"action=end of
+            // major GC\".\"cause=Ergonomics\" " +
+            "order by time desc limit 1";
+    String timeSQL =
+        "select * from "
+            +
+            //            "root._metric.\"127.0.0.1:8086\".\"jvm.gc.pause_total\".\"action=end of
+            // major GC\".\"cause=Allocation Failure\", " +
+            "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of major GC\".\"cause=Metadata GC Threshold\" "
+            +
+            //            "root._metric.\"127.0.0.1:8086\".\"jvm.gc.pause_total\".\"action=end of
+            // major GC\".\"cause=Ergonomics\" " +
+            "order by time desc limit 1";
+    List<String> countValues = executeQueryOneLine(sessionPool, countSQL);
+    List<String> timeValues = executeQueryOneLine(sessionPool, timeSQL);
+    long lastestTimeStamp = Long.parseLong(countValues.get(0));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    Integer detailAvailable = 2;
+    // TODO: IOTDB BUG 等待修复
+    String s1 = countValues.get(1).equals("null") ? "0.0" : countValues.get(1);
+    //    String s2 = countValues.get(2).equals("null") ? "0.0" : countValues.get(2);
+    //    String s3 = countValues.get(3).equals("null") ? "0.0" : countValues.get(3);
+
+    s1 = s1.substring(0, s1.indexOf('.'));
+    //    s2 = s2.substring(0, s2.indexOf('.'));
+    //    s3 = s3.substring(0, s3.indexOf('.'));
+    //    int count = Integer.parseInt(s1) + Integer.parseInt(s2) + Integer.parseInt(s3);
+    int count = Integer.parseInt(s1);
+    // TODO: IOTDB BUG 等待修复
+    double d1 = timeValues.get(1).equals("null") ? 0.0 : Double.parseDouble(timeValues.get(1));
+    //    double d2 = timeValues.get(2).equals("null")? 0.0 : Double.parseDouble(timeValues.get(2));
+    //    double d3 = timeValues.get(3).equals("null")? 0.0 : Double.parseDouble(timeValues.get(3));
+    //    double time = d1 + d2 + d3;
+    double time = (d1) / 1000;
+    String latestResult = count + "次 " + time + "s";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getFGCMaxCostTimeAndReason(Connection connection)
+      throws BaseException {
+    String name = "FGC最大耗时及原因";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    SessionPool sessionPool = getSessionPool(connection);
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String timeSQL =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_max\".\"action=end of major GC\".\"cause=Metadata GC Threshold\" "
+            +
+            //            "root._metric.\"127.0.0.1:8086\".\"jvm.gc.pause_max\".\"action=end of
+            // major GC\".\"cause=Allocation Failure\", " +
+            //            "root._metric.\"127.0.0.1:8086\".\"jvm.gc.pause_max\".\"action=end of
+            // major GC\".\"cause=Ergonomics\" " +
+            "order by time desc limit 1";
+    List<String> timeValues = executeQueryOneLine(sessionPool, timeSQL);
+    long lastestTimeStamp = Long.parseLong(timeValues.get(0));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    Integer detailAvailable = 2;
+    // TODO: IOTDB BUG 等待修复
+    String s1 = timeValues.get(1).equals("null") ? "0.0" : timeValues.get(1);
+    //    String s2 = timeValues.get(2).equals("null")? "0.0" : timeValues.get(2);
+    //    String s3 = timeValues.get(3).equals("null")? "0.0" : timeValues.get(3);
+    //    String latestResult = timeValues.get(1)+"s(Metadata GC
+    // Threshold)、"+timeValues.get(2)+"s(Allocation Failure)、"+timeValues.get(3)+"s(Ergonomics)";
+    String latestResult = Double.parseDouble(timeValues.get(1)) / 1000 + "s(Metadata GC Threshold)";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getGCCPUoverhead(Connection connection) throws BaseException {
+    String name = "GC消耗CPU的比例";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.overhead\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    double percent = Double.parseDouble(values.get(1));
+    BigDecimal b = new BigDecimal(percent);
+    double percent1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = percent1 + "%";
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getGCPromoted(Connection connection) throws BaseException {
+    String name = "从GC之前到GC之后老年代内存池大小正增长的累计";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.memory.promoted\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = getNetFileSizeDescription((long) (Double.parseDouble(values.get(1))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getMajorMemoryMaxValueEver(Connection connection)
+      throws BaseException {
+    String name = "老年代内存的历史最大值";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.max.data.size\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = getNetFileSizeDescription((long) (Double.parseDouble(values.get(1))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getMajorMemorySizeAfterGC(Connection connection)
+      throws BaseException {
+    String name = "GC之后老年代内存的大小";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.live.data.size\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = getNetFileSizeDescription((long) (Double.parseDouble(values.get(1))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getMinorMemorySizeAddedBetweentwoGC(Connection connection)
+      throws BaseException {
+    String name = "在一个GC之后到下一个GC之前年轻代增加的内存";
+    String metricType = "垃圾回收";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.memory.allocated\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = getNetFileSizeDescription((long) (Double.parseDouble(values.get(1))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getBufferUsed(Connection connection) throws BaseException {
+    String name = "已经使用的缓冲区大小";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=mapped\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=direct\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count =
+        getNetFileSizeDescription(
+            (long) (Double.parseDouble(values.get(1)) + Double.parseDouble(values.get(2))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getMaxBuffer(Connection connection) throws BaseException {
+    String name = "最大缓冲区大小";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.total.capacity\".\"id=mapped\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.total.capacity\".\"id=direct\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count =
+        getNetFileSizeDescription(
+            (long) (Double.parseDouble(values.get(1)) + Double.parseDouble(values.get(2))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getBufferCount(Connection connection) throws BaseException {
+    String name = "当前缓冲区数量";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.count\".\"id=mapped\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.count\".\"id=direct\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    String s2 = values.get(2);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    s2 = s2.substring(0, s2.indexOf('.'));
+    String latestResult = (Integer.parseInt(s1) + Integer.parseInt(s2)) + "个";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMCommittedMemorySize(Connection connection)
+      throws BaseException {
+    String name = "当前向JVM申请的内存大小";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.committed\".\"area=nonheap\".\"id=Compressed Class Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.committed\".\"area=nonheap\".\"id=Code Cache\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.committed\".\"area=nonheap\".\"id=Metaspace\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.committed\".\"area=heap\".\"id=PS Old Gen\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.committed\".\"area=heap\".\"id=PS Eden Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.committed\".\"area=heap\".\"id=PS Survivor Space\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count =
+        getNetFileSizeDescription(
+            (long)
+                (Double.parseDouble(values.get(1))
+                    + Double.parseDouble(values.get(2))
+                    + Double.parseDouble(values.get(3))
+                    + Double.parseDouble(values.get(4))
+                    + Double.parseDouble(values.get(5))
+                    + Double.parseDouble(values.get(6))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMMemoryMaxSize(Connection connection) throws BaseException {
+    String name = "JVM最大内存";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=nonheap\".\"id=Compressed Class Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=nonheap\".\"id=Code Cache\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=nonheap\".\"id=Metaspace\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=heap\".\"id=PS Old Gen\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=heap\".\"id=PS Eden Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=heap\".\"id=PS Survivor Space\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count =
+        getNetFileSizeDescription(
+            (long)
+                (Double.parseDouble(values.get(1))
+                    + Double.parseDouble(values.get(2))
+                    + Double.parseDouble(values.get(3))
+                    + Double.parseDouble(values.get(4))
+                    + Double.parseDouble(values.get(5))
+                    + Double.parseDouble(values.get(6))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMMemoryUsedSize(Connection connection) throws BaseException {
+    String name = "JVM已使用内存大小";
+    String metricType = "内存";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=nonheap\".\"id=Compressed Class Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=nonheap\".\"id=Code Cache\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=nonheap\".\"id=Metaspace\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=heap\".\"id=PS Old Gen\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=heap\".\"id=PS Eden Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=heap\".\"id=PS Survivor Space\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count =
+        getNetFileSizeDescription(
+            (long)
+                (Double.parseDouble(values.get(1))
+                    + Double.parseDouble(values.get(2))
+                    + Double.parseDouble(values.get(3))
+                    + Double.parseDouble(values.get(4))
+                    + Double.parseDouble(values.get(5))
+                    + Double.parseDouble(values.get(6))));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = count;
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMUnloadedClassesTotal(Connection connection)
+      throws BaseException {
+    String name = "JVM累计卸载的Class数量";
+    String metricType = "Classes";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.classes.unloaded\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    String latestResult = Integer.parseInt(s1) + "个";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMloadedClassesTotal(Connection connection) throws BaseException {
+    String name = "JVM累计加载的Class数量";
+    String metricType = "Classes";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.classes.loaded\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    String latestResult = Integer.parseInt(s1) + "个";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public JVMMetricsListDataVO getJVMCompilationTime(Connection connection) throws BaseException {
+    String name = "JVM耗费在编译上的时间";
+    String metricType = "Classes";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.compilation.time\".\"compiler=HotSpot 64-Bit Tiered Compilers\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = values.get(1) + "s";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    JVMMetricsListDataVO jvmMetricsListDataVO = new JVMMetricsListDataVO();
+    jvmMetricsListDataVO.setMetricType(metricType);
+    jvmMetricsListDataVO.setDetailAvailable(detailAvailable);
+    jvmMetricsListDataVO.setLatestResult(latestResult);
+    jvmMetricsListDataVO.setLatestScratchTime(latestScratchTime);
+    jvmMetricsListDataVO.setName(name);
+    return jvmMetricsListDataVO;
+  }
+
+  public MetricsListDataVO getCPUUsed(Connection connection) throws BaseException {
+    String name = "CPU使用率";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_cpu_load\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = values.get(1) + "%";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getCPUCores(Connection connection) throws BaseException {
+    String name = "CPU核数";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_cpu_cores\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String s1 = values.get(1);
+    s1 = s1.substring(0, s1.indexOf('.'));
+    String latestResult = s1 + "核";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getCPUTime(Connection connection) throws BaseException {
+    String name = "CPU Time";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"process_cpu_time\".\"name=process\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String timeStr = values.get(1);
+    long count = Long.parseLong(timeStr.substring(timeStr.indexOf("E") + 1));
+    double time = Double.parseDouble(timeStr.substring(0, timeStr.indexOf("E")));
+    while (count > 0) {
+      time *= 10;
+      count--;
+    }
+    String latestResult = (float) (time / 1000000000) + "s";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getTotalMem(Connection connection) throws BaseException {
+    String name = "物理内存大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    String str = connection.getHost();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_total_physical_memory_size\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = getNetFileSizeDescription((long) Double.parseDouble(values.get(1)));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getProcessRatio(Connection connection) throws BaseException {
+    String name = "IoTDB进程内存占用比例";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"process_mem_ratio\".\"name=process\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    String latestResult = values.get(1) + "%";
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getDiskTotalSize(Connection connection) throws BaseException {
+    String name = "磁盘总大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_disk_total_space\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = getNetFileSizeDescription((long) Double.parseDouble(values.get(1)));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getDiskLoadSize(Connection connection) throws BaseException {
+    // TODO: 假数据,等待iotdb增加该指标
+    String name = "磁盘挂载";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_disk_total_space\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    //    String latestResult = getNetFileSizeDescription((long)Double.parseDouble(values.get(1)));
+    String latestResult = "【假数据:指标暂缺】2G";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getDiskAvailableSize(Connection connection) throws BaseException {
+    String name = "磁盘剩余";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_disk_free_space\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String latestResult = getNetFileSizeDescription((long) Double.parseDouble(values.get(1)));
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getDiskIO(Connection connection) throws BaseException {
+    String name = "磁盘IO吞吐";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"sys_disk_free_space\".\"name=system\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    //    String latestResult = getNetFileSizeDescription((long)Double.parseDouble(values.get(1)));
+    String latestResult = "【假数据:指标暂缺】136K/s";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getWalFileCountAndSize(Connection connection) throws BaseException {
+    String name = "wal日志文件数量及大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=wal\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=wal\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "数量:" + count + ";" + "大小:" + size;
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getSeqTSFileCountAndSize(Connection connection) throws BaseException {
+    String name = "顺序TsFile文件数量及大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=seq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=seq\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "数量:" + count + ";" + "大小:" + size;
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getUnSeqTSFileCountAndSize(Connection connection) throws BaseException {
+    String name = "乱序TsFile文件数量及大小";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=unseq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=unseq\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "数量:" + count + ";" + "大小:" + size;
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getWriteDelay(Connection connection) throws BaseException {
+    String name = "写入延迟(最近一分钟)";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=unseq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=unseq\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "【假数据:指标暂缺】" + "90" + "%";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getWriteSucceedCount(Connection connection) throws BaseException {
+    String name = "查询成功次数(最近1分钟)";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=unseq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=unseq\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "【假数据:指标暂缺】" + "100" + "次";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getWriteFailedCount(Connection connection) throws BaseException {
+    String name = "查询失败次数(最近1分钟)";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=unseq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=unseq\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "【假数据:指标暂缺】" + "20" + "次";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  public MetricsListDataVO getWriteSucceedRatio(Connection connection) throws BaseException {
+    String name = "查询成功率";
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Integer detailAvailable = 0;
+    int port = connection.getPort();
+    // TODO bug 修复后删除
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=unseq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=unseq\" "
+            + "order by time desc limit 1";
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> values = executeQueryOneLine(sessionPool, sql);
+    long lastestTimeStamp = Long.parseLong(values.get(0));
+    String count = values.get(1);
+    count = count.substring(0, count.indexOf('.'));
+    String size = getNetFileSizeDescription((long) Double.parseDouble(values.get(2)));
+    String latestResult = "【假数据:指标暂缺】" + "80" + "%";
+    String latestScratchTime = simpleDateFormat.format(lastestTimeStamp);
+    MetricsListDataVO metricsListDataVO = new MetricsListDataVO();
+    metricsListDataVO.setDetailAvailable(detailAvailable);
+    metricsListDataVO.setLatestResult(latestResult);
+    metricsListDataVO.setLatestScratchTime(latestScratchTime);
+    metricsListDataVO.setName(name);
+    return metricsListDataVO;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getJVMMetricsDataList(Connection connection) throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    list.add(getCurrentThreadsCount(connection));
+    list.add(getCurrentDaemonThreadsCount(connection));
+    list.add(getPeakThreadsCount(connection));
+    list.add(getVariableThreadsCount(connection));
+    list.add(getYGCHappendCountAndCostTime(connection));
+    list.add(getYGCMaxCostTimeAndReason(connection));
+    list.add(getFGCHappendCountAndCostTime(connection));
+    list.add(getFGCMaxCostTimeAndReason(connection));
+    list.add(getGCCPUoverhead(connection));
+    list.add(getGCPromoted(connection));
+    list.add(getMajorMemoryMaxValueEver(connection));
+    list.add(getMajorMemorySizeAfterGC(connection));
+    list.add(getMinorMemorySizeAddedBetweentwoGC(connection));
+    list.add(getBufferUsed(connection));
+    list.add(getMaxBuffer(connection));
+    list.add(getBufferCount(connection));
+    list.add(getJVMCommittedMemorySize(connection));
+    list.add(getJVMMemoryMaxSize(connection));
+    list.add(getJVMMemoryUsedSize(connection));
+    list.add(getJVMUnloadedClassesTotal(connection));
+    list.add(getJVMloadedClassesTotal(connection));
+    list.add(getJVMCompilationTime(connection));
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getCPUMetricsDataList(Connection connection) throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    list.add(getCPUCores(connection));
+    list.add(getCPUUsed(connection));
+    list.add(getCPUTime(connection));
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getMemMetricsDataList(Connection connection) throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    list.add(getTotalMem(connection));
+    list.add(getProcessRatio(connection));
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getDiskMetricsDataList(Connection connection)
+      throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    list.add(getDiskTotalSize(connection));
+    list.add(getDiskLoadSize(connection));
+    list.add(getDiskAvailableSize(connection));
+    list.add(getDiskIO(connection));
+    list.add(getWalFileCountAndSize(connection));
+    list.add(getSeqTSFileCountAndSize(connection));
+    list.add(getUnSeqTSFileCountAndSize(connection));
+    return list;
+  }
+
+  @Override
+  public List<MetricsListDataVO> getWriteMetricsDataList(Connection connection)
+      throws BaseException {
+    List<MetricsListDataVO> list = new ArrayList<>();
+    list.add(getWriteDelay(connection));
+    list.add(getWriteSucceedCount(connection));
+    list.add(getWriteFailedCount(connection));
+    list.add(getWriteFailedCount(connection));
+    list.add(getWriteSucceedRatio(connection));
+    return list;
+  }
+
+  @Override
+  public MetircsQueryClassificationVO getMetircsQueryClassification(Integer serverId) {
+    // TODO:等待清华提供查询分类的接口
+    List<QueryClassificationVO> fakeData = new ArrayList<>();
+    for (int i = 0; i < 6; i++) {
+      QueryClassificationVO queryClassificationVO = new QueryClassificationVO();
+      queryClassificationVO.setId(i + 1);
+      queryClassificationVO.setName("查询分类" + (i + 1));
+      queryClassificationVO.setFlag(i % 2 == 0 ? 1 : 0);
+      fakeData.add(queryClassificationVO);
+    }
+    MetircsQueryClassificationVO metircsQueryClassificationVO = new MetircsQueryClassificationVO();
+    metircsQueryClassificationVO.setServerId(serverId);
+    metircsQueryClassificationVO.setClassificationList(fakeData);
+    return metircsQueryClassificationVO;
+  }
+
+  @Override
+  public QueryInfoVO getQueryInfo(
+      Integer serverId,
+      Integer queryClassificationId,
+      Integer pageSize,
+      Integer pageNum,
+      String filterString,
+      String startTimeStr,
+      String endTimeStr,
+      Integer executionResult)
+      throws BaseException {
+    long startTime = Long.parseLong(startTimeStr);
+    long endTime = Long.parseLong(endTimeStr);
+    Connection connection = connectionService.getById(serverId);
+    QueryInfoDTO queryInfoDTO =
+        iotDBService.getQueryInfoListByQueryClassificationId(
+            connection,
+            queryClassificationId,
+            pageSize,
+            pageNum,
+            filterString,
+            startTime,
+            endTime,
+            executionResult);
+    QueryInfoVO queryInfoVO = new QueryInfoVO();
+    queryInfoVO.setQueryClassificationId(queryClassificationId);
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    Long latestRunningTime = queryInfoDTO.getLatestRunningTime();
+    queryInfoVO.setLatestRunningTime(
+        latestRunningTime == 0 ? null : simpleDateFormat.format(latestRunningTime));
+    BeanUtils.copyProperties(queryInfoDTO, queryInfoVO);
+    queryInfoVO.setServerId(serverId);
+    return queryInfoVO;
+  }
+
+  @Override
+  public MetricsDataCountVO getMetricsDataCount(Integer serverId) throws BaseException {
+    Connection connection = connectionService.getById(serverId);
+    DataCountVO dataCountVO = new DataCountVO();
+    MetricsDataCountVO metricsDataCountVO = new MetricsDataCountVO();
+    DataCountVO dataCount = new DataCountVO();
+    try {
+      dataCount = iotDBService.getDataCount(connection);
+      metricsDataCountVO.setStatus(true);
+    } catch (BaseException e) {
+      metricsDataCountVO.setStatus(false);
+    }
+    metricsDataCountVO.setServerId(serverId);
+    metricsDataCountVO.setUrl(connection.getHost());
+    metricsDataCountVO.setPort(connection.getPort());
+    BeanUtils.copyProperties(dataCount, metricsDataCountVO);
+    metricsDataCountVO.setDataCount(dataCount.getDataCount());
+    return metricsDataCountVO;
+  }
+
+  @Override
+  public MetricsDataForListVO getMetricsDataForList(Integer serverId, Integer metricsType)
+      throws BaseException {
+    Connection connection = connectionService.getById(serverId);
+    List<MetricsListDataVO> metricsDataList = null;
+    // TODO:具体区分和判断等待清华提供方案和策略
+    switch (metricsType) {
+      case 0:
+        metricsDataList = getJVMMetricsDataList(connection);
+        break;
+      case 1:
+        metricsDataList = getCPUMetricsDataList(connection);
+        break;
+      case 2:
+        metricsDataList = getMemMetricsDataList(connection);
+        break;
+      case 3:
+        metricsDataList = getDiskMetricsDataList(connection);
+        break;
+      case 4:
+        metricsDataList = getWriteMetricsDataList(connection);
+        break;
+    }
+    MetricsDataForListVO metricsDataForListVO = new MetricsDataForListVO();
+    metricsDataForListVO.setServerId(serverId);
+    metricsDataForListVO.setMetricsType(metricsType);
+    metricsDataForListVO.setListInfo(metricsDataList);
+    return metricsDataForListVO;
+  }
+
+  public static SessionPool getSessionPool(Connection connection) throws BaseException {
+    String host = connection.getHost();
+    Integer port = connection.getPort();
+    String username = connection.getUsername();
+    String password = connection.getPassword();
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = new SessionPool(host, port, username, password, 3);
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    }
+    return sessionPool;
+  }
+
+  private List<String> executeQueryOneLine(SessionPool sessionPool, String sql)
+      throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      List<String> valueList = new ArrayList<>();
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      if (sessionDataSetWrapper.hasNext()) {
+        RowRecord rowRecord = sessionDataSetWrapper.next();
+        valueList.add(rowRecord.getTimestamp() + "");
+        List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+        for (org.apache.iotdb.tsfile.read.common.Field field : fields) {
+          valueList.add(field.toString());
+        }
+      }
+      return valueList;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+    }
+  }
+
+  private void closeSessionPool(SessionPool sessionPool) {
+    if (sessionPool != null) {
+      sessionPool.close();
+    }
+  }
+
+  private void closeResultSet(SessionDataSetWrapper sessionDataSetWrapper) {
+    if (sessionDataSetWrapper != null) {
+      sessionDataSetWrapper.close();
+    }
+  }
+
+  private static String getNetFileSizeDescription(long size) {
+    StringBuffer bytes = new StringBuffer();
+    DecimalFormat format = new DecimalFormat("###.0");
+    if (size >= 1024 * 1024 * 1024) {
+      double i = (size / (1024.0 * 1024.0 * 1024.0));
+      bytes.append(format.format(i)).append("GB");
+    } else if (size >= 1024 * 1024) {
+      double i = (size / (1024.0 * 1024.0));
+      bytes.append(format.format(i)).append("MB");
+    } else if (size >= 1024) {
+      double i = (size / (1024.0));
+      bytes.append(format.format(i)).append("KB");
+    } else if (size < 1024) {
+      if (size <= 0) {
+        bytes.append("0B");
+      } else {
+        bytes.append((int) size).append("B");
+      }
+    }
+    return bytes.toString();
+  }
+}


[iotdb-web-workbench] 27/34: 新增监控指标展示功能

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit ff960d2e6461a99d1d18c2c735c71bb0941cb01b
Author: loveher147 <lo...@qq.com>
AuthorDate: Thu May 26 14:48:03 2022 +0800

    新增监控指标展示功能
    
    - 该版本适配低于0.13版本的iotdb并提供数据库管理功能,但不提供监控管理(低于0.13版本iotdb不支持监控);
    - 仍然存在部分接口返回后端假数据,等待清华提供接口后替换为真实数据。
---
 backend/pom.xml                                    |    4 +-
 .../iotdb/admin/common/exception/ErrorCode.java    |    4 +
 .../iotdb/admin/controller/FileController.java     |   11 +
 .../iotdb/admin/controller/IotDBController.java    |   15 +-
 .../admin/model/dto/AuthorityPrivilegeDTO.java     |    1 +
 .../apache/iotdb/admin/model/vo/DataCountVO.java   |    5 +-
 .../apache/iotdb/admin/service/IotDBService.java   |   20 +-
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 1841 +++++++++++++++++++-
 backend/src/main/resources/sqlite/iotdb.db         |  Bin 36864 -> 53248 bytes
 9 files changed, 1846 insertions(+), 55 deletions(-)

diff --git a/backend/pom.xml b/backend/pom.xml
index 45d3bea..e3fb378 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -145,7 +145,7 @@
     <dependency>
       <groupId>org.apache.iotdb</groupId>
       <artifactId>iotdb-session</artifactId>
-      <version>0.12.1</version>
+      <version>0.12.5</version>
       <exclusions>
         <exclusion>
           <artifactId>logback-classic</artifactId>
@@ -157,7 +157,7 @@
     <dependency>
       <groupId>org.apache.iotdb</groupId>
       <artifactId>iotdb-jdbc</artifactId>
-      <version>0.12.1</version>
+      <version>0.12.5</version>
       <exclusions>
         <exclusion>
           <artifactId>logback-classic</artifactId>
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
index 2084338..7e04593 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
@@ -158,6 +158,10 @@ public class ErrorCode {
   public static final String SET_GROUP_FAIL = "IOTDB-0022";
   public static final String SET_GROUP_FAIL_MSG = "Failed to create storage group";
 
+  public static final String SET_GROUP_FAIL_EXISTS = "IOTDB-0095";
+  public static final String SET_GROUP_FAIL__EXISTS_MSG =
+      "Failed to create storage group, the storage group already exists";
+
   public static final String DELETE_GROUP_FAIL = "IOTDB-0023";
   public static final String DELETE_GROUP_FAIL_MSG = "Failed to delete storage group";
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java
index ea0106b..33aea37 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java
@@ -115,6 +115,17 @@ public class FileController {
     return getResponseEntity(resource);
   }
 
+  @ApiOperation("Download the query log file")
+  @GetMapping("/downloadQueryLogFile")
+  public ResponseEntity<Resource> downloadQueryLogFile(
+      @RequestParam String SQLStatement, @RequestParam Long timeStamp) throws BaseException {
+    Resource resource = new ClassPathResource("file/[Fake]QueryLog.txt");
+    if (!resource.exists()) {
+      throw new BaseException(ErrorCode.FILE_NOT_FOUND, ErrorCode.FILE_NOT_FOUND_MSG);
+    }
+    return getResponseEntity(resource);
+  }
+
   private ResponseEntity<Resource> getResponseEntity(Resource resource) {
     String contentType = "application/octet-stream";
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
index 612816e..5b4d0d0 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
@@ -85,10 +85,13 @@ public class IotDBController {
   @GetMapping("/dataModel")
   @ApiOperation("Get IoTDB data model")
   public BaseVO<DataModelVO> getDataModel(
-      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+      @PathVariable("serverId") Integer serverId,
+      @RequestParam(value = "path", required = false, defaultValue = "root") String path,
+      HttpServletRequest request)
+      throws BaseException {
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    DataModelVO dataModelVO = iotDBService.getDataModel(connection);
+    DataModelVO dataModelVO = iotDBService.getDataModel(connection, path);
     return BaseVO.success("Get IoTDB data model successfully", dataModelVO);
   }
 
@@ -164,7 +167,6 @@ public class IotDBController {
     checkTtl(ttl, ttlUnit);
     Integer groupId = groupDTO.getGroupId();
     groupDTO.setGroupName(groupName);
-
     List<String> groupNames = iotDBService.getAllStorageGroups(connection);
     if (groupId == null) {
       if (!groupNames.contains(groupDTO.getGroupName())) {
@@ -1121,9 +1123,7 @@ public class IotDBController {
 
   private void checkParameter(String groupName) throws BaseException {
     String checkName = StringUtils.removeStart(groupName, "root").toLowerCase();
-    if (!groupName.matches("^root\\.[^ ]+$")
-        || checkName.contains(".root.")
-        || checkName.matches("^[^ ]*\\.root$")) {
+    if (groupName.contains(".root.") || groupName.contains(".root")) {
       throw new BaseException(ErrorCode.NO_SUP_CONTAIN_ROOT, ErrorCode.NO_SUP_CONTAIN_ROOT_MSG);
     }
     if (checkName.contains(".as.")
@@ -1229,6 +1229,9 @@ public class IotDBController {
   }
 
   private void checkTtl(Long ttl, String unit) throws BaseException {
+    if (ttl == null || unit == null) {
+      return;
+    }
     if (Long.MAX_VALUE / switchTime(unit) < ttl) {
       throw new BaseException(ErrorCode.TTL_OVER, ErrorCode.TTL_OVER_MSG);
     }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java
index 4a7ea78..ed3b8e1 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java
@@ -26,6 +26,7 @@ import java.util.List;
 
 @Data
 public class AuthorityPrivilegeDTO implements Serializable {
+
   private List<String> privileges;
 
   private List<String> cancelPrivileges;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java
index cdef28c..fc2c2e7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java
@@ -25,8 +25,9 @@ import java.io.Serializable;
 
 @Data
 public class DataCountVO implements Serializable {
-  private Integer groupCount;
+  private Integer storageGroupCount;
   private Integer deviceCount;
-  private Integer measurementCount;
+  private Integer monitorCount;
   private Integer dataCount;
+  private String version;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
index 70cd585..0b050d7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
@@ -30,7 +30,7 @@ import java.util.Set;
 public interface IotDBService {
   DataCountVO getDataCount(Connection connection) throws BaseException;
 
-  DataModelVO getDataModel(Connection connection) throws BaseException;
+  DataModelVO getDataModel(Connection connection, String path) throws BaseException;
 
   List<String> getAllStorageGroups(Connection connection) throws BaseException;
 
@@ -162,4 +162,22 @@ public interface IotDBService {
   void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException;
 
   void stopQuery(Integer serverId, Long timestamp) throws BaseException;
+
+  QueryInfoDTO getQueryInfoListByQueryClassificationId(
+      Connection connection,
+      Integer queryClassificationId,
+      Integer pageSize,
+      Integer pageNum,
+      String filterString,
+      Long startTime,
+      Long endTime,
+      Integer executionResult)
+      throws BaseException;
+
+  MetricsDataForDiagramVO getMetricDataByMetricId(Connection connection, Integer metricId)
+      throws BaseException;
+
+  List<QueryMetricsVO> getTopQueryMetricsData();
+
+  List<QueryMetricsVO> getSlowQueryMetricsData();
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
index 803c4f5..e904462 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.model.dto.*;
 import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.metricsDo.QueryDataDo;
 import org.apache.iotdb.admin.model.vo.*;
 import org.apache.iotdb.admin.service.IotDBService;
 import org.apache.iotdb.rpc.IoTDBConnectionException;
@@ -38,9 +39,11 @@ import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
 import java.lang.reflect.Field;
+import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.Date;
@@ -96,22 +99,43 @@ public class IotDBServiceImpl implements IotDBService {
     SessionPool sessionPool = null;
     try {
       sessionPool = getSessionPool(connection);
+      String iotdbVersion = executeQueryOneValue(sessionPool, "show version");
+      logger.info("执行成功,获得iotdb版本号:" + iotdbVersion);
+      int versionFlag = 0;
+      if (iotdbVersion.contains("0.12.")) {
+        versionFlag = 12;
+      } else if (iotdbVersion.contains("0.13.") || iotdbVersion.contains("0.14.")) {
+        versionFlag = 13;
+      }
       String groupCountStr = executeQueryOneValue(sessionPool, "count storage group");
       int groupCount = Integer.parseInt(groupCountStr);
       String deviceCountStr = executeQueryOneValue(sessionPool, "count devices");
       int deviceCount = Integer.parseInt(deviceCountStr);
       String measurementCountStr = executeQueryOneValue(sessionPool, "count timeseries");
       int measurementCount = Integer.parseInt(measurementCountStr);
-      List<String> dataCountList = executeQueryOneLine(sessionPool, "select count(*) from root");
+      List<String> dataCountList = new ArrayList<>();
+      if (versionFlag == 13) {
+        dataCountList = executeQueryOneLine(sessionPool, "select count(*) from root.**");
+      } else if (versionFlag == 12) {
+        try {
+          dataCountList = executeQueryOneLine(sessionPool, "select count(*) from root.*");
+          //          dataCountList = executeQueryOneLine(sessionPool, "select count(*) from
+          // root.*");
+        } catch (BaseException e) {
+          logger.error("发生错误!!!");
+          e.printStackTrace();
+        }
+      }
       int dataCount = 0;
       for (String dataCountStr : dataCountList) {
         dataCount += Integer.parseInt(dataCountStr);
       }
       DataCountVO dataCountVO = new DataCountVO();
-      dataCountVO.setGroupCount(groupCount);
+      dataCountVO.setStorageGroupCount(groupCount);
       dataCountVO.setDeviceCount(deviceCount);
-      dataCountVO.setMeasurementCount(measurementCount);
+      dataCountVO.setMonitorCount(measurementCount);
       dataCountVO.setDataCount(dataCount);
+      dataCountVO.setVersion(iotdbVersion);
       return dataCountVO;
     } catch (NumberFormatException e) {
       throw new BaseException(ErrorCode.GET_DATA_COUNT_FAIL, ErrorCode.GET_DATA_COUNT_FAIL_MSG);
@@ -121,20 +145,39 @@ public class IotDBServiceImpl implements IotDBService {
   }
 
   @Override
-  public DataModelVO getDataModel(Connection connection) throws BaseException {
+  public DataModelVO getDataModel(Connection connection, String path) throws BaseException {
     SessionPool sessionPool = null;
     try {
       sessionPool = getSessionPool(connection);
-      DataModelVO root = new DataModelVO("root");
-      assembleDataModel(root, "root", sessionPool);
-      root.setGroupCount(getGroupCount(sessionPool));
-      root.setPath("root");
+      DataModelVO root = new DataModelVO(path);
+      setNodeInfo(root, sessionPool, path);
+      List<DataModelVO> childrenDataModel = getChildrenDataModel(root, path, sessionPool);
+      root.setChildren(childrenDataModel);
+      root.setGroupCount(path.equals("root") ? getGroupCount(sessionPool) : null);
+      root.setPath(path);
       return root;
     } finally {
       closeSessionPool(sessionPool);
     }
   }
 
+  private List<DataModelVO> getChildrenDataModel(
+      DataModelVO root, String path, SessionPool sessionPool) throws BaseException {
+    Set<String> childrenNode = getChildrenNode(path, sessionPool);
+    if (childrenNode == null) {
+      return null;
+    }
+    List<DataModelVO> childrenlist = new ArrayList<>();
+
+    // TODO: 大量IO
+    for (String child : childrenNode) {
+      DataModelVO childNode = new DataModelVO(child);
+      setNodeInfo(childNode, sessionPool, path + "." + child);
+      childrenlist.add(childNode);
+    }
+    return childrenlist;
+  }
+
   private void assembleDataModel(DataModelVO node, String prefixPath, SessionPool sessionPool)
       throws BaseException {
     Set<String> childrenNode = getChildrenNode(prefixPath, sessionPool);
@@ -152,22 +195,51 @@ public class IotDBServiceImpl implements IotDBService {
   private Set<String> getChildrenNode(String prefixPath, SessionPool sessionPool)
       throws BaseException {
     String sql = "show storage group " + prefixPath;
+    sql = sql.replace(',', '.');
     List<String> children = executeQueryOneColumn(sessionPool, sql);
-    if (children.size() == 0 || (children.size() == 1 && children.get(0).equals(prefixPath))) {
+    String dealedPrefixPath = prefixPath.replace(',', '.');
+    if (children.size() == 0
+        || (children.size() == 1 && children.get(0).equals(dealedPrefixPath))) {
       sql = "show timeseries " + prefixPath;
+      sql = sql.replace(',', '.');
       children = executeQueryOneColumn(sessionPool, sql);
-      if (children.size() == 0 || (children.size() == 1 && children.get(0).equals(prefixPath))) {
+      if (children.size() == 0
+          || (children.size() == 1 && children.get(0).equals(dealedPrefixPath))) {
         return null;
       }
     }
     Set<String> childrenNode = new HashSet<>();
     for (String child : children) {
+      child = dealChildNode(child);
       child = StringUtils.removeStart(child, prefixPath + ".").split("\\.")[0];
       childrenNode.add(child);
     }
     return childrenNode;
   }
 
+  private String dealChildNode(String child) {
+    int left = 0, right = 0;
+    int length = child.length();
+    while (right < length) {
+      char tempChar = child.charAt(right);
+      if (tempChar != '"' && left == right) {
+        left++;
+        right++;
+      } else if ((tempChar == '"' && left == right) || (tempChar != '"' && left != right)) {
+        right++;
+      } else if (tempChar == '"' && left != right) {
+        String preSubStr = child.substring(0, left);
+        String midSubStr = child.substring(left, right + 1);
+        String tailSubStr = child.substring(right + 1, length);
+        String newMidSubStr = midSubStr.replace('.', ',');
+        child = preSubStr + newMidSubStr + tailSubStr;
+        right++;
+        left = right;
+      }
+    }
+    return child;
+  }
+
   private Integer getGroupCount(SessionPool sessionPool) throws BaseException {
     String sql = "count storage group";
     String value = executeQueryOneValue(sessionPool, sql);
@@ -176,7 +248,19 @@ public class IotDBServiceImpl implements IotDBService {
   }
 
   private Integer getDeviceCount(SessionPool sessionPool, String groupName) throws BaseException {
-    String sql = "count devices " + groupName;
+    String iotdbVersion = executeQueryOneValue(sessionPool, "show version");
+    int versionFlag = 0;
+    if (iotdbVersion.contains("0.12.")) {
+      versionFlag = 12;
+    } else if (iotdbVersion.contains("0.13.") || iotdbVersion.contains("0.14.")) {
+      versionFlag = 13;
+    }
+    String sql = null;
+    if (versionFlag == 13) {
+      sql = "count devices " + groupName + ".**";
+    } else if (versionFlag == 12) {
+      sql = "count devices " + groupName;
+    }
     String value = executeQueryOneValue(sessionPool, sql);
     Integer count = Integer.valueOf(value);
     return count;
@@ -184,7 +268,19 @@ public class IotDBServiceImpl implements IotDBService {
 
   private Integer getMeasurementsCount(SessionPool sessionPool, String deviceName)
       throws BaseException {
-    String sql = "count timeseries " + deviceName;
+    String iotdbVersion = executeQueryOneValue(sessionPool, "show version");
+    int versionFlag = 0;
+    if (iotdbVersion.contains("0.12.")) {
+      versionFlag = 12;
+    } else if (iotdbVersion.contains("0.13.") || iotdbVersion.contains("0.14.")) {
+      versionFlag = 13;
+    }
+    String sql = null;
+    if (versionFlag == 13) {
+      sql = "count timeseries " + deviceName + ".**";
+    } else if (versionFlag == 12) {
+      sql = "count timeseries " + deviceName;
+    }
     String value = executeQueryOneValue(sessionPool, sql);
     Integer count = Integer.valueOf(value);
     return count;
@@ -231,6 +327,7 @@ public class IotDBServiceImpl implements IotDBService {
 
   private void setNodeInfo(DataModelVO dataModelVO, SessionPool sessionPool, String path)
       throws BaseException {
+    path = path.replace(',', '.');
     dataModelVO.setPath(path);
     if (isGroup(sessionPool, path)) {
       dataModelVO.setDeviceCount(getDeviceCount(sessionPool, path));
@@ -258,14 +355,24 @@ public class IotDBServiceImpl implements IotDBService {
             + timeseries.substring(index + 1)
             + ") from "
             + timeseries.substring(0, index);
-    String value = executeQueryOneValue(sessionPool, sql);
+    String value = "0";
+    try {
+      value = executeQueryOneValue(sessionPool, sql);
+    } catch (BaseException e) {
+      e.printStackTrace();
+    }
     return value;
   }
 
   private Integer getOneDataCount(SessionPool sessionPool, String timeseries) throws BaseException {
     int index = timeseries.lastIndexOf(".");
     String sql = "select count(*) from " + timeseries.substring(0, index);
-    String countStr = executeQueryOneLine(sessionPool, sql, "count(" + timeseries + ")");
+    String countStr = "0";
+    try {
+      countStr = executeQueryOneLine(sessionPool, sql, "count(" + timeseries + ")");
+    } catch (BaseException e) {
+      e.printStackTrace();
+    }
     return Integer.parseInt(countStr);
   }
 
@@ -349,7 +456,14 @@ public class IotDBServiceImpl implements IotDBService {
   public void saveStorageGroup(Connection connection, String groupName) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
     try {
-      sessionPool.setStorageGroup(groupName);
+      String iotdbVersion = executeQueryOneValue(sessionPool, "show version");
+      int versionFlag = 0;
+      if (iotdbVersion.contains("0.12.")) {
+        sessionPool.executeNonQueryStatement("set storage group " + groupName);
+      } else if (iotdbVersion.contains("0.13.") || iotdbVersion.contains("0.14.")) {
+        sessionPool.executeNonQueryStatement("create storage group " + groupName);
+      }
+      //      sessionPool.setStorageGroup(groupName);
     } catch (StatementExecutionException e) {
       if (e.getStatusCode() == 602) {
         throw new BaseException(ErrorCode.NO_PRI_SET_GROUP, ErrorCode.NO_PRI_SET_GROUP_MSG);
@@ -362,7 +476,8 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
+      throw new BaseException(
+          ErrorCode.SET_GROUP_FAIL_EXISTS, ErrorCode.SET_GROUP_FAIL__EXISTS_MSG);
     } finally {
       closeSessionPool(sessionPool);
     }
@@ -907,15 +1022,29 @@ public class IotDBServiceImpl implements IotDBService {
       String name,
       String privilegesStr)
       throws BaseException {
-    String sql =
-        operationType
-            + " "
-            + userOrRole
-            + " "
-            + name
-            + " privileges '"
-            + privilegesStr
-            + "' on root";
+    String show_version = executeQueryOneValue(sessionPool, "show version");
+    String sql = null;
+    if (show_version.contains("0.13") || show_version.contains("0.14")) {
+      sql =
+          operationType
+              + " "
+              + userOrRole
+              + " "
+              + name
+              + " privileges "
+              + privilegesStr
+              + " on root";
+    } else if (show_version.contains("0.12")) {
+      sql =
+          operationType
+              + " "
+              + userOrRole
+              + " "
+              + name
+              + " privileges '"
+              + privilegesStr
+              + "' on root";
+    }
     try {
       sessionPool.executeNonQueryStatement(sql);
     } catch (StatementExecutionException e) {
@@ -1444,7 +1573,9 @@ public class IotDBServiceImpl implements IotDBService {
 
   private void upsertMeasurementAlias(SessionPool sessionPool, String timeseries, String alias)
       throws BaseException {
-    if (alias == null || "null".equals(alias) || StringUtils.isBlank(alias)) {
+    // 需要改为" "值。
+    if (alias == null || "null".equals(alias)) {
+      //    if (alias == null || "null".equals(alias) || StringUtils.isBlank(alias)) {
       return;
     }
     if (alias.matches("^as$") || alias.matches("^\\d+$") || alias.matches("^like$")) {
@@ -2305,6 +2436,1610 @@ public class IotDBServiceImpl implements IotDBService {
     throw new BaseException(ErrorCode.NO_QUERY, ErrorCode.NO_QUERY_MSG);
   }
 
+  @Override
+  public QueryInfoDTO getQueryInfoListByQueryClassificationId(
+      Connection connection,
+      Integer queryClassificationId,
+      Integer pageSize,
+      Integer pageNum,
+      String filterString,
+      Long startTime,
+      Long endTime,
+      Integer executionResult)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    // TODO 【清华】需要获得查询语句详细信息的接口
+    QueryInfoDTO queryInfoDTO = new QueryInfoDTO();
+    // FakeData
+    // ***********************************************************
+    List<QueryDataVO> queryDataVOS = new ArrayList<>();
+    switch (queryClassificationId % 2) {
+      case 0:
+        for (int i = 0; i < 200; i++) {
+          QueryData1VO queryDataVO = new QueryData1VO();
+          long currentTimeMillis = System.currentTimeMillis();
+          queryDataVO.setId(i);
+          queryDataVO.setStatement(
+              "select * from root._metric.'127.0.0.1:8086'.'process_cpu_time'.'name=process'");
+          queryDataVO.setRunningTime(currentTimeMillis);
+          queryDataVO.setIsSlowQuery(i % 2 == 0 ? false : true);
+          queryDataVO.setTotalTime((int) (currentTimeMillis % 100));
+          queryDataVO.setAnalysisTime((int) (currentTimeMillis % 50));
+          queryDataVO.setPrecompiledTime((int) (currentTimeMillis % 30));
+          queryDataVO.setOptimizedTime((int) (currentTimeMillis % 20));
+          queryDataVO.setExecutionTime((int) (currentTimeMillis % 10));
+          queryDataVO.setExecutionResult(i % 2 == 0 ? 1 : 2);
+          queryDataVOS.add(queryDataVO);
+        }
+        break;
+      case 1:
+        for (int i = 0; i < 200; i++) {
+          QueryDataVO queryDataVO = new QueryDataVO();
+          long currentTimeMillis = System.currentTimeMillis();
+          queryDataVO.setId(i);
+          queryDataVO.setStatement(
+              "select * from root._metric.'127.0.0.1:8086'.'process_cpu_time'.'name=process'");
+          queryDataVO.setRunningTime(currentTimeMillis);
+          queryDataVO.setIsSlowQuery(i % 2 == 0 ? false : true);
+          queryDataVO.setTotalTime((int) (currentTimeMillis % 100));
+          queryDataVO.setAnalysisTime((int) (currentTimeMillis % 50));
+          queryDataVO.setExecutionTime((int) (currentTimeMillis % 10));
+          queryDataVO.setExecutionResult(i % 2 == 0 ? 1 : 2);
+          queryDataVOS.add(queryDataVO);
+        }
+        break;
+    }
+    // ***********************************************************
+    int queryDataVOSSize = queryDataVOS.size();
+    int count = 0;
+    Long latestTimeStamp = 0L;
+    List<QueryDataVO> filteredQueryDataVOS = new ArrayList<>();
+    if (queryDataVOSSize > 0) {
+      if ((filterString != null && filterString.length() != 0)
+          || (startTime != -1)
+          || (endTime != -1)
+          || (executionResult != null)) {
+        QueryDataDo queryDataDo =
+            filterQueryData(
+                queryDataVOS, pageSize, pageNum, filterString, startTime, endTime, executionResult);
+
+        count = queryDataDo.getCount();
+        latestTimeStamp = queryDataDo.getLatestTimeStamp();
+        filteredQueryDataVOS = queryDataDo.getQueryDataVOs();
+      } else {
+        for (QueryDataVO queryDataVO : queryDataVOS) {
+          count++;
+          latestTimeStamp = Math.max(latestTimeStamp, queryDataVO.getRunningTime());
+          if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+            filteredQueryDataVOS.add(queryDataVO);
+          }
+        }
+      }
+    }
+    String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+    List<QueryDataStrVO> filteredQueryDataStrVOS = new ArrayList<>();
+    if (queryClassificationId % 2 == 0) {
+      for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+        QueryDataStrVO1 queryDataStrVO = new QueryDataStrVO1();
+        BeanUtils.copyProperties(queryDataVO, queryDataStrVO);
+        queryDataStrVO.setRunningTime(simpleDateFormat.format(queryDataVO.getRunningTime()));
+        filteredQueryDataStrVOS.add(queryDataStrVO);
+      }
+    } else {
+      for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+        QueryDataStrVO queryDataStrVO = new QueryDataStrVO();
+        BeanUtils.copyProperties(queryDataVO, queryDataStrVO);
+        queryDataStrVO.setRunningTime(simpleDateFormat.format(queryDataVO.getRunningTime()));
+        filteredQueryDataStrVOS.add(queryDataStrVO);
+      }
+    }
+
+    queryInfoDTO.setTotalCount(count);
+    queryInfoDTO.setLatestRunningTime(latestTimeStamp);
+    queryInfoDTO.setFilteredQueryDataStrVOSList(filteredQueryDataStrVOS);
+    queryInfoDTO.setTotalPage(count % pageSize == 0 ? count / pageSize : count / pageSize + 1);
+    return queryInfoDTO;
+  }
+
+  @Override
+  public MetricsDataForDiagramVO getMetricDataByMetricId(Connection connection, Integer metricId)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    String url = connection.getHost();
+    Integer port = 0;
+    // TODO: 【清华】端口8086实际上是动态的从connection表中获取,但iotdb-0.13.0存在bug,导致写入的指标位置不对,等待修复,先暂时写死
+    String show_version = executeQueryOneValue(sessionPool, "show version");
+    if (show_version.contains("0.13") || show_version.contains("0.14")) {
+      port = 8086;
+    } else if (show_version.contains("0.12")) {
+      port = 6667;
+      url = "0.0.0.0";
+    }
+    // TODO: 指标先写死,后面根据指标Id判断用哪个timeSeries拼串为SQL查得值。
+    MetricsChartDataVO metricsChartDataVO = null;
+    MetricsDataForDiagramVO metricsDataForDiagramVO = new MetricsDataForDiagramVO();
+    switch (metricId) {
+      case 0:
+        metricsChartDataVO = getJVMGCDiagramData(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 1:
+        metricsChartDataVO = getJVMLoadDiagramData(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 2:
+        metricsChartDataVO = getYGCTimeAndReason(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 3:
+        metricsChartDataVO = getFGCTimeAndReason(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 4:
+        metricsChartDataVO = getVariableThreadCount(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 5:
+        metricsChartDataVO =
+            getVariableTimeThreadCount(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 6:
+        metricsChartDataVO = getMemUsedSize(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 7:
+        metricsChartDataVO = getBufferSize(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 8:
+        metricsChartDataVO = getCPUTime(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 9:
+        metricsChartDataVO = getDiskIO(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 10:
+        metricsChartDataVO = getFileCount(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 11:
+        metricsChartDataVO = getFileSize(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 12:
+        metricsChartDataVO = getWriteCount(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 13:
+        metricsChartDataVO = getQueryCount(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 14:
+        metricsChartDataVO = getInterfaceCount(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+      case 15:
+        metricsChartDataVO = getInterfaceTime(sessionPool, sessionDataSetWrapper, url, port);
+        break;
+    }
+    metricsDataForDiagramVO.setChartData(metricsChartDataVO);
+    metricsDataForDiagramVO.setMetricId(metricId);
+    return metricsDataForDiagramVO;
+  }
+
+  private MetricsChartDataVO getInterfaceTime(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    // TODO:假数据
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("Interface1");
+    metricnameList.add("Interface2");
+    metricnameList.add("Interface3");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("ms");
+    List<String> interface1 = new ArrayList<>();
+    List<String> interface2 = new ArrayList<>();
+    List<String> interface3 = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=mapped\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    //      try {
+    //        sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+    //        int batchSize = sessionDataSetWrapper.getBatchSize();
+    //        if (batchSize > 0) {
+    //          int count = 0;
+    //          while (sessionDataSetWrapper.hasNext()) {
+    //            count++;
+    //            RowRecord rowRecord = sessionDataSetWrapper.next();
+    //            long timestamp = rowRecord.getTimestamp();
+    //            List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+    //            String pattern1 = "HH:mm";
+    //            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    //            timeList.add(simpleDateFormat1.format(timestamp));
+    //            buffer.add(
+    //                    getNetFileSizeDescription(
+    //                            (getLongFromString(
+    //                                    (Float.parseFloat(fields1.get(0).toString())
+    //                                            + Float.parseFloat(fields1.get(1).toString()))
+    //                                            + ""))));
+    //          }
+    //          Collections.reverse(buffer);
+    //          Collections.reverse(max);
+    //          dataList.put(metricnameList.get(0), buffer);
+    //          dataList.put(metricnameList.get(1), max);
+    //          Collections.reverse(timeList);
+    //          metricsChartDataVO.setTimeList(timeList);
+    //          metricsChartDataVO.setMetricnameList(metricnameList);
+    //          metricsChartDataVO.setDataList(dataList);
+    //        }
+    //      } catch (IoTDBConnectionException e) {
+    //        e.printStackTrace();
+    //      } catch (StatementExecutionException e) {
+    //        e.printStackTrace();
+    //      }
+    String pattern1 = "HH:mm";
+    SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    long timestamp = System.currentTimeMillis();
+    for (int i = 0; i < 16; i++) {
+      timeList.add(simpleDateFormat1.format(timestamp));
+      timestamp -= 60000;
+      interface1.add("300");
+      interface2.add("200");
+      interface3.add("500");
+    }
+    Collections.reverse(timeList);
+    Collections.reverse(interface1);
+    Collections.reverse(interface2);
+    Collections.reverse(interface3);
+    dataList.put(metricnameList.get(0), interface1);
+    dataList.put(metricnameList.get(1), interface2);
+    dataList.put(metricnameList.get(2), interface3);
+    metricsChartDataVO.setTimeList(timeList);
+    metricsChartDataVO.setMetricnameList(metricnameList);
+    metricsChartDataVO.setDataList(dataList);
+    metricsChartDataVO.setUnitList(unitList);
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getInterfaceCount(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("Close Operation");
+    metricnameList.add("Execute Query Statement");
+    metricnameList.add("Execute Statement");
+    metricnameList.add("Get Properties");
+    metricnameList.add("Insert Record");
+    metricnameList.add("Close Session");
+    metricnameList.add("Open Session");
+    metricnameList.add("Request Statement Id");
+    metricnameList.add("Fetch Results");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("ms");
+    List<String> close_Operation = new ArrayList<>();
+    List<String> execute_Query_Statement = new ArrayList<>();
+    List<String> execute_Statement = new ArrayList<>();
+    List<String> get_Properties = new ArrayList<>();
+    List<String> insert_Record = new ArrayList<>();
+    List<String> close_Session = new ArrayList<>();
+    List<String> open_Session = new ArrayList<>();
+    List<String> request_Statement_Id = new ArrayList<>();
+    List<String> fetch_Results = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=closeOperation\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=executeQueryStatement\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=executeStatement\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=getProperties\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=insertRecord\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=closeSession\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=openSession\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=requestStatementId\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"entry_total\".\"name=fetchResults\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          close_Operation.add(fields1.get(0).toString());
+          execute_Query_Statement.add(fields1.get(1).toString());
+          execute_Statement.add(fields1.get(2).toString());
+          get_Properties.add(fields1.get(3).toString());
+          insert_Record.add(fields1.get(4).toString());
+          close_Session.add(fields1.get(5).toString());
+          open_Session.add(fields1.get(6).toString());
+          request_Statement_Id.add(fields1.get(7).toString());
+          fetch_Results.add(fields1.get(8).toString());
+        }
+        Collections.reverse(close_Operation);
+        Collections.reverse(execute_Query_Statement);
+        Collections.reverse(execute_Statement);
+        Collections.reverse(get_Properties);
+        Collections.reverse(insert_Record);
+        Collections.reverse(close_Session);
+        Collections.reverse(open_Session);
+        Collections.reverse(request_Statement_Id);
+        Collections.reverse(fetch_Results);
+        dataList.put(metricnameList.get(0), close_Operation);
+        dataList.put(metricnameList.get(1), execute_Query_Statement);
+        dataList.put(metricnameList.get(2), execute_Statement);
+        dataList.put(metricnameList.get(3), get_Properties);
+        dataList.put(metricnameList.get(4), insert_Record);
+        dataList.put(metricnameList.get(5), close_Session);
+        dataList.put(metricnameList.get(6), open_Session);
+        dataList.put(metricnameList.get(7), request_Statement_Id);
+        dataList.put(metricnameList.get(8), fetch_Results);
+        Collections.reverse(timeList);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getQueryCount(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    // TODO:假数据
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("success");
+    metricnameList.add("fail");
+    metricnameList.add("total");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("ms");
+    List<String> success = new ArrayList<>();
+    List<String> fail = new ArrayList<>();
+    List<String> total = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=mapped\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    //      try {
+    //        sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+    //        int batchSize = sessionDataSetWrapper.getBatchSize();
+    //        if (batchSize > 0) {
+    //          int count = 0;
+    //          while (sessionDataSetWrapper.hasNext()) {
+    //            count++;
+    //            RowRecord rowRecord = sessionDataSetWrapper.next();
+    //            long timestamp = rowRecord.getTimestamp();
+    //            List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+    //            String pattern1 = "HH:mm";
+    //            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    //            timeList.add(simpleDateFormat1.format(timestamp));
+    //            buffer.add(
+    //                    getNetFileSizeDescription(
+    //                            (getLongFromString(
+    //                                    (Float.parseFloat(fields1.get(0).toString())
+    //                                            + Float.parseFloat(fields1.get(1).toString()))
+    //                                            + ""))));
+    //          }
+    //          Collections.reverse(buffer);
+    //          Collections.reverse(max);
+    //          dataList.put(metricnameList.get(0), buffer);
+    //          dataList.put(metricnameList.get(1), max);
+    //          Collections.reverse(timeList);
+    //          metricsChartDataVO.setTimeList(timeList);
+    //          metricsChartDataVO.setMetricnameList(metricnameList);
+    //          metricsChartDataVO.setDataList(dataList);
+    //        }
+    //      } catch (IoTDBConnectionException e) {
+    //        e.printStackTrace();
+    //      } catch (StatementExecutionException e) {
+    //        e.printStackTrace();
+    //      }
+    String pattern1 = "HH:mm";
+    SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    long timestamp = System.currentTimeMillis();
+    for (int i = 0; i < 16; i++) {
+      timeList.add(simpleDateFormat1.format(timestamp));
+      timestamp -= 60000;
+      success.add("100");
+      fail.add("200");
+      total.add("300");
+    }
+    Collections.reverse(timeList);
+    Collections.reverse(success);
+    Collections.reverse(fail);
+    Collections.reverse(total);
+    dataList.put(metricnameList.get(0), success);
+    dataList.put(metricnameList.get(1), fail);
+    dataList.put(metricnameList.get(2), total);
+    metricsChartDataVO.setTimeList(timeList);
+    metricsChartDataVO.setMetricnameList(metricnameList);
+    metricsChartDataVO.setDataList(dataList);
+    metricsChartDataVO.setUnitList(unitList);
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getWriteCount(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    // TODO:假数据
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("success");
+    metricnameList.add("fail");
+    metricnameList.add("total");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("ms");
+    List<String> success = new ArrayList<>();
+    List<String> fail = new ArrayList<>();
+    List<String> total = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=mapped\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    //      try {
+    //        sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+    //        int batchSize = sessionDataSetWrapper.getBatchSize();
+    //        if (batchSize > 0) {
+    //          int count = 0;
+    //          while (sessionDataSetWrapper.hasNext()) {
+    //            count++;
+    //            RowRecord rowRecord = sessionDataSetWrapper.next();
+    //            long timestamp = rowRecord.getTimestamp();
+    //            List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+    //            String pattern1 = "HH:mm";
+    //            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    //            timeList.add(simpleDateFormat1.format(timestamp));
+    //            buffer.add(
+    //                    getNetFileSizeDescription(
+    //                            (getLongFromString(
+    //                                    (Float.parseFloat(fields1.get(0).toString())
+    //                                            + Float.parseFloat(fields1.get(1).toString()))
+    //                                            + ""))));
+    //          }
+    //          Collections.reverse(buffer);
+    //          Collections.reverse(max);
+    //          dataList.put(metricnameList.get(0), buffer);
+    //          dataList.put(metricnameList.get(1), max);
+    //          Collections.reverse(timeList);
+    //          metricsChartDataVO.setTimeList(timeList);
+    //          metricsChartDataVO.setMetricnameList(metricnameList);
+    //          metricsChartDataVO.setDataList(dataList);
+    //        }
+    //      } catch (IoTDBConnectionException e) {
+    //        e.printStackTrace();
+    //      } catch (StatementExecutionException e) {
+    //        e.printStackTrace();
+    //      }
+    String pattern1 = "HH:mm";
+    SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    long timestamp = System.currentTimeMillis();
+    for (int i = 0; i < 16; i++) {
+      timeList.add(simpleDateFormat1.format(timestamp));
+      timestamp -= 60000;
+      success.add("10");
+      fail.add("20");
+      total.add("30");
+    }
+    Collections.reverse(timeList);
+    Collections.reverse(success);
+    Collections.reverse(fail);
+    Collections.reverse(total);
+    dataList.put(metricnameList.get(0), success);
+    dataList.put(metricnameList.get(1), fail);
+    dataList.put(metricnameList.get(2), total);
+    metricsChartDataVO.setTimeList(timeList);
+    metricsChartDataVO.setMetricnameList(metricnameList);
+    metricsChartDataVO.setDataList(dataList);
+    metricsChartDataVO.setUnitList(unitList);
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getFileSize(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("wal");
+    metricnameList.add("tsfile_seq");
+    metricnameList.add("tsfile_unseq");
+    metricnameList.add("total");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("MB");
+    List<String> wal = new ArrayList<>();
+    List<String> tsfile_seq = new ArrayList<>();
+    List<String> tsfile_unseq = new ArrayList<>();
+    List<String> total = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=wal\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=seq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_size\".\"name=unseq\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          wal.add(getNetFileSizeDescription((long) Float.parseFloat(fields1.get(0).toString())));
+          tsfile_seq.add(
+              getNetFileSizeDescription((long) Float.parseFloat(fields1.get(1).toString())));
+          tsfile_unseq.add(
+              getNetFileSizeDescription((long) Float.parseFloat(fields1.get(2).toString())));
+          total.add(
+              getNetFileSizeDescription(
+                  (long)
+                      (Float.parseFloat(fields1.get(0).toString())
+                          + Float.parseFloat(fields1.get(1).toString())
+                          + Float.parseFloat(fields1.get(2).toString()))));
+        }
+        Collections.reverse(timeList);
+        Collections.reverse(wal);
+        Collections.reverse(tsfile_seq);
+        Collections.reverse(tsfile_unseq);
+        Collections.reverse(total);
+        dataList.put(metricnameList.get(0), wal);
+        dataList.put(metricnameList.get(1), tsfile_seq);
+        dataList.put(metricnameList.get(2), tsfile_unseq);
+        dataList.put(metricnameList.get(3), total);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getFileCount(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("wal");
+    metricnameList.add("tsfile_seq");
+    metricnameList.add("tsfile_unseq");
+    metricnameList.add("total");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("个");
+    List<String> wal = new ArrayList<>();
+    List<String> tsfile_seq = new ArrayList<>();
+    List<String> tsfile_unseq = new ArrayList<>();
+    List<String> total = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=wal\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=seq\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"file_count\".\"name=unseq\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          String s1 = fields1.get(0).toString();
+          wal.add(s1.substring(0, s1.indexOf('.')));
+          String s2 = fields1.get(1).toString();
+          tsfile_seq.add(s2.substring(0, s2.indexOf('.')));
+          String s3 = fields1.get(2).toString();
+          tsfile_unseq.add(s3.substring(0, s3.indexOf('.')));
+          total.add(
+              (Integer.parseInt(s1.substring(0, s1.indexOf('.')))
+                      + Integer.parseInt(s2.substring(0, s2.indexOf('.'))))
+                  + Integer.parseInt(s3.substring(0, s3.indexOf('.')))
+                  + "个");
+        }
+        Collections.reverse(timeList);
+        Collections.reverse(wal);
+        Collections.reverse(tsfile_seq);
+        Collections.reverse(tsfile_unseq);
+        Collections.reverse(total);
+        dataList.put(metricnameList.get(0), wal);
+        dataList.put(metricnameList.get(1), tsfile_seq);
+        dataList.put(metricnameList.get(2), tsfile_unseq);
+        dataList.put(metricnameList.get(3), total);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getDiskIO(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    // TODO : 假数据 等待接口
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("io");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("次/s");
+    List<String> io = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=mapped\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    //      try {
+    //        sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+    //        int batchSize = sessionDataSetWrapper.getBatchSize();
+    //        if (batchSize > 0) {
+    //          int count = 0;
+    //          while (sessionDataSetWrapper.hasNext()) {
+    //            count++;
+    //            RowRecord rowRecord = sessionDataSetWrapper.next();
+    //            long timestamp = rowRecord.getTimestamp();
+    //            List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+    //            String pattern1 = "HH:mm";
+    //            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    //            timeList.add(simpleDateFormat1.format(timestamp));
+    //            buffer.add(
+    //                    getNetFileSizeDescription(
+    //                            (getLongFromString(
+    //                                    (Float.parseFloat(fields1.get(0).toString())
+    //                                            + Float.parseFloat(fields1.get(1).toString()))
+    //                                            + ""))));
+    //          }
+    //          Collections.reverse(buffer);
+    //          Collections.reverse(max);
+    //          dataList.put(metricnameList.get(0), buffer);
+    //          dataList.put(metricnameList.get(1), max);
+    //          Collections.reverse(timeList);
+    //          metricsChartDataVO.setTimeList(timeList);
+    //          metricsChartDataVO.setMetricnameList(metricnameList);
+    //          metricsChartDataVO.setDataList(dataList);
+    //        }
+    //      } catch (IoTDBConnectionException e) {
+    //        e.printStackTrace();
+    //      } catch (StatementExecutionException e) {
+    //        e.printStackTrace();
+    //      }
+    String pattern1 = "HH:mm";
+    SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    long timestamp = System.currentTimeMillis();
+    for (int i = 0; i < 16; i++) {
+      timeList.add(simpleDateFormat1.format(timestamp));
+      timestamp -= 60000;
+      io.add("20");
+    }
+    Collections.reverse(timeList);
+    Collections.reverse(io);
+    dataList.put(metricnameList.get(0), io);
+    metricsChartDataVO.setTimeList(timeList);
+    metricsChartDataVO.setMetricnameList(metricnameList);
+    metricsChartDataVO.setDataList(dataList);
+    metricsChartDataVO.setUnitList(unitList);
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getBufferSize(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("buffer");
+    metricnameList.add("max");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("MB");
+    List<String> buffer = new ArrayList<>();
+    List<String> max = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=mapped\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.memory.used\".\"id=direct\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.total.capacity\".\"id=mapped\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.buffer.total.capacity\".\"id=direct\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          buffer.add(
+              getNetFileSizeDescription(
+                  (getLongFromString(
+                      (Float.parseFloat(fields1.get(0).toString())
+                              + Float.parseFloat(fields1.get(1).toString()))
+                          + ""))));
+          max.add(
+              getNetFileSizeDescription(
+                  (getLongFromString(
+                      (Float.parseFloat(fields1.get(2).toString())
+                              + Float.parseFloat(fields1.get(3).toString()))
+                          + ""))));
+        }
+        Collections.reverse(buffer);
+        Collections.reverse(max);
+        dataList.put(metricnameList.get(0), buffer);
+        dataList.put(metricnameList.get(1), max);
+        Collections.reverse(timeList);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getMemUsedSize(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("storage");
+    metricnameList.add("max");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("MB");
+    List<String> storage = new ArrayList<>();
+    List<String> max = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=nonheap\".\"id=Compressed Class Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=nonheap\".\"id=Code Cache\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=nonheap\".\"id=Metaspace\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=heap\".\"id=PS Old Gen\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=heap\".\"id=PS Eden Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.max\".\"area=heap\".\"id=PS Survivor Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=nonheap\".\"id=Compressed Class Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=nonheap\".\"id=Code Cache\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=nonheap\".\"id=Metaspace\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=heap\".\"id=PS Old Gen\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=heap\".\"id=PS Eden Space\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.memory.used\".\"area=heap\".\"id=PS Survivor Space\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          storage.add(
+              getNetFileSizeDescription(
+                  (getLongFromString(
+                      (Float.parseFloat(fields1.get(6).toString())
+                              + Float.parseFloat(fields1.get(7).toString())
+                              + Float.parseFloat(fields1.get(8).toString())
+                              + Float.parseFloat(fields1.get(9).toString())
+                              + Float.parseFloat(fields1.get(10).toString())
+                              + Float.parseFloat(fields1.get(11).toString()))
+                          + ""))));
+          max.add(
+              getNetFileSizeDescription(
+                  (getLongFromString(
+                      (Float.parseFloat(fields1.get(0).toString())
+                              + Float.parseFloat(fields1.get(1).toString())
+                              + Float.parseFloat(fields1.get(2).toString())
+                              + Float.parseFloat(fields1.get(3).toString())
+                              + Float.parseFloat(fields1.get(4).toString())
+                              + Float.parseFloat(fields1.get(5).toString()))
+                          + ""))));
+        }
+        Collections.reverse(storage);
+        Collections.reverse(max);
+        dataList.put(metricnameList.get(0), storage);
+        dataList.put(metricnameList.get(1), max);
+        Collections.reverse(timeList);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getVariableTimeThreadCount(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("new");
+    metricnameList.add("canrunning");
+    metricnameList.add("running");
+    metricnameList.add("block");
+    metricnameList.add("die");
+    metricnameList.add("dormancy");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("个");
+    List<String> newState = new ArrayList<>();
+    List<String> canrunning = new ArrayList<>();
+    List<String> running = new ArrayList<>();
+    List<String> block = new ArrayList<>();
+    List<String> die = new ArrayList<>();
+    List<String> dormancy = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=new\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=waiting\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=runnable\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=blocked\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=timed-waiting\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.states\".\"state=terminated\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          String s1 = fields1.get(0).toString();
+          newState.add(s1.substring(0, s1.indexOf('.')));
+          String s2 = fields1.get(1).toString();
+          canrunning.add(s2.substring(0, s2.indexOf('.')));
+          String s3 = fields1.get(2).toString();
+          running.add(s3.substring(0, s3.indexOf('.')));
+          String s4 = fields1.get(3).toString();
+          block.add(s4.substring(0, s4.indexOf('.')));
+          String s5 = fields1.get(4).toString();
+          die.add(s5.substring(0, s5.indexOf('.')));
+          String s6 = fields1.get(5).toString();
+          dormancy.add(s6.substring(0, s6.indexOf('.')));
+        }
+        Collections.reverse(timeList);
+        Collections.reverse(newState);
+        Collections.reverse(canrunning);
+        Collections.reverse(running);
+        Collections.reverse(block);
+        Collections.reverse(die);
+        Collections.reverse(dormancy);
+        dataList.put(metricnameList.get(0), newState);
+        dataList.put(metricnameList.get(1), canrunning);
+        dataList.put(metricnameList.get(2), running);
+        dataList.put(metricnameList.get(3), block);
+        dataList.put(metricnameList.get(4), die);
+        dataList.put(metricnameList.get(5), dormancy);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getVariableThreadCount(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("front");
+    metricnameList.add("end");
+    metricnameList.add("total");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("个");
+    List<String> front = new ArrayList<>();
+    List<String> end = new ArrayList<>();
+    List<String> total = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.daemon\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.live\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          String s1 = fields1.get(0).toString();
+          end.add(s1.substring(0, s1.indexOf('.')));
+          String s2 = fields1.get(1).toString();
+          total.add(s2.substring(0, s2.indexOf('.')));
+          front.add(
+              (Integer.parseInt(s2.substring(0, s2.indexOf('.')))
+                      - Integer.parseInt(s1.substring(0, s1.indexOf('.'))))
+                  + "");
+        }
+        Collections.reverse(timeList);
+        Collections.reverse(front);
+        Collections.reverse(end);
+        Collections.reverse(total);
+        dataList.put(metricnameList.get(0), front);
+        dataList.put(metricnameList.get(1), end);
+        dataList.put(metricnameList.get(2), total);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getCPUTime(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    // TODO:【接口缺失,等待确认增加】
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("模块1");
+    metricnameList.add("模块2");
+    metricnameList.add("模块3");
+    metricnameList.add("模块4");
+    metricnameList.add("模块5");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("%");
+    List<String> module1 = new ArrayList<>();
+    List<String> module2 = new ArrayList<>();
+    List<String> module3 = new ArrayList<>();
+    List<String> module4 = new ArrayList<>();
+    List<String> module5 = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.daemon\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.threads.live\" "
+            + "order by time desc limit 1";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    //      try {
+    //        sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+    //        int batchSize = sessionDataSetWrapper.getBatchSize();
+    //        if (batchSize > 0) {
+    //          int count = 0;
+    //          while (sessionDataSetWrapper.hasNext()) {
+    //            count++;
+    //            RowRecord rowRecord = sessionDataSetWrapper.next();
+    //            long timestamp = rowRecord.getTimestamp();
+    //            List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+    //            String pattern1 = "HH:mm";
+    //            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+    //            timeList.add(simpleDateFormat1.format(timestamp));
+    //            String s1 = fields1.get(0).toString();
+    //            end.add(s1.substring(0, s1.indexOf('.')));
+    //            String s2 = fields1.get(1).toString();
+    //            total.add(s2.substring(0, s2.indexOf('.')));
+    //            front.add((Integer.parseInt(s2.substring(0,
+    // s2.indexOf('.')))-Integer.parseInt(s1.substring(0, s1.indexOf('.')))) + "");
+    //          }
+    //          dataList.put(metricnameList.get(0), front);
+    //          dataList.put(metricnameList.get(1), end);
+    //          dataList.put(metricnameList.get(2), total);
+    //          metricsChartDataVO.setTimeList(timeList);
+    //          metricsChartDataVO.setMetricnameList(metricnameList);
+    //          metricsChartDataVO.setDataList(dataList);
+    //        }
+    //      } catch (IoTDBConnectionException e) {
+    //        e.printStackTrace();
+    //      } catch (StatementExecutionException e) {
+    //        e.printStackTrace();
+    //      }
+    module1.add("15" + "%");
+    module2.add("25" + "%");
+    module3.add("20" + "%");
+    module4.add("30" + "%");
+    module5.add("10" + "%");
+
+    dataList.put(metricnameList.get(0), module1);
+    dataList.put(metricnameList.get(1), module2);
+    dataList.put(metricnameList.get(2), module3);
+    dataList.put(metricnameList.get(3), module3);
+    dataList.put(metricnameList.get(4), module3);
+    metricsChartDataVO.setTimeList(timeList);
+    metricsChartDataVO.setMetricnameList(metricnameList);
+    metricsChartDataVO.setDataList(dataList);
+    metricsChartDataVO.setUnitList(unitList);
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getYGCTimeAndReason(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("Metadata GC Threshold");
+    metricnameList.add("Allocation Failure");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("ms");
+    List<String> metadata_GC_Threshold_Reason = new ArrayList<>();
+    List<String> Allocation_Failure_Reason = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Allocation Failure\" "
+            + "order by time desc limit 1";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          metadata_GC_Threshold_Reason.add(Float.parseFloat(fields1.get(0).toString()) + "");
+          Allocation_Failure_Reason.add(Float.parseFloat(fields1.get(1).toString()) + "");
+        }
+        dataList.put(metricnameList.get(0), metadata_GC_Threshold_Reason);
+        dataList.put(metricnameList.get(1), Allocation_Failure_Reason);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getFGCTimeAndReason(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("Metadata GC Threshold");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("ms");
+    List<String> metadata_GC_Threshold_Reason = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\" "
+            + "order by time desc limit 1";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          metadata_GC_Threshold_Reason.add(Float.parseFloat(fields1.get(0).toString()) + "");
+        }
+        dataList.put(metricnameList.get(0), metadata_GC_Threshold_Reason);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private MetricsChartDataVO getJVMLoadDiagramData(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("load");
+    metricnameList.add("unload");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("个");
+    List<String> load = new ArrayList<>();
+    List<String> unload = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.classes.loaded\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.classes.unloaded\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          String s1 = fields1.get(0).toString();
+          load.add(s1.substring(0, s1.indexOf('.')));
+          String s2 = fields1.get(1).toString();
+          unload.add(s2.substring(0, s2.indexOf('.')));
+        }
+        Collections.reverse(load);
+        Collections.reverse(unload);
+        dataList.put(metricnameList.get(0), load);
+        dataList.put(metricnameList.get(1), unload);
+        Collections.reverse(timeList);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  @Override
+  public List<QueryMetricsVO> getTopQueryMetricsData() {
+    // TODO [清华]提供获取Top SQL语句信息的接口
+    // FakeData
+    List<QueryMetricsVO> queryMetricsVOS = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      QueryMetricsVO queryMetricsVO = new QueryMetricsVO();
+      String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+      SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+      String timeStamp = simpleDateFormat.format(System.currentTimeMillis());
+      queryMetricsVO.setSQLStatement("SELECT * FROM root.* where time > " + timeStamp);
+      queryMetricsVO.setRunningTime(timeStamp);
+      queryMetricsVO.setExecutionTime(200 - 10 * i);
+      queryMetricsVOS.add(queryMetricsVO);
+    }
+    return queryMetricsVOS;
+  }
+
+  @Override
+  public List<QueryMetricsVO> getSlowQueryMetricsData() {
+    // TODO [清华]提供获取Slow SQL语句信息的接口
+    // FakeData
+    List<QueryMetricsVO> queryMetricsVOS = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      QueryMetricsVO queryMetricsVO = new QueryMetricsVO();
+      String pattern = "yyyy-MM-dd' 'HH:mm:ss.SSS";
+      SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
+      String timeStamp = simpleDateFormat.format(System.currentTimeMillis());
+      queryMetricsVO.setSQLStatement("SELECT * FROM root.* where time > " + timeStamp);
+      queryMetricsVO.setRunningTime(timeStamp);
+      queryMetricsVO.setExecutionTime(1000 - 10 * i);
+      queryMetricsVOS.add(queryMetricsVO);
+    }
+    return queryMetricsVOS;
+  }
+
+  private MetricsChartDataVO getJVMGCDiagramData(
+      SessionPool sessionPool,
+      SessionDataSetWrapper sessionDataSetWrapper,
+      String url,
+      Integer port) {
+    List<String> timeList = new ArrayList<>();
+    List<String> metricnameList = new ArrayList<>();
+    metricnameList.add("fgc次数");
+    metricnameList.add("ygc次数");
+    metricnameList.add("fgc耗时");
+    metricnameList.add("ygc耗时");
+    List<String> unitList = new ArrayList<>();
+    unitList.add("次");
+    unitList.add("ms");
+    List<String> majorGCCount = new ArrayList<>();
+    List<String> minorGCCount = new ArrayList<>();
+    List<String> majorGCTime = new ArrayList<>();
+    List<String> minorGCTime = new ArrayList<>();
+    HashMap<String, List<String>> dataList = new HashMap<>();
+    if (port == 6668) {
+      port = 8086;
+    }
+    String sql =
+        "select * from "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_count\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_count\".\"action=end of minor GC\".\"cause=Allocation Failure\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_count\".\"action=end of major GC\".\"cause=Metadata GC Threshold\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Metadata GC Threshold\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of minor GC\".\"cause=Allocation Failure\", "
+            + "root._metric.\"127.0.0.1:"
+            + port
+            + "\".\"jvm.gc.pause_total\".\"action=end of major GC\".\"cause=Metadata GC Threshold\" "
+            + "order by time desc limit 16";
+    MetricsChartDataVO metricsChartDataVO = new MetricsChartDataVO();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        int count = 0;
+        while (sessionDataSetWrapper.hasNext()) {
+          count++;
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields1 = rowRecord.getFields();
+          String pattern1 = "HH:mm";
+          SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(pattern1);
+          timeList.add(simpleDateFormat1.format(timestamp));
+          String s1 = fields1.get(2).toString();
+          s1 = s1.substring(0, s1.indexOf('.'));
+          String s2 = fields1.get(0).toString();
+          s2 = s2.substring(0, s2.indexOf('.'));
+          String s3 = fields1.get(1).toString();
+          s3 = s3.substring(0, s3.indexOf('.'));
+          majorGCCount.add(s1 + "次");
+          minorGCCount.add((Integer.parseInt(s2) + Integer.parseInt(s3)) + "次");
+          majorGCTime.add(Float.parseFloat(fields1.get(5).toString()) + "ms");
+          minorGCTime.add(
+              (Float.parseFloat(fields1.get(3).toString())
+                      + Float.parseFloat(fields1.get(4).toString()))
+                  + "ms");
+        }
+        Collections.reverse(majorGCCount);
+        Collections.reverse(minorGCCount);
+        Collections.reverse(majorGCTime);
+        Collections.reverse(minorGCTime);
+        dataList.put(metricnameList.get(0), majorGCCount);
+        dataList.put(metricnameList.get(1), minorGCCount);
+        dataList.put(metricnameList.get(2), majorGCTime);
+        dataList.put(metricnameList.get(3), minorGCTime);
+        Collections.reverse(timeList);
+        metricsChartDataVO.setTimeList(timeList);
+        metricsChartDataVO.setMetricnameList(metricnameList);
+        metricsChartDataVO.setDataList(dataList);
+        metricsChartDataVO.setUnitList(unitList);
+      }
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    } catch (StatementExecutionException e) {
+      e.printStackTrace();
+    }
+    return metricsChartDataVO;
+  }
+
+  private QueryDataDo filterQueryData(
+      List<QueryDataVO> queryDataVOS,
+      Integer pageSize,
+      Integer pageNum,
+      String filterString,
+      Long startTime,
+      Long endTime,
+      Integer executionResult) {
+    List<QueryDataVO> filteredQueryDataVOS = new ArrayList<>();
+    filteredQueryDataVOS.addAll(queryDataVOS);
+    if (filterString != null) {
+      List<QueryDataVO> tempList = new ArrayList<>();
+      for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+        if (queryDataVO.getStatement().contains(filterString)) {
+          tempList.add(queryDataVO);
+        }
+      }
+      filteredQueryDataVOS.clear();
+      filteredQueryDataVOS.addAll(tempList);
+    }
+    if (startTime != -1) {
+      List<QueryDataVO> tempList = new ArrayList<>();
+      for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+        if (queryDataVO.getRunningTime() >= startTime) {
+          tempList.add(queryDataVO);
+        }
+      }
+      filteredQueryDataVOS.clear();
+      filteredQueryDataVOS.addAll(tempList);
+    }
+    if (endTime != -1) {
+      List<QueryDataVO> tempList = new ArrayList<>();
+      for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+        if (queryDataVO.getRunningTime() <= endTime) {
+          tempList.add(queryDataVO);
+        }
+      }
+      filteredQueryDataVOS.clear();
+      filteredQueryDataVOS.addAll(tempList);
+    }
+    if (executionResult != null) {
+      List<QueryDataVO> tempList = new ArrayList<>();
+      if (executionResult == 0) {
+        tempList.addAll(filteredQueryDataVOS);
+      } else {
+        for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+          if (queryDataVO.getExecutionResult().equals(executionResult)) {
+            tempList.add(queryDataVO);
+          }
+        }
+      }
+      filteredQueryDataVOS.clear();
+      filteredQueryDataVOS.addAll(tempList);
+    }
+
+    System.out.println(filteredQueryDataVOS.size());
+    int count = 0;
+    Long latestTimeStamp = 0L;
+    List<QueryDataVO> pageFilteredQueryDataVOS = new ArrayList<>();
+    for (QueryDataVO queryDataVO : filteredQueryDataVOS) {
+      count++;
+      if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+        pageFilteredQueryDataVOS.add(queryDataVO);
+      }
+      latestTimeStamp = Math.max(latestTimeStamp, queryDataVO.getRunningTime());
+    }
+
+    QueryDataDo queryDataDo = new QueryDataDo();
+    queryDataDo.setCount(count);
+    queryDataDo.setLatestTimeStamp(latestTimeStamp);
+    queryDataDo.setQueryDataVOs(pageFilteredQueryDataVOS);
+    return queryDataDo;
+  }
+
   private void grantOrRevoke(
       String grantOrRevoke,
       String userOrRole,
@@ -2342,20 +4077,17 @@ public class IotDBServiceImpl implements IotDBService {
       List<String> paths,
       SessionPool sessionPool)
       throws BaseException {
+    String sql = null;
+    String show_version = executeQueryOneValue(sessionPool, "show version");
+    if (show_version.contains("0.13") || show_version.contains("0.14")) {
+      sql = grantOrRevoke + " " + userOrRole + " " + name + " privileges " + privilege + " on ";
+    } else if (show_version.contains("0.12")) {
+      sql = grantOrRevoke + " " + userOrRole + " " + name + " privileges '" + privilege + "' on ";
+    }
     if (notNullAndNotZero(paths)) {
       for (String groupPath : paths) {
-        String sql =
-            grantOrRevoke
-                + " "
-                + userOrRole
-                + " "
-                + name
-                + " privileges '"
-                + privilege
-                + "' on "
-                + groupPath;
         try {
-          sessionPool.executeNonQueryStatement(sql);
+          sessionPool.executeNonQueryStatement(sql + groupPath);
         } catch (StatementExecutionException e) {
           logger.error(e.getMessage());
           if (e.getStatusCode() == 602) {
@@ -2504,7 +4236,7 @@ public class IotDBServiceImpl implements IotDBService {
           RowRecord rowRecord = sessionDataSetWrapper.next();
           if (timeFlag) {
             long timestamp = rowRecord.getTimestamp();
-            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
             Date date = new Date(timestamp);
             String timeStr = simpleDateFormat.format(date);
             strList.add(timeStr);
@@ -2746,9 +4478,9 @@ public class IotDBServiceImpl implements IotDBService {
         case "PLAIN":
           list.add(TSEncoding.PLAIN);
           break;
-        case "PLAIN_DICTIONARY":
-          list.add(TSEncoding.PLAIN_DICTIONARY);
-          break;
+          //        case "PLAIN_DICTIONARY":
+          //          list.add(TSEncoding.DICTIONARY);
+          //          break;
         case "RLE":
           list.add(TSEncoding.RLE);
           break;
@@ -2783,9 +4515,9 @@ public class IotDBServiceImpl implements IotDBService {
       case "PLAIN":
         tsEncoding = TSEncoding.PLAIN;
         break;
-      case "PLAIN_DICTIONARY":
-        tsEncoding = TSEncoding.PLAIN_DICTIONARY;
-        break;
+        //      case "PLAIN_DICTIONARY":
+        //        tsEncoding = TSEncoding.DICTIONARY;
+        //        break;
       case "RLE":
         tsEncoding = TSEncoding.RLE;
         break;
@@ -2966,4 +4698,25 @@ public class IotDBServiceImpl implements IotDBService {
       sessionDataSetWrapper.close();
     }
   }
+
+  private static String getNetFileSizeDescription(long size) {
+    StringBuffer bytes = new StringBuffer();
+    DecimalFormat format = new DecimalFormat("###.0");
+    double i = (size / (1024.0 * 1024.0));
+    bytes.append(format.format(i));
+    if (bytes.toString().equals(".0")) {
+      return "0.0";
+    }
+    return bytes.toString();
+  }
+
+  private static long getLongFromString(String timeStr) {
+    long count = Long.parseLong(timeStr.substring(timeStr.indexOf("E") + 1));
+    double time = Double.parseDouble(timeStr.substring(0, timeStr.indexOf("E")));
+    while (count > 0) {
+      time *= 10;
+      count--;
+    }
+    return (long) time;
+  }
 }
diff --git a/backend/src/main/resources/sqlite/iotdb.db b/backend/src/main/resources/sqlite/iotdb.db
index 9700849..26e0b25 100644
Binary files a/backend/src/main/resources/sqlite/iotdb.db and b/backend/src/main/resources/sqlite/iotdb.db differ


[iotdb-web-workbench] 11/34: Merge branch 'apache:master' into master

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit ce1cc5dbcca9f5da254926663ef3b8a94bf5df11
Merge: a046c45 fd390fd
Author: haungrui777 <hu...@163.com>
AuthorDate: Tue Sep 14 17:42:56 2021 +0800

    Merge branch 'apache:master' into master

 .github/workflows/default.yml                      |   55 +
 NOTICE                                             |    5 +-
 README.md                                          |    1 +
 README_zh.md                                       |   19 +-
 backend/.drone.yml                                 |   68 +
 backend/.gitignore                                 |   10 +
 backend/Dockerfile                                 |   24 +
 README.md => backend/README.md                     |   37 +-
 backend/build.gradle                               |   66 +
 backend/build.sh                                   |   20 +
 backend/doc/code-guidelines.zip                    |  Bin 0 -> 9427033 bytes
 README.md => backend/doc/config.md                 |   28 +-
 backend/doc/deploy.md                              |   65 +
 ...57\246\347\273\206\351\205\215\347\275\256.jpg" |  Bin 0 -> 286055 bytes
 .../doc/image/maven\351\205\215\347\275\256.jpg"   |  Bin 0 -> 96532 bytes
 ...05\215\347\275\256\346\226\207\344\273\266.png" |  Bin 0 -> 128969 bytes
 ...26\207\344\273\266\344\275\215\347\275\256.png" |  Bin 0 -> 60565 bytes
 backend/doc/image/pom.PNG                          |  Bin 0 -> 60121 bytes
 ...20\257\345\212\250\346\210\220\345\212\237.PNG" |  Bin 0 -> 153254 bytes
 "backend/doc/image/\346\211\223\345\214\205.png"   |  Bin 0 -> 22644 bytes
 ...05\215\347\275\256\346\226\207\344\273\266.PNG" |  Bin 0 -> 15910 bytes
 backend/doc/intro.md                               |   55 +
 README.md => backend/doc/log.md                    |   10 +-
 backend/doc/maven.md                               |   46 +
 backend/doc/note.md                                |   74 +
 README.md => backend/doc/promise.md                |    9 +-
 README.md => backend/doc/release.md                |    8 +-
 README.md => backend/doc/rest.md                   |   11 +-
 README.md => backend/doc/rule.md                   |   17 +-
 backend/doc/swagger.md                             |   51 +
 backend/doc/validate.md                            |   68 +
 backend/gradlew                                    |  188 ++
 backend/gradlew.bat                                |   89 +
 backend/pom.xml                                    |  267 +++
 backend/settings.gradle                            |   20 +
 .../org/apache/iotdb/admin/AdminApplication.java   |   36 +
 .../iotdb/admin/aop/BaseExceptionAdvice.java       |   42 +
 .../apache/iotdb/admin/aop/ParamValidAspect.java   |   72 +
 .../admin/common/exception/BaseException.java      |   41 +
 .../iotdb/admin/common/exception/ErrorCode.java    |  283 +++
 .../admin/common/utils/AuthenticationUtils.java    |   49 +
 .../apache/iotdb/admin/config/FilterConfig.java    |   44 +
 .../iotdb/admin/config/MybatisPlusConfig.java      |   48 +
 .../apache/iotdb/admin/config/SecurityConfig.java  |   48 +
 .../apache/iotdb/admin/config/SwaggerConfig.java   |   77 +
 .../iotdb/admin/config/ValidatorConfiguration.java |   43 +
 .../admin/controller/ConnectionController.java     |  128 ++
 .../iotdb/admin/controller/HealthController.java   |   46 +
 .../iotdb/admin/controller/IotDBController.java    |  915 +++++++++
 .../iotdb/admin/controller/QueryController.java    |  142 ++
 .../iotdb/admin/controller/UserController.java     |  125 ++
 .../java/org/apache/iotdb/admin/demo/JDBC.java     |  152 ++
 .../org/apache/iotdb/admin/demo/NativeAPI.java     |  113 ++
 .../org/apache/iotdb/admin/filter/TokenFilter.java |   60 +
 .../iotdb/admin/mapper/ConnectionMapper.java       |   28 +
 .../apache/iotdb/admin/mapper/DeviceMapper.java    |   28 +
 .../org/apache/iotdb/admin/mapper/GroupMapper.java |   28 +
 .../iotdb/admin/mapper/MeasurementMapper.java      |   28 +
 .../org/apache/iotdb/admin/mapper/QueryMapper.java |   28 +
 .../org/apache/iotdb/admin/mapper/UserMapper.java  |   28 +
 .../iotdb/admin/model/dto/ConnectionDTO.java       |   55 +
 .../org/apache/iotdb/admin/model/dto/CountDTO.java |   33 +
 .../apache/iotdb/admin/model/dto/DeviceDTO.java    |   36 +
 .../iotdb/admin/model/dto/DeviceInfoDTO.java       |   42 +
 .../org/apache/iotdb/admin/model/dto/GroupDTO.java |   40 +
 .../apache/iotdb/admin/model/dto/IotDBRole.java    |   36 +
 .../apache/iotdb/admin/model/dto/IotDBUser.java    |   44 +
 .../apache/iotdb/admin/model/dto/IotDBUserDTO.java |   31 +
 .../iotdb/admin/model/dto/MeasurementDTO.java      |   37 +
 .../iotdb/admin/model/dto/PrivilegeInfoDTO.java    |   40 +
 .../org/apache/iotdb/admin/model/dto/QueryDTO.java |   35 +
 .../apache/iotdb/admin/model/dto/SearchDTO.java    |   36 +
 .../apache/iotdb/admin/model/dto/Timeseries.java   |   39 +
 .../iotdb/admin/model/entity/Connection.java       |   68 +
 .../apache/iotdb/admin/model/entity/Device.java    |   55 +
 .../iotdb/admin/model/entity/Measurement.java      |   43 +
 .../org/apache/iotdb/admin/model/entity/Query.java |   43 +
 .../iotdb/admin/model/entity/StorageGroup.java     |   53 +
 .../org/apache/iotdb/admin/model/entity/User.java  |   49 +
 .../org/apache/iotdb/admin/model/vo/BaseVO.java    |   48 +
 .../org/apache/iotdb/admin/model/vo/ConnVO.java    |   36 +
 .../apache/iotdb/admin/model/vo/ConnectionVO.java  |   38 +
 .../apache/iotdb/admin/model/vo/DeviceInfo.java    |   34 +
 .../apache/iotdb/admin/model/vo/DeviceInfoVO.java  |   33 +
 .../org/apache/iotdb/admin/model/vo/DeviceVO.java  |   33 +
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |   36 +
 .../org/apache/iotdb/admin/model/vo/GroupVO.java   |   36 +
 .../apache/iotdb/admin/model/vo/IotDBUserVO.java   |   34 +
 .../apache/iotdb/admin/model/vo/MeasurementVO.java |   34 +
 .../iotdb/admin/model/vo/MeasuremtnInfoVO.java     |   33 +
 .../org/apache/iotdb/admin/model/vo/PathVO.java    |   32 +
 .../apache/iotdb/admin/model/vo/PrivilegeInfo.java |   39 +
 .../org/apache/iotdb/admin/model/vo/QueryVO.java   |   31 +
 .../org/apache/iotdb/admin/model/vo/RecordVO.java  |   33 +
 .../iotdb/admin/model/vo/RoleWithPrivilegesVO.java |   32 +
 .../apache/iotdb/admin/model/vo/SqlResultVO.java   |   35 +
 .../iotdb/admin/model/vo/StorageGroupVO.java       |   31 +
 .../iotdb/admin/service/ConnectionService.java     |   41 +
 .../apache/iotdb/admin/service/DeviceService.java  |   43 +
 .../apache/iotdb/admin/service/GroupService.java   |   44 +
 .../apache/iotdb/admin/service/IotDBService.java   |  107 ++
 .../iotdb/admin/service/MeasurementService.java    |   36 +
 .../apache/iotdb/admin/service/QueryService.java   |   39 +
 .../apache/iotdb/admin/service/UserService.java    |   32 +
 .../admin/service/impl/ConnectionServiceImpl.java  |  128 ++
 .../admin/service/impl/DeviceServiceImpl.java      |  146 ++
 .../iotdb/admin/service/impl/GroupServiceImpl.java |  163 ++
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 1967 ++++++++++++++++++++
 .../admin/service/impl/MeasurementServiceImpl.java |  150 ++
 .../iotdb/admin/service/impl/QueryServiceImpl.java |  108 ++
 .../iotdb/admin/service/impl/UserServiceImpl.java  |   81 +
 backend/src/main/resources/META-INF/app.properties |   20 +
 .../src/main/resources/application-dev.properties  |   30 +
 .../src/main/resources/application-prod.properties |   30 +
 .../src/main/resources/application-test.properties |   26 +
 backend/src/main/resources/application.properties  |   21 +
 backend/src/main/resources/log4j2-prod.xml         |  120 ++
 backend/src/main/resources/log4j2.xml              |  120 ++
 backend/src/main/resources/sqlite/iotdb.db         |  Bin 0 -> 36864 bytes
 .../test/java/org/apache/iotdb/admin/DemoJDBC.java |   38 +
 .../admin/controller/ConnectionControllerTest.java |  119 ++
 .../admin/controller/IotDBControllerTest.java      |  387 ++++
 .../admin/controller/QueryControllerTest.java      |  136 ++
 .../iotdb/admin/controller/TestSystemInfo.java     |   45 +
 124 files changed, 9538 insertions(+), 25 deletions(-)


[iotdb-web-workbench] 08/34: Add GH actions Support till version 13 Fixed all licensing for RAT Plugin Minor Update in Readme and License

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 63a507fcbb5456941ddce2c6807a54729fac667c
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 10:54:52 2021 +0200

    Add GH actions
    Support till version 13
    Fixed all licensing for RAT Plugin
    Minor Update in Readme and License
---
 .github/workflows/default.yml                      |   55 +
 NOTICE                                             |    5 +-
 README.md                                          |    1 +
 README_zh.md                                       |   19 +-
 backend/.drone.yml                                 |   68 +
 backend/Dockerfile                                 |   24 +
 README.md => backend/README.md                     |   37 +-
 backend/build.gradle                               |   66 +
 backend/build.sh                                   |   20 +
 README.md => backend/doc/config.md                 |   28 +-
 backend/doc/deploy.md                              |   65 +
 backend/doc/intro.md                               |   55 +
 README.md => backend/doc/log.md                    |   10 +-
 backend/doc/maven.md                               |   46 +
 backend/doc/note.md                                |   74 +
 README.md => backend/doc/promise.md                |    9 +-
 README.md => backend/doc/release.md                |    8 +-
 README.md => backend/doc/rest.md                   |   11 +-
 README.md => backend/doc/rule.md                   |   17 +-
 backend/doc/swagger.md                             |   51 +
 backend/doc/validate.md                            |   68 +
 backend/gradlew                                    |  188 ++
 backend/pom.xml                                    |  239 +++
 backend/settings.gradle                            |   20 +
 .../org/apache/iotdb/admin/AdminApplication.java   |   39 +
 .../iotdb/admin/aop/BaseExceptionAdvice.java       |   44 +
 .../apache/iotdb/admin/aop/ParamValidAspect.java   |   78 +
 .../admin/common/exception/BaseException.java      |   43 +
 .../iotdb/admin/common/exception/ErrorCode.java    |  286 +++
 .../admin/common/utils/AuthenticationUtils.java    |   49 +
 .../apache/iotdb/admin/config/FilterConfig.java    |   46 +
 .../iotdb/admin/config/MybatisPlusConfig.java      |   51 +
 .../apache/iotdb/admin/config/SecurityConfig.java  |   49 +
 .../apache/iotdb/admin/config/SwaggerConfig.java   |   79 +
 .../iotdb/admin/config/ValidatorConfiguration.java |   41 +
 .../admin/controller/ConnectionController.java     |  125 ++
 .../iotdb/admin/controller/HealthController.java   |   51 +
 .../iotdb/admin/controller/IotDBController.java    |  867 +++++++++
 .../iotdb/admin/controller/QueryController.java    |  133 ++
 .../iotdb/admin/controller/UserController.java     |  121 ++
 .../java/org/apache/iotdb/admin/demo/JDBC.java     |  159 ++
 .../org/apache/iotdb/admin/demo/NativeAPI.java     |  123 ++
 .../org/apache/iotdb/admin/filter/TokenFilter.java |   57 +
 .../iotdb/admin/mapper/ConnectionMapper.java       |   29 +
 .../apache/iotdb/admin/mapper/DeviceMapper.java    |   28 +
 .../org/apache/iotdb/admin/mapper/GroupMapper.java |   28 +
 .../iotdb/admin/mapper/MeasurementMapper.java      |   29 +
 .../org/apache/iotdb/admin/mapper/QueryMapper.java |   29 +
 .../org/apache/iotdb/admin/mapper/UserMapper.java  |   29 +
 .../iotdb/admin/model/dto/ConnectionDTO.java       |   53 +
 .../org/apache/iotdb/admin/model/dto/CountDTO.java |   33 +
 .../apache/iotdb/admin/model/dto/DeviceDTO.java    |   36 +
 .../iotdb/admin/model/dto/DeviceInfoDTO.java       |   41 +
 .../org/apache/iotdb/admin/model/dto/GroupDTO.java |   41 +
 .../apache/iotdb/admin/model/dto/IotDBRole.java    |   39 +
 .../apache/iotdb/admin/model/dto/IotDBUser.java    |   45 +
 .../apache/iotdb/admin/model/dto/IotDBUserDTO.java |   31 +
 .../iotdb/admin/model/dto/MeasurementDTO.java      |   37 +
 .../iotdb/admin/model/dto/PrivilegeInfoDTO.java    |   40 +
 .../org/apache/iotdb/admin/model/dto/QueryDTO.java |   35 +
 .../apache/iotdb/admin/model/dto/SearchDTO.java    |   36 +
 .../apache/iotdb/admin/model/dto/Timeseries.java   |   42 +
 .../iotdb/admin/model/entity/Connection.java       |   65 +
 .../apache/iotdb/admin/model/entity/Device.java    |   54 +
 .../iotdb/admin/model/entity/Measurement.java      |   43 +
 .../org/apache/iotdb/admin/model/entity/Query.java |   42 +
 .../iotdb/admin/model/entity/StorageGroup.java     |   54 +
 .../org/apache/iotdb/admin/model/entity/User.java  |   49 +
 .../org/apache/iotdb/admin/model/vo/BaseVO.java    |   58 +
 .../org/apache/iotdb/admin/model/vo/ConnVO.java    |   38 +
 .../apache/iotdb/admin/model/vo/ConnectionVO.java  |   40 +
 .../apache/iotdb/admin/model/vo/DeviceInfo.java    |   34 +
 .../apache/iotdb/admin/model/vo/DeviceInfoVO.java  |   33 +
 .../org/apache/iotdb/admin/model/vo/DeviceVO.java  |   33 +
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |   37 +
 .../org/apache/iotdb/admin/model/vo/GroupVO.java   |   36 +
 .../apache/iotdb/admin/model/vo/IotDBUserVO.java   |   34 +
 .../apache/iotdb/admin/model/vo/MeasurementVO.java |   34 +
 .../iotdb/admin/model/vo/MeasuremtnInfoVO.java     |   33 +
 .../org/apache/iotdb/admin/model/vo/PathVO.java    |   32 +
 .../apache/iotdb/admin/model/vo/PrivilegeInfo.java |   39 +
 .../org/apache/iotdb/admin/model/vo/QueryVO.java   |   31 +
 .../org/apache/iotdb/admin/model/vo/RecordVO.java  |   33 +
 .../iotdb/admin/model/vo/RoleWithPrivilegesVO.java |   34 +
 .../apache/iotdb/admin/model/vo/SqlResultVO.java   |   37 +
 .../iotdb/admin/model/vo/StorageGroupVO.java       |   31 +
 .../iotdb/admin/service/ConnectionService.java     |   41 +
 .../apache/iotdb/admin/service/DeviceService.java  |   43 +
 .../apache/iotdb/admin/service/GroupService.java   |   44 +
 .../apache/iotdb/admin/service/IotDBService.java   |   96 +
 .../iotdb/admin/service/MeasurementService.java    |   36 +
 .../apache/iotdb/admin/service/QueryService.java   |   39 +
 .../apache/iotdb/admin/service/UserService.java    |   32 +
 .../admin/service/impl/ConnectionServiceImpl.java  |  128 ++
 .../admin/service/impl/DeviceServiceImpl.java      |  144 ++
 .../iotdb/admin/service/impl/GroupServiceImpl.java |  157 ++
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 1857 ++++++++++++++++++++
 .../admin/service/impl/MeasurementServiceImpl.java |  142 ++
 .../iotdb/admin/service/impl/QueryServiceImpl.java |  109 ++
 .../iotdb/admin/service/impl/UserServiceImpl.java  |   85 +
 backend/src/main/resources/META-INF/app.properties |   20 +
 .../src/main/resources/application-dev.properties  |   30 +
 .../src/main/resources/application-prod.properties |   30 +
 .../src/main/resources/application-test.properties |   26 +
 backend/src/main/resources/application.properties  |   21 +
 backend/src/main/resources/log4j2-prod.xml         |  120 ++
 backend/src/main/resources/log4j2.xml              |  120 ++
 .../test/java/org/apache/iotdb/admin/DemoJDBC.java |   41 +
 .../admin/controller/ConnectionControllerTest.java |  118 ++
 .../admin/controller/IotDBControllerTest.java      |  380 ++++
 .../admin/controller/QueryControllerTest.java      |  134 ++
 .../iotdb/admin/controller/TestSystemInfo.java     |   47 +
 112 files changed, 9275 insertions(+), 25 deletions(-)

diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml
new file mode 100644
index 0000000..d0b7938
--- /dev/null
+++ b/.github/workflows/default.yml
@@ -0,0 +1,55 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Main Mac and Linux
+
+on:
+  push:
+    branches:
+      - master
+      - 'rel/*'
+      - Vector
+    paths-ignore:
+      - 'docs/**'
+  pull_request:
+    branches:
+      - master
+      - 'rel/*'
+      - cluster_new
+      - Vector
+    paths-ignore:
+      - 'docs/**'
+  # allow manually run the action:
+  workflow_dispatch:
+
+env:
+  MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3
+
+jobs:
+  unix:
+    strategy:
+      fail-fast: false
+      max-parallel: 20
+      matrix:
+        java: [ 8, 11, 13 ]
+        os: [ ubuntu-latest, macos-latest ]
+    runs-on: ${{ matrix.os}}
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up JDK ${{ matrix.java }}
+        uses: actions/setup-java@v1
+        with:
+          java-version: ${{ matrix.java }}
+      - name: Cache Maven packages
+        uses: actions/cache@v2
+        with:
+          path: ~/.m2
+          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+          restore-keys: ${{ runner.os }}-m2-
+      - name: Check Apache Rat
+        run: cd backend && mvn -B apache-rat:check -P site -P code-coverage
+      - name: IT/UT Test
+        shell: bash
+        # we do not compile client-cpp for saving time, it is tested in client.yml
+        run:  cd backend && mvn -B clean post-integration-test -Dtest.port.closed=true -P '!testcontainer'
diff --git a/NOTICE b/NOTICE
index e983e45..3b945c0 100644
--- a/NOTICE
+++ b/NOTICE
@@ -21,4 +21,7 @@ Apache Commons Collections
 Copyright 2001-2019 The Apache Software Foundation
 
 This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
+The Apache Software Foundation (http://www.apache.org/).
+
+============================================================================
+
diff --git a/README.md b/README.md
index 06ee6a0..adf58fc 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,7 @@
     under the License.
 
 -->
+
 [English](./README.md) | [中文](./README_ZH.md)
 
 # Overview
diff --git a/README_zh.md b/README_zh.md
index 06ee6a0..9f1cb6d 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -18,9 +18,22 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+[English](./README.md) | [中文](./README_zh.md)
+
+# IoTDB-Workbench
+
+IotDB-Workbench是IotDB的可视化管理工具,可对IotDB的数据进行增删改查、权限控制等,简化IotDB的使用及学习成本。
+在我们心中IotDB是最棒的时序数据库之一,我们将一直不遗余力地推动国产时序数据库IotDB的应用和发展,为本土开源能力的提高、开源生态的发展,贡献自己的力量,欢迎大家加入IotDB Admin的开发及维护,期待你的加入:
+
+![微信](backend/doc/image/wechat.png)
+
+## 后端服务运行
+
+[后端服务设计及运行说明](backend/README.md)
+
+## 前端服务运行
+
+[前端服务运行说明](frontend/README.md)
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
 
diff --git a/backend/.drone.yml b/backend/.drone.yml
new file mode 100644
index 0000000..9307f0d
--- /dev/null
+++ b/backend/.drone.yml
@@ -0,0 +1,68 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+---
+kind: pipeline
+name: deploy-testing-environment-preview.1.0
+git_image: hub.d.cisdigital.cn/drone/git
+platform:
+  os: linux
+  arch: amd64
+
+steps:
+  - name: tag
+    image: hub.segma.tech/drone/drone-tag:v1.1
+    environment:
+      TAG_FILE: .tags
+
+  - name: build
+    image: hub.segma.tech/drone/maven-plugin:3.6.1-jdk-8-alpine
+    commands:
+      - mvn clean package -D maven.test.skip=true
+
+  - name: docker
+    image: hub.segma.tech/drone/plugins/docker:19.03.8
+    environment:
+      PLUGIN_DEBUG: true
+    settings:
+      dockerfile: ./Dockerfile
+      username:
+        from_secret: docker_username
+      password:
+        from_secret: docker_password
+      repo: hub.d.cisdigital.cn/iot-dacoo/iotdb
+      registry: hub.d.cisdigital.cn
+      insecure: true
+
+  - name: deploy
+    image: hub.d.cisdigital.cn/drone/drone-paas-plugin:latest
+    settings:
+      application_id: 62
+      application_cluster: dev_paas
+      application_deployment_id: 725
+      application_deployment_replicas: 1
+      application_deployment_image: hub.d.cisdigital.cn/iot-dacoo/iotdb
+      server_url: http://drone-paas-server.kube-drone:8080
+      
+trigger:
+  branch:
+    - master
+    - dev
+  event:
+    - push
\ No newline at end of file
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100644
index 0000000..f6e39cc
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+FROM hub.segma.tech/library/java:8-jre-centos7-apollo
+
+COPY target/service-1.0.0.jar /app/app.jar
+
+ENTRYPOINT ["java", "-jar", "/app/app.jar"]
diff --git a/README.md b/backend/README.md
similarity index 58%
copy from README.md
copy to backend/README.md
index 06ee6a0..63d3d6e 100644
--- a/README.md
+++ b/backend/README.md
@@ -18,9 +18,40 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 后端服务设计及运行说明
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+[IoTDB-Workbench快速入门](doc/intro.md)
 
+## Building the Backend
+
+The backend can be built using maven by using
+
+```
+mvn clean install
+```
+
+## 开发环境搭建
+
+[Maven配置](doc/maven.md)
+
+[日志如何配置](doc/log.md)
+
+[接口文档配置](doc/swagger.md)
+
+[统一参数验证](doc/validate.md)
+
+[常用实践约定](doc/promise.md)
+
+[接口规范](doc/rest.md)
+
+[代码规范checkstyle](doc/rule.md)
+
+[代码规范和注释](doc/note.md)
+
+## 线上部署
+
+[项目部署](doc/deploy.md)
+
+## 发布日志
+[release-note](doc/release.md)
diff --git a/backend/build.gradle b/backend/build.gradle
new file mode 100644
index 0000000..8b92fc3
--- /dev/null
+++ b/backend/build.gradle
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+apply plugin: 'java'
+apply plugin: 'maven'
+
+group = 'cn.cisdigital.demo'
+version = '1.0.0'
+
+description = """demo项目"""
+
+sourceCompatibility = 1.5
+targetCompatibility = 1.5
+tasks.withType(JavaCompile) {
+	options.encoding = 'UTF-8'
+}
+
+
+
+repositories {
+        
+     maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+     maven { url "http://10.73.1.87:8088/nexus/content/groups/public/" }
+     maven { url "http://repo.maven.apache.org/maven2" }
+}
+dependencies {
+    compile(group: 'org.springframework.boot', name: 'spring-boot-starter-web', version:'2.3.3.RELEASE') {
+exclude(module: 'spring-boot-starter-logging')
+    }
+    compile(group: 'mysql', name: 'mysql-connector-java', version:'5.1.47') {
+exclude(module: 'protobuf-java')
+    }
+    compile group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2', version:'2.3.3.RELEASE'
+    compile group: 'org.projectlombok', name: 'lombok', version:'1.18.12'
+    compile group: 'com.alibaba', name: 'druid-spring-boot-starter', version:'1.1.17'
+    compile group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version:'3.4.0'
+    compile group: 'com.alibaba', name: 'fastjson', version:'1.2.73'
+    compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.11'
+    compile group: 'com.ctrip.framework.apollo', name: 'apollo-client', version:'1.2.0'
+    compile group: 'io.springfox', name: 'springfox-swagger2', version:'2.7.0'
+    compile group: 'io.springfox', name: 'springfox-swagger-ui', version:'2.7.0'
+    compile group: 'cn.cisdigital', name: 'exception-component', version:'1.0.0'
+    compile group: 'com.dianping.cat', name: 'cat-client', version:'3.0.0'
+    compile group: 'org.hibernate.validator', name: 'hibernate-validator', version:'6.0.9.Final'
+    compile group: 'org.aspectj', name: 'aspectjweaver', version:'1.9.6'
+    testCompile(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version:'2.3.3.RELEASE') {
+exclude(module: 'junit-vintage-engine')
+    }
+    testCompile group: 'junit', name: 'junit', version:'4.13'
+}
diff --git a/backend/build.sh b/backend/build.sh
new file mode 100755
index 0000000..40fdd9a
--- /dev/null
+++ b/backend/build.sh
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+#!/usr/bin/env bash
\ No newline at end of file
diff --git a/README.md b/backend/doc/config.md
similarity index 54%
copy from README.md
copy to backend/doc/config.md
index 06ee6a0..bd1b453 100644
--- a/README.md
+++ b/backend/doc/config.md
@@ -18,9 +18,31 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 配置中心 Apollo
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+##接入步骤
+1. 添加依赖 ,在pom.xml 中添加依赖,如不需要apolo,可以去掉该依赖
 
+```xml
+<dependency>
+  <groupId>com.ctrip.framework.apollo</groupId>
+  <artifactId>apollo-client</artifactId>
+  <version>1.2.0</version>
+</dependency>
+```
+
+版本号请使用1.2.0,服务器版本xxx
+
+2. 在application.properties文件中增加必要配置
+
+```properties
+    #配置中心服务地址
+    apollo.meta=http://192.168.1.241:8081
+    #开启配置中心
+    apollo.bootstrap.enabled=true
+    # 采用配置的形式注入命名空间application
+    apollo.bootstrap.namespaces=application
+```
+
+3. 编写读取配置的类。参考bean包下面的TestBean类。
diff --git a/backend/doc/deploy.md b/backend/doc/deploy.md
new file mode 100644
index 0000000..c608a17
--- /dev/null
+++ b/backend/doc/deploy.md
@@ -0,0 +1,65 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# 部署流程
+
+## 后端部署
+
+1 通过backend/src/main/resources/application-xxx.properties文件配置项目,注意修改数据源的路径。
+
+![](image/配置文件.PNG)
+
+2 打包
+
+![](image/打包.png)
+
+3 打包之后,将jar包上传到指定服务器并运行。  
+
+首先请确定服务器上安装了sqlite3(一般Linux系统自带sqlite3,如果没有请安装)。  
+通过如下命令将jar包挂载到后台运行:  
+nohup java -jar xxx.jar >/dev/null 2>&1 &
+
+至此后端部署完成。
+
+## 前端结合后端部署
+
+1 在服务器安装nginx服务器,命令如下:
+
+yum install -y nginx
+
+2 安装完成后,配置nginx的配置文件,可通过nginx -t 获取配置文件路径:
+
+![](image/nginx配置文件位置.png)
+
+3 vim xxx.conf编辑nginx配置
+
+配置信息如下:
+
+![](image/nginx配置文件.png)
+
+黄框内容为监听端口号配置;  
+红框内容以“/”映射前端资源文件,请指定为你的dist文件路径;  
+绿框以“/api”映射后台服务地址,与application-xxx.properties文件中配置的端口号和上下文根保持一致;  
+如果你需要多个服务则需配置多个server
+
+4 保存配置后,命令行输入nginx启动nginx
+
+浏览器调用服务器ip地址,端口号为黄框里指定的端口号,请求到服务器资源则部署成功。
diff --git a/backend/doc/intro.md b/backend/doc/intro.md
new file mode 100644
index 0000000..b57f038
--- /dev/null
+++ b/backend/doc/intro.md
@@ -0,0 +1,55 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# IoTDB-Workbench快速入门
+
+该项目IoTDB-Workbench,为IoTDB的可视化监控程序。
+
+## 支持的环境
+
+目前支持的开发环境如下:
+
+- Java 1.8
+- Maven 3.3.9 或以上
+- Gradle
+- 推荐IntelliJ IDEA 2017或以上
+
+## 目录结构说明
+
+- doc : 文档目录,一些帮助文档
+- src : 源码文件
+- Dockerfile : docker镜像打包文件
+- pom.xml : Maven Pom文件
+- README.md : 帮助文件目录
+
+## 使用的公用库
+
+由于是开源软件,使用的所有库都应该是maven公有仓库能找的,满足轻量、稳定2个特性。
+
+## 快速启动
+
+项目提供maven、gradle两种构建工具,以maven为例启动项目:  
+首先通过IntelliJ IDEA打开本项目,右键点击pom.xml,点击Add as Maven Project导入项目相关依赖。
+![](image/pom.PNG)  
+导入完成后启动AdminApplication项目,如果未报错并出现如下界面则代表项目运行成功。  
+![](image/启动成功.PNG)  
+本系统默认登录用户为root,密码为123456。  
+具体部署步骤请参考[部署文档](deploy.md)
\ No newline at end of file
diff --git a/README.md b/backend/doc/log.md
similarity index 61%
copy from README.md
copy to backend/doc/log.md
index 06ee6a0..536f83b 100644
--- a/README.md
+++ b/backend/doc/log.md
@@ -18,9 +18,13 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 日志配置
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+日志使用的是log4j,日志配置文件在src/main/resources/log4j2.xml中,log4j2.xml中默认路径写的是:
 
+<property name="log.home">/data/applogs/app-test</property>
+
+window系统请更改路径。
+
+默认我们已经配置好了日志,如果启动的时候报`ERROR Unable to create file /data/applogs/app/projectservicedemo_debug.log java.io.IOException: Could not create directory /data/applogs/app`的错误,那么可能你没有/data目录的权限,这时候你需要换一个目录。
diff --git a/backend/doc/maven.md b/backend/doc/maven.md
new file mode 100644
index 0000000..6b03b5a
--- /dev/null
+++ b/backend/doc/maven.md
@@ -0,0 +1,46 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# Maven 仓库配置
+
+本文介绍如何配置Maven仓库
+
+## Maven 安装
+
+无论你是mac电脑还是window电脑,都可以到Maven官网直接下载[Maven 3.8.2](https://dlcdn.apache.org/maven/maven-3/3.8.2/binaries/apache-maven-3.8.2-bin.tar.gz)
+
+然后找一个目录解压,路径最好不要有中文,然后在Idea中引用该Maven。在下图中找到"Maven Setting"
+
+![](image/maven配置.jpg)
+
+然后按照如下内容进行配置
+
+![](image/maven详细配置.jpg)
+
+## Maven 配置
+
+Maven也请使用jdk 1.8,在Idea的Build Tools->Maven->Runner中设置JRE为1.8。
+
+尝试执行右边的Maven Projects窗口中的Lifecycle中的compile命令,看是否编译成功,如失败可以添加`-X`参数,查看错误原因。
+
+如果出现编译错误:Error:java: 无效的目标发行版: 11
+
+请到 Build,Execution,Deployment->Compiler->Java Compiler设置 Per-module btyecode为1.8,默认可能为11。
diff --git a/backend/doc/note.md b/backend/doc/note.md
new file mode 100644
index 0000000..16f74b0
--- /dev/null
+++ b/backend/doc/note.md
@@ -0,0 +1,74 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# Controller格式
+
+```java
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.xxx;
+
+import org.apache.iotdb.xxx;
+import org.apache.iotdb.rpc.xxx;
+import org.apache.iotdb.service.rpc.xxx;
+
+import org.apache.thrift.xxx;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+```
+
+排列整齐 不同层级之间用空格分开
+
+## 注释
+
+注释使用英文注释
diff --git a/README.md b/backend/doc/promise.md
similarity index 79%
copy from README.md
copy to backend/doc/promise.md
index 06ee6a0..1f9c2ad 100644
--- a/README.md
+++ b/backend/doc/promise.md
@@ -18,9 +18,12 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 常用实践约定
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+本章讨论常用默认的IoTDB-Workbench约定
+
+## 理论约定
+
+1. 随着SpringBoot的流行,我们现在更多采用基于注解式的配置从而替换掉了基于XML的配置。
 
diff --git a/README.md b/backend/doc/release.md
similarity index 84%
copy from README.md
copy to backend/doc/release.md
index 06ee6a0..0e4c436 100644
--- a/README.md
+++ b/backend/doc/release.md
@@ -18,9 +18,11 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 发布日志
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+## 1.0.0
+
+1. xxx
+2. xxx
 
diff --git a/README.md b/backend/doc/rest.md
similarity index 79%
copy from README.md
copy to backend/doc/rest.md
index 06ee6a0..0b25e53 100644
--- a/README.md
+++ b/backend/doc/rest.md
@@ -18,9 +18,14 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 接口规范
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+有时候,会犯一些错误,例如直接会定义如下的一些接口:
 
+- /user/delete
+- /user/add
+- /user/update
+- /user/select
+
+这样的接口太数据库化,读起来虽然比较容易
diff --git a/README.md b/backend/doc/rule.md
similarity index 51%
copy from README.md
copy to backend/doc/rule.md
index 06ee6a0..31b6225 100644
--- a/README.md
+++ b/backend/doc/rule.md
@@ -18,9 +18,20 @@
     under the License.
 
 -->
-[English](./README.md) | [中文](./README_ZH.md)
 
-# Overview
+# 阿里巴巴java规范checkstyle
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+我们使用阿里巴巴java规范泰山版(1.6.0)
 
+需使用idea(版本2018.3+)安装插件,自动检查代码规范,具体操作步骤如下:
+
+1、Mac:IntelliJ IDEA -> Preferences -> Plugins -> Installed plugins from Disk -> 选择doc目录下的code-guidelines进行安装
+   Windows:File -> Settings -> Plugins -> Installed plugins from Disk -> 选择doc目录下的code-guidelines进行安装
+
+2、重启idea
+
+##在线安装java规范checkstyle
+1、Mac:IntelliJ IDEA -> Preferences -> Plugins -> Browse repositories -> 搜索Alibaba Java Coding Guidelines -> 直接install进行在线安装
+   Windows:File -> Settings -> Plugins -> Marketplace -> 搜索Alibaba Java Coding Guidelines -> 直接install进行在线安装
+
+2、重启idea
\ No newline at end of file
diff --git a/backend/doc/swagger.md b/backend/doc/swagger.md
new file mode 100644
index 0000000..37e9b0d
--- /dev/null
+++ b/backend/doc/swagger.md
@@ -0,0 +1,51 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# swagger的使用
+
+swagger在前后端联调开发中,启动非常重要的作用,如下:
+
+1. 保持接口和文档的一致性
+2. 使注释更为丰富
+
+
+
+1、框架依赖中已包含swagger接口组件。
+```xml
+<dependency>
+    <groupId>io.springfox</groupId>
+    <artifactId>springfox-swagger2</artifactId>
+    <version>2.7.0</version>
+</dependency>
+<dependency>
+    <groupId>io.springfox</groupId>
+    <artifactId>springfox-swagger-ui</artifactId>
+    <version>2.7.0</version>
+</dependency>
+```
+
+## 网页地址
+
+你可以通过http://localhost:8080/swagger-ui.html这个地址获得接口信息。
+
+## 生产环境、测试环境、开发环境配置
+
+在生产环境中需要把swagger去掉,请参考配置类Swagger2Config中的@Profile({"dev", "test"})注解。(当前配置表示加载在dev和test文件使用,只在开发环境和测试环境的时候加载该类)
\ No newline at end of file
diff --git a/backend/doc/validate.md b/backend/doc/validate.md
new file mode 100644
index 0000000..ceb0f5b
--- /dev/null
+++ b/backend/doc/validate.md
@@ -0,0 +1,68 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# 参数验证
+
+参数验证一般有很多种方法:
+
+1. 直接写在controller中,有时候,特别是新人,98%会忘记写参数验证
+2. 切面,注解形式的参数验证
+
+我们认为第2种方式会好于第一种方式,所以我们使用了成熟的hibernat验证框架对参数进行验证
+
+## hibernat参数验证配置
+
+在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码有几个麻烦:
+
+1. 验证代码繁琐,重复劳动
+2. 方法内代码显得冗长
+3. 每次要看哪些参数验证是否完整,需要去翻阅验证逻辑代码
+hibernate validator(官方文档)提供了一套比较完善、便捷的验证实现方式。
+
+spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依赖。
+
+## 校验框架的使用方式
+
+接入步骤:
+
+1、引入依赖
+
+```xml
+<dependency>
+    <groupId>org.hibernate.validator</groupId>
+    <artifactId>hibernate-validator</artifactId>
+    <version>6.0.9.Final</version>
+</dependency>
+```
+
+2、在需要校验的类上的属性上加上相关注解
+
+如DemoUser中name上加@NotNull和@Length注解
+
+3、进行aop配置,创建ParamValidAspect切面配置(可选)。
+
+
+## 注意事项:
+
+>如果不接入ParamValidAspect切面配置,校验框架会自动抛出Spring的参数校验的异常;如果使用了自定义切面配置,
+可以在doAround方法中对相关的参数校验做特殊的处理。本项目中对参数校验进行了统一的特殊处理(切面配置),返回与
+异常主见中的异常保持一致的错误状态码。建议以该项目的方式进行切面配置,从而遵循异常状态码规范。
+
diff --git a/backend/gradlew b/backend/gradlew
new file mode 100755
index 0000000..f4f9798
--- /dev/null
+++ b/backend/gradlew
@@ -0,0 +1,188 @@
+#!/usr/bin/env sh
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/backend/pom.xml b/backend/pom.xml
new file mode 100644
index 0000000..6413aba
--- /dev/null
+++ b/backend/pom.xml
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-parent</artifactId>
+    <version>2.3.3.RELEASE</version>
+    <relativePath/> <!-- lookup parent from repository -->
+  </parent>
+  <groupId>org.apache.iotdb.admin</groupId>
+  <artifactId>workbench</artifactId>
+  <version>1.0.0</version>
+  <packaging>jar</packaging>
+  <name>IoTDB Workbench</name>
+  <description>Apache IoTDB Workbench开源项目</description>
+
+  <properties>
+    <!-- 对应java 1.8,如果编译错误,可能需要调整 -->
+    <java.version>1.8</java.version>
+    <skipTests>true</skipTests>
+  </properties>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>org.springframework.boot</groupId>
+          <artifactId>spring-boot-starter-logging</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-log4j2</artifactId>
+    </dependency>
+
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-security</artifactId>
+    </dependency>
+
+    <!--sqlite驱动-->
+    <dependency>
+      <groupId>org.xerial</groupId>
+      <artifactId>sqlite-jdbc</artifactId>
+      <version>3.34.0</version>
+    </dependency>
+
+    <!--jwt-->
+    <dependency>
+      <groupId>com.auth0</groupId>
+      <artifactId>java-jwt</artifactId>
+      <version>3.4.0</version>
+    </dependency>
+
+    <!-- get set方法自动生成 -->
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <optional>true</optional>
+    </dependency>
+
+    <!-- mybatis-plus -->
+    <dependency>
+      <groupId>com.baomidou</groupId>
+      <artifactId>mybatis-plus-boot-starter</artifactId>
+      <version>3.4.0</version>
+    </dependency>
+    <!-- 数据库结束 -->
+
+    <!-- 常用工具库 -->
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>fastjson</artifactId>
+      <version>1.2.73</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <version>3.11</version>
+    </dependency>
+    <!-- 常用工具库结束 -->
+
+
+    <!-- spring单元测试 -->
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-test</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.junit.vintage</groupId>
+          <artifactId>junit-vintage-engine</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- spring单元测试结束 -->
+
+    <!-- swagger 组件,用于自动生成api接口文档 -->
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger2</artifactId>
+      <version>2.7.0</version>
+    </dependency>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger-ui</artifactId>
+      <version>2.7.0</version>
+    </dependency>
+    <!-- swagger 组件结束-->
+
+    <!-- 校验框架-->
+    <dependency>
+      <groupId>org.hibernate.validator</groupId>
+      <artifactId>hibernate-validator</artifactId>
+      <version>6.0.9.Final</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.aspectj</groupId>
+      <artifactId>aspectjweaver</artifactId>
+      <version>1.9.6</version>
+    </dependency>
+    <!-- 校验框架结束-->
+
+    <dependency>
+      <groupId>org.apache.iotdb</groupId>
+      <artifactId>iotdb-session</artifactId>
+      <version>0.12.0</version>
+      <exclusions>
+        <exclusion>
+          <artifactId>logback-classic</artifactId>
+          <groupId>ch.qos.logback</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.iotdb</groupId>
+      <artifactId>iotdb-jdbc</artifactId>
+      <version>0.12.0</version>
+      <exclusions>
+        <exclusion>
+          <artifactId>logback-classic</artifactId>
+          <groupId>ch.qos.logback</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+        <version>2.5.3</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>repackage</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <!--https://blog.csdn.net/eguid/article/details/78291497-->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.1</version>
+        <configuration>
+          <verbose>true</verbose>
+          <fork>true</fork>
+          <executable>${JAVA_HOME}/bin/javac</executable>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>license-check</id>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+    </plugins>
+
+  </build>
+
+  <repositories>
+    <repository>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+</project>
diff --git a/backend/settings.gradle b/backend/settings.gradle
new file mode 100644
index 0000000..c9e1192
--- /dev/null
+++ b/backend/settings.gradle
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+rootProject.name = 'service'
diff --git a/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java b/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
new file mode 100644
index 0000000..55adaf8
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+
+/**
+ * 后端代码启动类
+ * 1. MapperScan需要配置为mapper所在的包,自动扫描mapper,MapperScan是用于数据库组件自动扫描使用的。
+ */
+@SpringBootApplication
+@MapperScan("org.apache.iotdb.admin.mapper")
+@EnableWebSecurity
+public class AdminApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AdminApplication.class, args);
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java b/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
new file mode 100644
index 0000000..da38b49
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.vo.BaseVO;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * 通用异常处理拦截器
+ */
+@Slf4j
+@ControllerAdvice
+public class BaseExceptionAdvice {
+
+    @ExceptionHandler(BaseException.class)
+    @ResponseBody
+    public BaseVO handleBaseException(BaseException e) {
+        log.error("调用接口异常", e);
+        BaseVO result = new BaseVO(e.getErrorCode(), e.getMessage(), null);
+        return result;
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java b/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
new file mode 100644
index 0000000..5b9cb07
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Path;
+import javax.validation.Validator;
+import java.util.Set;
+
+/**
+ * 参数验证
+ */
+@Aspect
+@Slf4j
+@Component
+public class ParamValidAspect {
+
+    @Autowired
+    private Validator validator;
+
+
+    /**
+     * 定义校验包的未知
+     */
+    @Pointcut("execution(* org.apache.iotdb.admin.controller..*.*(..))")
+    public void pointcut() {
+    }
+
+    /**
+     * 处理参数校验错误的具体方法,抛出异常组件中的异常,遵循异常规范
+     */
+    @Around("pointcut()")
+    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+        Object[] args = pjp.getArgs();
+        for (Object arg : args) {
+            if (arg != null) {
+                Set<ConstraintViolation<Object>> constraintViolations = validator.validate(arg);
+                if (constraintViolations.size() > 0) {
+                    for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
+                        Path property = constraintViolation.getPropertyPath();
+                        String name = property.iterator().next().getName();
+                        //打印具体异常信息,对应校验框架注解中的message
+                        log.error("[" + name + "]" + constraintViolation.getMessage());
+                        throw new BaseException(ErrorCode.WRONG_PARAM, "参数错误:" + constraintViolation.getMessage());
+                    }
+                }
+            }
+        }
+        return pjp.proceed();
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
new file mode 100644
index 0000000..41eaa70
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.common.exception;
+
+/**
+ * 异常类
+ */
+public class BaseException extends Exception {
+
+    private String errorCode;
+    private String message;
+
+    public BaseException(String errorCode, String message) {
+        this.errorCode = errorCode;
+        this.message = message;
+    }
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
new file mode 100644
index 0000000..1fa47da
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.common.exception;
+
+/**
+ * 错误码类
+ */
+public class ErrorCode {
+
+    // 连接相关
+    public static final String ALIAS_REPEAT = "CONN-0001";
+    public static final String ALIAS_REPEAT_MSG = "别名重复";
+
+    public static final String INSERT_CONN_FAIL = "CONN-0002";
+    public static final String INSERT_CONN_FAIL_MSG = "添加或更新连接失败";
+
+    public static final String DELETE_CONN_FAIL = "CONN-0003";
+    public static final String DELETE_CONN_FAIL_MSG = "删除连接失败";
+
+    public static final String NO_CONN = "CONN-0004";
+    public static final String NO_CONN_MSG = "连接不存在";
+
+    public static final String GET_CONN_FAIL = "CONN-0005";
+    public static final String GET_CONN_FAIL_MSG = "获取连接失败";
+
+    public static final String CHECK_FAIL = "CONN-0006";
+    public static final String CHECK_FAIL_MSG = "没有权限或连接不存在";
+
+    public static final String TEST_CONN_FAIL = "CONN-0007";
+    public static final String TEST_CONN_FAIL_MSG = "连接不可达或连接超时";
+
+    public static final String TEST_CONN_WRONG = "CONN-0008";
+    public static final String TEST_CONN_WRONG_MSG = "连接失败,主机输入不合法";
+
+    public static final String TIME_OUT = "CONN-0009";
+    public static final String TIME_OUT_MSG = "连接超时";
+
+    public static final String TEST_CONN_FAIL_PWD = "CONN-0010";
+    public static final String TEST_CONN_FAIL_PWD_MSG = "连接失败,用户名或密码错误";
+
+    // 登录相关
+    public static final String LOGIN_FAIL_USER = "USER-0001";
+    public static final String LOGIN_FAIL_USER_MSG = "登录失败,用户不存在";
+
+    public static final String USER_EXIST = "USER-0002";
+    public static final String USER_EXIST_MSG = "用户已存在";
+
+    public static final String LOGIN_FAIL_PWD = "USER-0003";
+    public static final String LOGIN_FAIL_PWD_MSG = "登录失败,密码错误";
+
+    public static final String INSERT_USER_FAIL = "USER-0004";
+    public static final String INSERT_USER_FAIL_MSG = "插入失败";
+
+    public static final String WRONG_USER_PARAM = "USER-0005";
+    public static final String WRONG_USER_PARAM_MSG = "请输入合法的用户名和密码";
+
+    public static final String DELETE_USER_FAIL = "USER-0006";
+    public static final String DELETE_USER_FAIL_MSG = "删除用户失败";
+
+    public static final String NO_USER = "USER-0007";
+    public static final String NO_USER_MSG = "用户未指定";
+
+    public static final String USER_AUTH_FAIL = "USER-0008";
+    public static final String USER_AUTH_FAIL_MSG = "用户不一致,不能进行操作";
+
+    public static final String TOKEN_ERR = "USER-0009";
+    public static final String TOKEN_ERR_MSG = "请登录或token失效";
+
+    public static final String GET_TOKEN_FAIL = "USER-0010";
+    public static final String GET_TOKEN_FAIL_MSG = "获取token失败";
+
+    public static final String SET_JWT_FAIL = "USER-0011";
+    public static final String SET_JWT_FAIL_MSG = "JWT编解码失败";
+
+    // iotDB相关
+    public static final String INSERT_TS_FAIL = "IOTDB-0001";
+    public static final String INSERT_TS_FAIL_MSG = "插入时间序列失败";
+
+    public static final String DELETE_TS_FAIL = "IOTDB-0002";
+    public static final String DELETE_TS_FAIL_MSG = "删除时间序列失败";
+
+    public static final String DB_BOOL_WRONG = "IOTDB-0003";
+    public static final String DB_BOOL_WRONG_MSG = "Boolean值输入错误,0为false,1为true";
+
+    public static final String DB_DATATYPE_WRONG = "IOTDB-0004";
+    public static final String DB_DATATYPE_WRONG_MSG = "TSDataType类型传入错误";
+
+    public static final String GET_DBCONN_FAIL = "IOTDB-005";
+    public static final String GET_DBCONN_FAIL_MSG = "获取数据库连接失败";
+
+    public static final String GET_SESSION_FAIL = "IOTDB-0006";
+    public static final String GET_SESSION_FAIL_MSG = "获取session失败";
+
+    public static final String CLOSE_DBCONN_FAIL = "IOTDB-0007";
+    public static final String CLOSE_DBCONN_FAIL_MSG = "关闭连接失败";
+
+    public static final String SQL_EP = "IOTDB-0008";
+    public static final String SQL_EP_MSG = "没有权限或sql异常";
+
+    public static final String QUERY_FAIL = "IOTDB-0009";
+    public static final String QUERY_FAIL_MSG = "sql查询失败";
+
+    public static final String SQL_PARAM_WRONG = "IOTDB-0010";
+    public static final String SQL_PARAM_WRONG_MSG = "sql参数不合法";
+
+    public static final String WRONG_DB_PARAM = "IOTDB-0011";
+    public static final String WRONG_DB_PARAM_MSG = "输入参数不合法";
+
+    public static final String GET_USER_FAIL = "IOTDB-0012";
+    public static final String GET_USER_FAIL_MSG = "获取用户信息失败";
+
+    public static final String GET_SQL_ONE_VALUE_FAIL = "IOTDB-0013";
+    public static final String GET_SQL_ONE_VALUE_FAIL_MSG = "获取值失败";
+
+    public static final String SET_TTL_FAIL = "IOTDB-0014";
+    public static final String SET_TTL_FAIL_MSG = "设置存活时间失败";
+
+    public static final String DEL_TTL_FAIL = "IOTDB-0015";
+    public static final String DEL_TTL_FAIL_MSG = "删除存活时间失败";
+
+    public static final String GET_SQL_ONE_COLUMN_FAIL = "IOTDB-0016";
+    public static final String GET_SQL_ONE_COLUMN_FAIL_MSG = "获取列表失败";
+
+    public static final String GET_SQL_SET_FAIL = "IOTDB-0017";
+    public static final String GET_SQL_SET_FAIL_MSG = "获取列表集合失败";
+
+    public static final String INSERT_DEV_FAIL = "IOTDB-0018";
+    public static final String INSERT_DEV_FAIL_MSG = "插入实体失败";
+
+    public static final String GET_MSM_FAIL = "IOTDB-0019";
+    public static final String GET_MSM_FAIL_MSG = "获取物理量数据信息失败";
+
+    public static final String NO_SUCH_FIELD = "IOTDB-0020";
+    public static final String NO_SUCH_FIELD_MSG = "返回集没此属性";
+
+    public static final String GET_LAST_VALUE_FAIL = "IOTDB-0021";
+    public static final String GET_LAST_VALUE_FAIL_MSG = "获取物理量最新值失败";
+
+    public static final String SET_GROUP_FAIL = "IOTDB-0022";
+    public static final String SET_GROUP_FAIL_MSG = "创建存储组失败";
+
+    public static final String DELETE_GROUP_FAIL = "IOTDB-0023";
+    public static final String DELETE_GROUP_FAIL_MSG = "删除存储组失败";
+
+    public static final String DELETE_DB_USER_FAIL = "IOTDB-0024";
+    public static final String DELETE_DB_USER_FAIL_MSG = "删除数据库用户失败";
+
+    public static final String DELETE_DB_ROLE_FAIL = "IOTDB-0025";
+    public static final String DELETE_DB_ROLE_FAIL_MSG = "删除数据库角色失败";
+
+    public static final String SET_DB_USER_FAIL = "IOTDB-0026";
+    public static final String SET_DB_USER_FAIL_MSG = "创建数据库用户失败";
+
+    public static final String SET_DB_ROLE_FAIL = "IOTDB-0027";
+    public static final String SET_DB_ROLE_FAIL_MSG = "创建数据库角色或对应权限时失败";
+
+    public static final String NO_TYPE = "IOTDB-0028";
+    public static final String NO_TYPE_MSG = "粒度类型不存在";
+
+    public static final String PRIV_ROOT_FAIL = "IOTDB-0029";
+    public static final String PRIV_ROOT_FAIL_MSG = "根路径权限操作失败";
+
+    public static final String PRIV_GROUP_FAIL = "IOTDB-0030";
+    public static final String PRIV_GROUP_FAIL_MSG = "组路径权限操作失败";
+
+    public static final String PRIV_DEVICE_FAIL = "IOTDB-0031";
+    public static final String PRIV_DEVICE_FAIL_MSG = "实体路径权限操作失败";
+
+    public static final String PRIV_TIMESERIES_FAIL = "IOTDB-0032";
+    public static final String PRIV_TIMESERIES_FAIL_MSG = "物理量路径权限操作失败";
+
+    public static final String GET_RECORD_FAIL = "IOTDB-0033";
+    public static final String GET_RECORD_FAIL_MSG = "获取物理量记录失败";
+
+    public static final String NO_SQL = "IOTDB-0034";
+    public static final String NO_SQL_MSG = "没有sql执行语句";
+
+    public static final String UPDATE_GROUP_INFO_FAIL = "IOTDB-0035";
+    public static final String UPDATE_GROUP_INFO_FAIL_MSG = "更新组信息失败";
+
+    public static final String NO_GROUP_INFO = "IOTDB-0036";
+    public static final String NO_GROUP_INFO_MSG = "不存在存储组信息";
+
+    public static final String NO_GROUP = "IOTDB-0037";
+    public static final String NO_GROUP_MSG = "不存在存储组";
+
+    public static final String NO_DEVICE_INFO = "IOTDB-0038";
+    public static final String NO_DEVICE_INFO_MSG = "不存在设备信息";
+
+    public static final String UPDATE_PWD_FAIL = "IOTDB-0039";
+    public static final String UPDATE_PWD_FAIL_MSG = "修改账号密码失败";
+
+    public static final String NO_QUERY = "IOTDB-0040";
+    public static final String NO_QUERY_MSG = "不存在此查询";
+
+    public static final String NO_ALL_NUM_SEARCH = "IOTDB-0041";
+    public static final String NO_ALL_NUM_SEARCH_MSG = "不支持纯数字查询";
+
+    public static final String NO_PRI_SET_TTL = "IOTDB-0042";
+    public static final String NO_PRI_SET_TTL_MSG = "没有权限设置存活时间";
+
+    public static final String NO_PRI_CREATE_TIMESERIES = "IOTDB-0043";
+    public static final String NO_PRI_CREATE_TIMESERIES_MSG = "没有权限创建物理量";
+
+    public static final String NO_PRI_READ_TIMESERIES = "IOTDB-0044";
+    public static final String NO_PRI_READ_TIMESERIES_MSG = "没有权限查看物理量";
+
+    public static final String NO_PRI_DELETE_TIMESERIES = "IOTDB-0045";
+    public static final String NO_PRI_DELETE_TIMESERIES_MSG = "没有权限删除物理量";
+
+    public static final String CONN_REFUSED = "IOTDB-0046";
+    public static final String CONN_REFUSED_MSG = "连接错误,检查输入";
+
+    public static final String WRONG_USER = "IOTDB-0047";
+    public static final String WRONG_USER_MSG = "连接用户名或密码错误";
+
+    public static final String NO_PRI_SET_GROUP = "IOTDB-0048";
+    public static final String NO_PRI_SET_GROUP_MSG = "没有权限操作存储组";
+
+    public static final String NO_PRI_DELETE_GROUP = "IOTDB-0048";
+    public static final String NO_PRI_DELETE_GROUP_MSG = "没有权限删除存储组";
+
+    public static final String NO_SUPPORT_SQL = "IOTDB-0049";
+    public static final String NO_SUPPORT_SQL_MSG = "不支持此sql执行";
+
+    public static final String TTL_WRONG = "IOTDB-0050";
+    public static final String TTL_WRONG_MSG = "存活时间必须大于等于0";
+
+    public static final String NO_PRI_TIMESERIES_DATA = "IOTDB-0051";
+    public static final String NO_PRI_TIMESERIES_DATA_MSG = "没有权限查看测点数据";
+
+    public static final String NO_SUP_CONTAIN_ROOT = "IOTDB-0052";
+    public static final String NO_SUP_CONTAIN_ROOT_MSG = "不支持包含\"root\"的输入";
+
+    // 存储组表相关
+    public static final String INSERT_GROUP_INFO_FAIL = "GROUP-0001";
+    public static final String INSERT_GROUP_INFO_FAIL_MSG = "插入存储组信息失败";
+
+    public static final String DELETE_GROUP_INFO_FAIL = "GROUP-0002";
+    public static final String DELETE_GROUP_INFO_FAIL_MSG = "删除存储组信息失败";
+
+    // 实体表相关
+    public static final String DELETE_DEVICE_INFO_FAIL = "DEV-0001";
+    public static final String DELETE_DEVICE_INFO_FAIL_MSG = "删除实体信息失败";
+
+    public static final String SET_DEVICE_INFO_FAIL = "DEV-0002";
+    public static final String SET_DEVICE_INFO_FAIL_MSG = "插入实体信息失败";
+
+    // 物理量表相关
+    public static final String DELETE_MEASUREMENT_INFO_FAIL = "MEASU-0001";
+    public static final String DELETE_MEASUREMENT_INFO_FAIL_MSG = "删除物理量信息失败";
+
+    public static final String SET_MEASUREMENT_INFO_FAIL = "MEASU-0002";
+    public static final String SET_MEASUREMENT_INFO_FAIL_MSG = "插入物理量信息失败";
+
+    public static final String GET_MSM_DES_FAIL = "MEASU-0003";
+    public static final String GET_MSM_DES_FAIL_MSG = "获取物理量描述信息失败";
+
+    // 查询表相关
+    public static final String QUERY_EXIST = "QUERY-0001";
+    public static final String QUERY_EXIST_MSG = "脚本名已存在";
+
+    public static final String QUERY_NOT_EXIST = "QUERY-0002";
+    public static final String QUERY_NOT_EXIST_MSG = "脚本不存在";
+
+
+    // 参数校验相关
+    public static final String WRONG_PARAM = "PARAM-0001";
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java b/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
new file mode 100644
index 0000000..efe1f84
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.common.utils;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 校验工具类
+ */
+public class AuthenticationUtils {
+
+    public static void userAuthentication(Integer userId, HttpServletRequest request) throws BaseException {
+        if (userId == null) {
+            throw new BaseException(ErrorCode.NO_USER, ErrorCode.NO_USER_MSG);
+        }
+        DecodedJWT authorization = JWT.decode(request.getHeader("Authorization"));
+        Integer tokenUserId = authorization.getClaim("userId").asInt();
+        if (!tokenUserId.equals(userId)) {
+            throw new BaseException(ErrorCode.USER_AUTH_FAIL, ErrorCode.USER_AUTH_FAIL_MSG);
+        }
+    }
+
+    public static Integer getUserId(HttpServletRequest request) {
+        DecodedJWT authentication = JWT.decode(request.getHeader("Authorization"));
+        return authentication.getClaim("userId").asInt();
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
new file mode 100644
index 0000000..50dafeb
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.config;
+
+import org.apache.iotdb.admin.filter.TokenFilter;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 拦截器配置类
+ */
+@Component
+public class FilterConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new TokenFilter());
+        List<String> paths = new ArrayList();
+        paths.add("/servers/**");
+        paths.add("/get");
+        interceptorRegistration.addPathPatterns(paths);
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..becedc1
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 该类是Mybatis-Plus的配置类,mybatis以插件的形式来实现特定功能
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+    /**
+     * 分页插件配置,对相关数据库进行拦截并分页
+     *
+     * @return 分页拦截器
+     */
+    @Bean
+    public MybatisPlusInterceptor paginationInterceptor() {
+        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+        // 使用不同的数据库,可以更改DbType.MYSQL的类型
+        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
+        // 每页最多100条,可以更改,但不建议太大
+        paginationInnerInterceptor.setMaxLimit(100L);
+        interceptor.addInnerInterceptor(paginationInnerInterceptor);
+        return interceptor;
+    }
+
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
new file mode 100644
index 0000000..bf93858
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+
+/**
+ * 加密算法配置类 hash算法
+ */
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests()
+            .antMatchers("/**")
+            .permitAll()
+            .anyRequest()
+            .authenticated()
+            .and().csrf().disable();
+    }
+
+    @Bean
+    public BCryptPasswordEncoder bCryptPasswordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
new file mode 100644
index 0000000..45a0374
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * swagger配置类
+ */
+@Configuration
+@EnableSwagger2
+@Profile({"dev", "test"})
+public class SwaggerConfig {
+
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+            .apiInfo(apiinfo())
+            .enable(true)
+            .globalOperationParameters(jwtToken())
+            .select()
+            .apis(RequestHandlerSelectors.basePackage("org.apache.iotdb.admin.controller"))
+            .paths(PathSelectors.any())
+            .build();
+    }
+
+    private ApiInfo apiinfo() {
+        return new ApiInfoBuilder()
+            .title("IOTDB接口文档")
+            .description("iotDB层级关系 存储组 -> 实体(设备) -> 测点(时间序列)")
+            .build();
+    }
+
+    private List<Parameter> jwtToken() {
+
+        ParameterBuilder tokenPar = new ParameterBuilder();
+        List<Parameter> pars = new ArrayList<>();
+        tokenPar.name("Authorization")
+            .description("jwt令牌")
+            .modelRef(new ModelRef("string"))
+            .parameterType("header")
+            .required(false);
+        pars.add(tokenPar.build());
+        return pars;
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java b/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
new file mode 100644
index 0000000..ff63d55
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.config;
+
+import org.hibernate.validator.HibernateValidator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+/**
+ * 校验框架配置类
+ */
+@Configuration
+public class ValidatorConfiguration {
+
+    @Bean("validator")
+    public Validator getValidatorFactory() {
+        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory();
+        return validatorFactory.getValidator();
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
new file mode 100644
index 0000000..71dbdd3
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
+import org.apache.iotdb.admin.model.dto.ConnectionDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.BaseVO;
+import org.apache.iotdb.admin.model.vo.ConnVO;
+import org.apache.iotdb.admin.model.vo.ConnectionVO;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.apache.iotdb.session.Session;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.List;
+
+@RestController
+@Api(value = "连接相关接口")
+public class ConnectionController {
+
+    @Autowired
+    private ConnectionService connectionService;
+
+    @PostMapping("/servers")
+    @ApiOperation("保存或更新连接")
+    public BaseVO saveOrUpdateConnection(@RequestBody Connection connection, HttpServletRequest request) throws BaseException {
+        AuthenticationUtils.userAuthentication(connection.getUserId(), request);
+        if (connection.getId() != null) {
+            connectionService.update(connection);
+            return BaseVO.success("更新成功", null);
+        }
+        connectionService.insert(connection);
+
+        return BaseVO.success("保存成功", null);
+    }
+
+    @DeleteMapping("/servers/{serverId}")
+    @ApiOperation("删除连接")
+    public BaseVO deleteConnection(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+        Integer userId = AuthenticationUtils.getUserId(request);
+        connectionService.check(serverId, userId);
+        connectionService.deleteById(serverId, userId);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @GetMapping("/servers/{serverId}")
+    @ApiOperation("获取连接具体配置")
+    public BaseVO<Connection> getConnection(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+        Integer userId = AuthenticationUtils.getUserId(request);
+        connectionService.check(serverId, userId);
+        return BaseVO.success("获取成功", connectionService.getById(serverId));
+    }
+
+    @GetMapping("/servers")
+    @ApiOperation("获取所有连接")
+    public BaseVO<ConnectionVO> getAllConnections(@RequestParam("userId") Integer userId, HttpServletRequest request) throws BaseException {
+        AuthenticationUtils.userAuthentication(userId, request);
+        List<ConnVO> connVOs = connectionService.getAllConnections(userId);
+        ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, null);
+        return BaseVO.success("获取成功", connectionVO);
+    }
+
+    @PostMapping("/test")
+    @ApiOperation("连通性测试")
+    public BaseVO testConnection(@RequestBody ConnectionDTO conn) throws BaseException {
+        Socket socket = null;
+        try {
+            socket = new Socket();
+            socket.connect(new InetSocketAddress(conn.getHost(), conn.getPort()), 5000);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.TEST_CONN_FAIL, ErrorCode.TEST_CONN_FAIL_MSG);
+        } finally {
+            try {
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (Exception e) {
+                throw new BaseException(ErrorCode.TEST_CONN_FAIL, ErrorCode.TEST_CONN_FAIL_MSG);
+            }
+        }
+        Session session = null;
+        try {
+            session = new Session(conn.getHost(), conn.getPort(), conn.getUsername(), conn.getPassword());
+            session.open();
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
+        } finally {
+            try {
+                if (session != null) {
+                    session.close();
+                }
+            } catch (Exception e) {
+                throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
+            }
+        }
+        return BaseVO.success("连通成功", null);
+    }
+
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
new file mode 100644
index 0000000..62efb35
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * 运维平台通过存活、就绪探针表示应用是否存活,就绪。这个类大家最好不好删除,url地址也不要改变
+ */
+@Controller
+public class HealthController {
+
+    /**
+     * 存活探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示存活,
+     * 如果多次返回500,则表示这个程序已经死了,会重启这个程序。
+     */
+    @GetMapping(value = "/healthz/liveness")
+    public void liveness(HttpServletResponse response) throws IOException, BaseException {
+        response.setStatus(HttpServletResponse.SC_OK);
+    }
+
+    /**
+     * 就绪探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示程序已经可用,
+     * 如果多次返回500,则表示这个程序未启动成功,会重启这个程序。
+     */
+    @GetMapping(value = "/healthz/readiness")
+    public void readiness(HttpServletResponse response) throws IOException {
+        response.setStatus(HttpServletResponse.SC_OK);
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
new file mode 100644
index 0000000..8153022
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
@@ -0,0 +1,867 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
+import org.apache.iotdb.admin.model.dto.*;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.entity.Device;
+import org.apache.iotdb.admin.model.entity.StorageGroup;
+import org.apache.iotdb.admin.model.vo.*;
+import org.apache.iotdb.admin.service.*;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@Api(value = "iotdb操作相关接口")
+@RequestMapping("/servers/{serverId}")
+public class IotDBController {
+
+    @Autowired
+    private ConnectionService connectionService;
+
+    @Autowired
+    private IotDBService iotDBService;
+
+    @Autowired
+    private GroupService groupService;
+
+    @Autowired
+    private DeviceService deviceService;
+
+    @Autowired
+    private MeasurementService measurementService;
+
+
+    @GetMapping("/storageGroups/info")
+    @ApiOperation("获得存储组信息列表")
+    public BaseVO<List<GroupInfoVO>> getAllStorageGroupsInfo(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        List<String> groupNames = iotDBService.getAllStorageGroups(connection);
+        List<GroupInfoVO> groupInfoList = new ArrayList<>();
+        if (groupNames == null || groupNames.size() == 0) {
+            return BaseVO.success("获取成功", groupInfoList);
+        }
+        String host = connection.getHost();
+        List<Integer> deviceCounts = iotDBService.getDevicesCount(connection, groupNames);
+        List<String> descriptions = groupService.getGroupDescription(host, groupNames);
+        for (int i = 0; i < groupNames.size(); i++) {
+            GroupInfoVO groupInfoVO = new GroupInfoVO();
+            groupInfoVO.setGroupName(groupNames.get(i).replaceFirst("root.", ""));
+            groupInfoVO.setDeviceCount(deviceCounts.get(i));
+            groupInfoVO.setDescription(descriptions.get(i));
+            groupInfoList.add(groupInfoVO);
+        }
+        return BaseVO.success("获取成功", groupInfoList);
+    }
+
+    @GetMapping("/storageGroups")
+    @ApiOperation("获得存储组列表")
+    public BaseVO<List<StorageGroupVO>> getAllStorageGroups(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        List<StorageGroupVO> storageGroupVOList = new ArrayList<>();
+        List<String> groupNames = iotDBService.getAllStorageGroups(connection);
+        if (groupNames == null || groupNames.size() == 0) {
+            return BaseVO.success("获取成功", storageGroupVOList);
+        }
+        String host = connection.getHost();
+        for (String groupName : groupNames) {
+            StorageGroupVO storageGroupVO = new StorageGroupVO();
+            Integer id = groupService.getGroupId(host, groupName);
+            storageGroupVO.setGroupId(id);
+            groupName = groupName.replaceFirst("root.", "");
+            storageGroupVO.setGroupName(groupName);
+            storageGroupVOList.add(storageGroupVO);
+        }
+        return BaseVO.success("获取成功", storageGroupVOList);
+    }
+
+    @PostMapping("/storageGroups")
+    @ApiOperation("新增或修改存储组")
+    public BaseVO saveStorageGroup(@PathVariable("serverId") Integer serverId,
+        @RequestBody GroupDTO groupDTO,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        String groupName = groupDTO.getGroupName();
+        String checkName = groupName.toLowerCase();
+        if (checkName.contains("root")) {
+            throw new BaseException(ErrorCode.NO_SUP_CONTAIN_ROOT, ErrorCode.NO_SUP_CONTAIN_ROOT_MSG);
+        }
+        groupName = "root." + groupName;
+        Long ttl = groupDTO.getTtl();
+        String ttlUnit = groupDTO.getTtlUnit();
+        Integer groupId = groupDTO.getGroupId();
+        groupDTO.setGroupName(groupName);
+
+        List<String> groupNames = iotDBService.getAllStorageGroups(connection);
+        if (groupId == null) {
+            if (!groupNames.contains(groupDTO.getGroupName())) {
+                iotDBService.saveStorageGroup(connection, groupName);
+            }
+            groupService.setStorageGroupInfo(connection, groupDTO);
+        } else {
+            groupService.updateStorageGroupInfo(connection, groupDTO);
+        }
+        if (ttl != null && ttlUnit != null) {
+            if (ttl >= 0) {
+                Long times = switchTime(ttlUnit);
+                iotDBService.saveGroupTtl(connection, groupName, ttl * times);
+            } else {
+                throw new BaseException(ErrorCode.TTL_WRONG, ErrorCode.TTL_WRONG_MSG);
+            }
+        } else {
+            if (ttl == null && ttlUnit == null) {
+                iotDBService.cancelGroupTtl(connection, groupName);
+            } else {
+                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+            }
+        }
+        return BaseVO.success("新增或更新成功", null);
+    }
+
+    @DeleteMapping("/storageGroups/{groupName}")
+    @ApiOperation("删除存储组")
+    public BaseVO deleteStorageGroup(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        String host = connection.getHost();
+        iotDBService.deleteStorageGroup(connection, groupName);
+        groupService.deleteGroupInfo(host, groupName);
+        deviceService.deleteDeviceInfo(host, groupName);
+        measurementService.deleteMeasurementInfo(host, groupName);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @GetMapping("/storageGroups/{groupName}")
+    @ApiOperation("存储组详情获取")
+    public BaseVO<GroupVO> getStorageGroup(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        String host = connection.getHost();
+        StorageGroup group = groupService.getGroupInfo(host, groupName);
+        String ttl = iotDBService.getGroupTTL(connection, groupName);
+        String ttlUnit;
+        GroupVO groupVO = new GroupVO();
+        if (ttl != null && !"null".equalsIgnoreCase(ttl)) {
+            Long totalTime = Long.valueOf(ttl);
+            ttlUnit = getTTL(totalTime);
+            Long times = switchTime(ttlUnit);
+            ttl = String.valueOf(totalTime / times);
+            groupVO.setTtl(ttl);
+            groupVO.setTtiUnit(ttlUnit);
+        } else {
+            groupVO.setTtl(null);
+        }
+        if (group != null) {
+            groupVO.setCreator(group.getCreator());
+            groupVO.setDescription(group.getDescription());
+            Date date = new Date(group.getCreateTime());
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+            String createTime = simpleDateFormat.format(date);
+            groupVO.setCreateTime(createTime);
+        }
+        groupVO.setGroupName(groupName.replaceFirst("root.", ""));
+        groupVO.setAlias(connection.getAlias());
+        return BaseVO.success("获取成功", groupVO);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices/info")
+    @ApiOperation("获取指定存储组下的实体(设备)信息列表")
+    public BaseVO<DeviceInfoVO> getDevicesInfoByGroupName(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @RequestParam("pageSize") Integer pageSize,
+        @RequestParam("pageNum") Integer pageNum,
+        @RequestParam(value = "keyword", required = false) String keyword,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        if (pageSize == null || pageNum == null) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        CountDTO countDTO = iotDBService.getDevicesByGroup(connection, groupName, pageSize, pageNum, keyword);
+        List<String> deviceNames = countDTO.getObjects();
+        DeviceInfoVO deviceInfoVO = new DeviceInfoVO();
+        Integer totalPage = countDTO.getTotalPage();
+        Integer totalCount = countDTO.getTotalCount();
+        deviceInfoVO.setTotalCount(totalCount);
+        deviceInfoVO.setTotalPage(totalPage);
+        List<Integer> lines = iotDBService.getTimeseriesCount(connection, deviceNames);
+        List<Device> devices = deviceService.getDevices(connection.getHost(), deviceNames);
+        List<DeviceInfo> deviceInfos = new ArrayList<>();
+        if (deviceNames != null) {
+            for (int i = 0; i < deviceNames.size(); i++) {
+                String deviceName = deviceNames.get(i);
+                if (groupName.equals(deviceName)) {
+                    continue;
+                }
+                DeviceInfo deviceInfo = new DeviceInfo();
+                deviceInfo.setDeviceName(deviceName.replaceFirst(groupName + ".", ""));
+                deviceInfo.setLine(lines.get(i));
+                if (devices.get(i) != null) {
+                    deviceInfo.setDeviceId(devices.get(i).getId());
+                    deviceInfo.setCreator(devices.get(i).getCreator());
+                    deviceInfo.setDescription(devices.get(i).getDescription());
+                }
+                deviceInfos.add(deviceInfo);
+            }
+        }
+        deviceInfoVO.setDeviceInfos(deviceInfos);
+        return BaseVO.success("获取成功", deviceInfoVO);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices")
+    @ApiOperation("获取指定存储组下的实体(设备)列表")
+    public BaseVO<List<String>> getDevicesByGroupName(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        List<String> deviceNamesStr = iotDBService.getDevices(connection, groupName);
+        List<String> deviceNames = new ArrayList<>();
+        for (String s : deviceNamesStr) {
+            String deviceName;
+            if (groupName.equals(s)) {
+                continue;
+            } else {
+                deviceName = s.replaceFirst(groupName + ".", "");
+            }
+            deviceNames.add(deviceName);
+        }
+        return BaseVO.success("获取成功", deviceNames);
+    }
+
+    @PostMapping("/storageGroups/{groupName}/devices")
+    @ApiOperation("新增或编辑实体(设备)")
+    public BaseVO<List<String>> saveOrUpdateDevice(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @RequestBody DeviceInfoDTO deviceInfoDTO,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        if (deviceInfoDTO.getDeviceDTOList() == null || deviceInfoDTO.getDeviceDTOList().size() == 0) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceInfoDTO.setDeviceName(groupName + "." + deviceInfoDTO.getDeviceName());
+        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+            deviceDTO.setTimeseries(deviceInfoDTO.getDeviceName() + "." + deviceDTO.getTimeseries());
+        }
+        String host = connection.getHost();
+        iotDBService.createDeviceWithMeasurements(connection, deviceInfoDTO);
+        if (deviceInfoDTO.getDeviceId() == null) {
+            deviceService.setDeviceInfo(connection, deviceInfoDTO);
+            measurementService.setMeasurementsInfo(host, deviceInfoDTO);
+        } else {
+            deviceService.updateDeviceInfo(deviceInfoDTO);
+            measurementService.updateMeasurementsInfo(host, deviceInfoDTO);
+        }
+        return BaseVO.success("新增或更新成功", null);
+    }
+
+
+    @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}")
+    @ApiOperation("删除实体(设备)")
+    public BaseVO deleteDevice(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        String host = connection.getHost();
+        iotDBService.deleteTimeseriesByDevice(connection, deviceName);
+        deviceService.deleteDeviceInfoByDeviceName(host, deviceName);
+        measurementService.deleteMeasurementInfoByDeviceName(host, deviceName);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}")
+    @ApiOperation("获取实体(设备)详情")
+    public BaseVO<DeviceVO> getDeviceInfo(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        HttpServletRequest request) throws BaseException {
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        String host = connection.getHost();
+        DeviceVO deviceVO = deviceService.getDevice(host, deviceName);
+        return BaseVO.success("获取成功", deviceVO);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/info")
+    @ApiOperation("获取指定实体(设备)下的物理量列表详情")
+    public BaseVO<MeasuremtnInfoVO> getMeasurementsByDeviceName(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        @RequestParam("pageSize") Integer pageSize,
+        @RequestParam("pageNum") Integer pageNum,
+        @RequestParam(value = "keyword", required = false) String keyword,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        CountDTO countDTO = iotDBService.getMeasurementsByDevice(connection, deviceName, pageSize, pageNum, keyword);
+        List<MeasurementDTO> measurementDTOList = countDTO.getObjects();
+        List<MeasurementVO> measurementVOList = new ArrayList<>();
+        String host = connection.getHost();
+        if (measurementDTOList != null) {
+            for (MeasurementDTO measurementDTO : measurementDTOList) {
+                MeasurementVO measurementVO = new MeasurementVO();
+                BeanUtils.copyProperties(measurementDTO, measurementVO);
+                if (measurementVO.getTimeseries() != null) {
+                    measurementVO.setTimeseries(measurementVO.getTimeseries().replaceFirst(deviceName + ".", ""));
+                }
+                String description = measurementService.getDescription(host, measurementDTO.getTimeseries());
+                String newValue = iotDBService.getLastMeasurementValue(connection, measurementDTO.getTimeseries());
+                measurementVO.setNewValue(newValue);
+                measurementVO.setDescription(description);
+                measurementVOList.add(measurementVO);
+            }
+        }
+        MeasuremtnInfoVO measuremtnInfoVO = new MeasuremtnInfoVO();
+        measuremtnInfoVO.setTotalCount(countDTO.getTotalCount());
+        measuremtnInfoVO.setTotalPage(countDTO.getTotalPage());
+        measuremtnInfoVO.setMeasurementVOList(measurementVOList);
+        return BaseVO.success("获取成功", measuremtnInfoVO);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
+    @ApiOperation("获取指定物理量的最新两百条数据记录")
+    public BaseVO<RecordVO> getMeasurementInfo(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        @PathVariable("timeseriesName") String timeseriesName,
+        HttpServletRequest request) throws BaseException {
+        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        RecordVO recordVO = iotDBService.getRecords(connection, deviceName, timeseriesName);
+        return BaseVO.success("获取成功", recordVO);
+    }
+
+    @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
+    @ApiOperation("创建时间序列  (未使用)")
+    public BaseVO insertTimeseries(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        @RequestBody Timeseries timeseries,
+        HttpServletRequest request) throws BaseException {
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        iotDBService.insertTimeseries(connection, deviceName, timeseries);
+        return BaseVO.success("创建成功", null);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/info")
+    @ApiOperation("指定设备下的所有物理量  (未使用)")
+    public BaseVO<SqlResultVO> showTimeseries(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        HttpServletRequest request) throws BaseException {
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        SqlResultVO resultVO = iotDBService.showTimeseries(connection, deviceName);
+        return BaseVO.success("获取成功", resultVO);
+    }
+
+    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
+    @ApiOperation("指定设备下的物理量列表")
+    public BaseVO<List<String>> getTimeseries(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        HttpServletRequest request) throws BaseException {
+        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        List<String> timeseriesStr = iotDBService.getTimeseries(connection, deviceName);
+        List<String> timeseries = new ArrayList<>();
+        for (String s : timeseriesStr) {
+            timeseries.add(s.replaceFirst(deviceName + ".", ""));
+        }
+        return BaseVO.success("获取成功", timeseries);
+    }
+
+    @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
+    @ApiOperation("删除物理量")
+    public BaseVO deleteTimeseries(@PathVariable("serverId") Integer serverId,
+        @PathVariable("groupName") String groupName,
+        @PathVariable("deviceName") String deviceName,
+        @PathVariable("timeseriesName") String timeseriesName,
+        HttpServletRequest request) throws BaseException {
+        if (timeseriesName == null || !timeseriesName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        groupName = "root." + groupName;
+        deviceName = groupName + "." + deviceName;
+        timeseriesName = deviceName + "." + timeseriesName;
+        iotDBService.deleteTimeseries(connection, timeseriesName);
+        String host = connection.getHost();
+        measurementService.deleteMeasurementInfo(host, timeseriesName);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @GetMapping("/users")
+    @ApiOperation("获取数据库用户列表")
+    public BaseVO<List<String>> getIotDBUserList(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        List<String> users = iotDBService.getIotDBUserList(connection);
+        String username = connection.getUsername();
+        if (users == null) {
+            users = new ArrayList<>();
+            users.add(username);
+            return BaseVO.success("获取成功", users);
+        }
+        // 前端需要将当前用户处于列表第一位
+        List<String> newUsers = new ArrayList<>();
+        newUsers.add(username);
+        for (String user : users) {
+            if (username.equalsIgnoreCase(user)) {
+                continue;
+            }
+            newUsers.add(user);
+        }
+        return BaseVO.success("获取成功", newUsers);
+    }
+
+    @GetMapping("/roles")
+    @ApiOperation("获取数据库角色列表   (未使用)")
+    public BaseVO<List<String>> getIotDBRoleList(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        List<String> roles = iotDBService.getIotDBRoleList(connection);
+        return BaseVO.success("获取成功", roles);
+    }
+
+    @GetMapping("/users/{userName}")
+    @ApiOperation("获取数据源用户的具体信息或其他用户的权限信息")
+    public BaseVO<IotDBUserVO> getIotDBUser(@PathVariable("serverId") Integer serverId,
+        @PathVariable("userName") String userName,
+        HttpServletRequest request) throws BaseException {
+        if (userName == null || !userName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        IotDBUserVO iotDBUserVO = iotDBService.getIotDBUser(connection, userName);
+        return BaseVO.success("获取成功", iotDBUserVO);
+    }
+
+    @PostMapping("/users/{userName}")
+    @ApiOperation("数据库用户赋权")
+    public BaseVO setUserPrivileges(@PathVariable("serverId") Integer serverId,
+        @PathVariable("userName") String userName,
+        @RequestBody PrivilegeInfoDTO privilegeInfoDTO,
+        HttpServletRequest request) throws BaseException {
+        if (userName == null || !userName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        if (privilegeInfoDTO == null) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        Integer type = privilegeInfoDTO.getType();
+        if (type != null && (type > 3 || type < 0)) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+//        Integer delType = pathCheckAndGetDelType(privilegeInfoDTO);
+        pathCheck(privilegeInfoDTO);
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        iotDBService.setUserPrivileges(connection, userName, privilegeInfoDTO);
+        return BaseVO.success("操作成功", null);
+    }
+
+    private void pathCheck(PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
+        Integer type = privilegeInfoDTO.getType();
+        List<String> groupPaths = privilegeInfoDTO.getGroupPaths();
+        List<String> devicePaths = privilegeInfoDTO.getDevicePaths();
+        List<String> timeseriesPaths = privilegeInfoDTO.getTimeseriesPaths();
+        List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
+        List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
+        List<String> delTimeseriesPaths = privilegeInfoDTO.getDelTimeseriesPaths();
+        if (type == null) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        switch (type) {
+            case 0:
+                if (groupPaths != null && groupPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (devicePaths != null && devicePaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (delDevicePaths != null && delDevicePaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (delGroupPaths != null && delGroupPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                break;
+            case 1:
+                if (devicePaths != null && devicePaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (delDevicePaths != null && delDevicePaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                break;
+            case 2:
+                if (groupPaths != null && groupPaths.size() > 0) {
+                    if (groupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (devicePaths == null || devicePaths.size() == 0) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (devicePaths != null && devicePaths.size() > 0) {
+                    if (groupPaths == null || groupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                if (delGroupPaths != null && delGroupPaths.size() > 0) {
+                    if (delGroupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (delDevicePaths == null || delDevicePaths.size() == 0) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (delDevicePaths != null && delDevicePaths.size() > 0) {
+                    if (delGroupPaths == null || delGroupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                }
+                break;
+            case 3:
+                if (groupPaths != null && groupPaths.size() > 0) {
+                    if (groupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (devicePaths == null || devicePaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (timeseriesPaths == null || timeseriesPaths.size() == 0) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (devicePaths != null && devicePaths.size() > 0) {
+                    if (devicePaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (groupPaths == null || groupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (timeseriesPaths == null || timeseriesPaths.size() == 0) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+                    if (groupPaths == null || groupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (devicePaths == null || devicePaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (delGroupPaths != null && delGroupPaths.size() > 0) {
+                    if (delGroupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (delDevicePaths == null || delDevicePaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (delTimeseriesPaths == null || delTimeseriesPaths.size() == 0) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (delDevicePaths != null && delDevicePaths.size() > 0) {
+                    if (delDevicePaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (delGroupPaths == null || delGroupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (delTimeseriesPaths == null || delTimeseriesPaths.size() == 0) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+                    if (delGroupPaths == null || delGroupPaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                    if (delDevicePaths == null || delDevicePaths.size() != 1) {
+                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+                    }
+                }
+                break;
+            default:
+                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+//        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+//            if (delGroupPaths == null || delGroupPaths.size() != 1) {
+//                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+//            }
+//            if (delDevicePaths == null || delDevicePaths.size() != 1) {
+//                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+//            }
+//            return 3;
+//        }
+//        if (delDevicePaths != null && delDevicePaths.size() > 0) {
+//            if (delGroupPaths == null || delGroupPaths.size() != 1) {
+//                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+//            }
+//            return 2;
+//        }
+//        if (delGroupPaths != null && delGroupPaths.size() > 0) {
+//            return 1;
+//        }
+//        return 0;
+    }
+
+    @PostMapping("/users/pwd")
+    @ApiOperation("改变用户密码")
+    public BaseVO updatePassword(@PathVariable("serverId") Integer serverId,
+        @RequestBody IotDBUser iotDBUser,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        iotDBService.updatePwd(connection, iotDBUser);
+        return BaseVO.success("修改成功", null);
+    }
+
+    @DeleteMapping("/users/{userName}")
+    @ApiOperation("删除数据库用户")
+    public BaseVO deleteIotDBUser(@PathVariable("serverId") Integer serverId,
+        @PathVariable("userName") String userName,
+        HttpServletRequest request) throws BaseException {
+        if (userName == null || !userName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        iotDBService.deleteIotDBUser(connection, userName);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @DeleteMapping("/roles/{roleName}")
+    @ApiOperation("删除数据库角色  (未使用)")
+    public BaseVO deleteIotDBRole(@PathVariable("serverId") Integer serverId,
+        @PathVariable("roleName") String roleName,
+        HttpServletRequest request) throws BaseException {
+        if (roleName == null || roleName.matches("^[^ ]+$")) {
+            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        iotDBService.deleteIotDBRole(connection, roleName);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @PostMapping("/users")
+    @ApiOperation("创建数据库用户")
+    public BaseVO setIotDBUser(@PathVariable("serverId") Integer serverId,
+        @RequestBody IotDBUser iotDBUser,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        iotDBService.setIotDBUser(connection, iotDBUser);
+        return BaseVO.success("创建成功", null);
+    }
+
+    @PostMapping("/roles")
+    @ApiOperation("创建数据角色   (未使用)")
+    public BaseVO setIotDBUser(@PathVariable("serverId") Integer serverId,
+        @RequestBody IotDBRole iotDBRole,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        iotDBService.setIotDBRole(connection, iotDBRole);
+        return BaseVO.success("创建成功", null);
+    }
+
+    private void check(HttpServletRequest request, Integer serverId) throws BaseException {
+        Integer userId = AuthenticationUtils.getUserId(request);
+        connectionService.check(serverId, userId);
+    }
+
+
+    private Long switchTime(String ttlUnit) throws BaseException {
+        Long time = 0L;
+        switch (ttlUnit) {
+            case "second":
+                time = 1000L;
+                break;
+            case "minute":
+                time = 60 * 1000L;
+                break;
+            case "hour":
+                time = 60 * 60 * 1000L;
+                break;
+            case "day":
+                time = 24 * 60 * 60 * 1000L;
+                break;
+            case "week":
+                time = 7 * 24 * 60 * 60 * 1000L;
+                break;
+            case "month":
+                time = 30 * 24 * 60 * 60 * 1000L;
+                break;
+            case "year":
+                time = 12 * 30 * 24 * 60 * 60 * 1000L;
+                break;
+            default:
+                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        return time;
+    }
+
+    private String getTTL(Long time) {
+        long yearTime = 31104000000L;
+        long monthTime = 2592000000L;
+        long weekTime = 604800000L;
+        long dayTime = 86400000L;
+        long hourTime = 3600000L;
+        long minuteTime = 60000L;
+        long secondTime = 1000L;
+        if (time == 0) {
+            return "milliSecond";
+        }
+        if ((time / yearTime != 0) && (time % yearTime == 0)) {
+            return "year";
+        }
+        if ((time / monthTime != 0) && (time % monthTime == 0)) {
+            return "month";
+        }
+        if ((time / weekTime != 0) && (time % weekTime == 0)) {
+            return "week";
+        }
+        if ((time / dayTime != 0) && (time % dayTime == 0)) {
+            return "day";
+        }
+        if ((time / hourTime != 0) && (time % hourTime == 0)) {
+            return "hour";
+        }
+        if ((time / minuteTime != 0) && (time % minuteTime == 0)) {
+            return "minute";
+        }
+        if ((time / secondTime != 0) && (time % secondTime == 0)) {
+            return "second";
+        }
+        return null;
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
new file mode 100644
index 0000000..88ec329
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
+import org.apache.iotdb.admin.model.dto.SearchDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.entity.Query;
+import org.apache.iotdb.admin.model.vo.BaseVO;
+import org.apache.iotdb.admin.model.vo.QueryVO;
+import org.apache.iotdb.admin.model.vo.SqlResultVO;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.apache.iotdb.admin.service.IotDBService;
+import org.apache.iotdb.admin.service.QueryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+@RestController
+@Api(value = "查询相关接口")
+@RequestMapping("/servers/{serverId}")
+public class QueryController {
+
+    @Autowired
+    private ConnectionService connectionService;
+
+    @Autowired
+    private IotDBService iotDBService;
+
+    @Autowired
+    private QueryService queryService;
+
+    @PostMapping("/querySql")
+    @ApiOperation("用于查询器查询")
+    public BaseVO<List<SqlResultVO>> query(@PathVariable("serverId") Integer serverId,
+        @RequestBody SearchDTO searchDTO,
+        HttpServletRequest request) throws BaseException {
+        List<String> sqls = searchDTO.getSqls();
+        if (sqls == null || sqls.size() == 0) {
+            throw new BaseException(ErrorCode.NO_SQL, ErrorCode.NO_SQL_MSG);
+        }
+        check(request, serverId);
+        Connection connection = connectionService.getById(serverId);
+        Long timestamp = searchDTO.getTimestamp();
+        List<SqlResultVO> sqlResultVOList = iotDBService.queryAll(connection, sqls, timestamp);
+        return BaseVO.success("查询成功", sqlResultVOList);
+    }
+
+    @PostMapping("/query")
+    @ApiOperation("用于查询脚本保存或编辑")
+    public BaseVO saveQuery(@PathVariable("serverId") Integer serverId,
+        @RequestBody Query query,
+        HttpServletRequest request) throws BaseException {
+        String sqls = query.getSqls();
+        if (sqls == null || "".equals(sqls)) {
+            throw new BaseException(ErrorCode.NO_SQL, ErrorCode.NO_SQL_MSG);
+        }
+        check(request, serverId);
+        if (query.getId() != null) {
+            queryService.update(serverId, query);
+            return BaseVO.success("更新成功", null);
+        }
+        queryService.save(serverId, query);
+        return BaseVO.success("保存成功", null);
+    }
+
+    @GetMapping("/query")
+    @ApiOperation("获取脚本列表")
+    public BaseVO<List<QueryVO>> getQueries(@PathVariable("serverId") Integer serverId,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        List<QueryVO> queryVOList = queryService.getQueryList(serverId);
+        return BaseVO.success("获取成功", queryVOList);
+    }
+
+    @DeleteMapping("/query/{queryId}")
+    @ApiOperation("删除脚本")
+    public BaseVO deleteQuery(@PathVariable("serverId") Integer serverId,
+        @PathVariable("queryId") Integer queryId,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        queryService.deleteQuery(queryId);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @GetMapping("/query/{queryId}")
+    @ApiOperation("获取指定脚本")
+    public BaseVO<Query> getQuery(@PathVariable("serverId") Integer serverId,
+        @PathVariable("queryId") Integer queryId,
+        HttpServletRequest request) throws BaseException {
+        check(request, serverId);
+        Query query = queryService.getQuery(queryId);
+        return BaseVO.success("获取成功", query);
+    }
+
+    @GetMapping("/stop")
+    @ApiOperation("用于查询终止")
+    public BaseVO query(@PathVariable("serverId") Integer serverId, @RequestParam("timestamp") Long timestamp, HttpServletRequest request)
+        throws BaseException {
+        check(request, serverId);
+        iotDBService.stopQuery(serverId, timestamp);
+        return BaseVO.success("停止成功", null);
+    }
+
+    public void check(HttpServletRequest request, Integer serverId) throws BaseException {
+        Integer userId = AuthenticationUtils.getUserId(request);
+        connectionService.check(serverId, userId);
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
new file mode 100644
index 0000000..8fbbc3d
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
+import org.apache.iotdb.admin.model.entity.User;
+import org.apache.iotdb.admin.model.vo.BaseVO;
+import org.apache.iotdb.admin.model.vo.ConnVO;
+import org.apache.iotdb.admin.model.vo.ConnectionVO;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.apache.iotdb.admin.service.UserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.InetAddress;
+import java.util.Calendar;
+import java.util.List;
+
+@RestController
+@Api(value = "登录相关接口")
+public class UserController {
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private ConnectionService connectionService;
+
+    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
+
+    @PostMapping("/login")
+    @ApiOperation("登录")
+    public BaseVO<ConnectionVO> login(@RequestParam("name") String name, @RequestParam("password") String password, HttpServletResponse response)
+        throws BaseException {
+        if (name == null || password == null || name.length() < 4 || password.length() < 4) {
+            throw new BaseException(ErrorCode.WRONG_USER_PARAM, ErrorCode.WRONG_USER_PARAM_MSG);
+        }
+        User user = userService.login(name, password);
+        int userId = user.getId();
+        List<ConnVO> connVOs = connectionService.getAllConnections(userId);
+        ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, name);
+        response.addHeader("Authorization", getToken(user));
+        return BaseVO.success("登录成功", connectionVO);
+    }
+
+    @PostMapping("/save")
+    @ApiOperation("创建用户  (未使用)")
+    public BaseVO save(@RequestBody User user) throws BaseException {
+        userService.insert(user);
+        return BaseVO.success("保存成功", null);
+    }
+
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除用户  (未使用)")
+    public BaseVO delete(@RequestParam("userId") Integer userId, HttpServletRequest request) throws BaseException {
+        AuthenticationUtils.userAuthentication(userId, request);
+        userService.delete(userId);
+        return BaseVO.success("删除成功", null);
+    }
+
+    @GetMapping("/get")
+    @ApiOperation("二次登录获取用户信息")
+    public BaseVO<User> getUser(HttpServletRequest request) {
+        String authorization = request.getHeader("Authorization");
+        DecodedJWT decode = JWT.decode(authorization);
+        User user = new User();
+        if (decode != null) {
+            Integer userId = decode.getClaim("userId").asInt();
+            String name = decode.getClaim("name").asString();
+            user.setId(userId);
+            user.setName(name);
+        }
+        return BaseVO.success("获取成功", user);
+    }
+
+    private String getToken(User user) throws BaseException {
+        Calendar instance = Calendar.getInstance();
+        try {
+            instance.add(Calendar.HOUR, 24);
+            String token = JWT.create()
+                .withClaim("userId", user.getId())
+                .withClaim("name", user.getName())
+                .withExpiresAt(instance.getTime())
+                .sign(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()));
+            logger.info(user.getName() + "登录成功");
+            return token;
+        } catch (Exception e) {
+            logger.info(e.getMessage());
+            throw new BaseException(ErrorCode.GET_TOKEN_FAIL, ErrorCode.GET_TOKEN_FAIL_MSG);
+        }
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java b/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
new file mode 100644
index 0000000..3cb100a
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.demo;
+
+
+import java.sql.*;
+
+/**
+ * JDBC demo代码
+ */
+public class JDBC {
+
+    public static void main(String[] args) throws SQLException {
+        Connection connection = getConnection();
+        if (connection == null) {
+            System.out.println("get connection defeat");
+            return;
+        }
+        Statement statement = connection.createStatement();
+        //创建存储组
+        try {
+            statement.execute("SET STORAGE GROUP TO root.demo");
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+        //展示存储组
+        statement.execute("SHOW STORAGE GROUP");
+        outputResult(statement.getResultSet());
+        //创建时间序列
+        //不同的数据类型有不同的编码方式. 这里以INT32作为例子
+        try {
+            statement.execute("CREATE TIMESERIES root.demo.s0 WITH DATATYPE=INT32,ENCODING=RLE;");
+        } catch (SQLException e) {
+            System.out.println(e.getMessage());
+        }
+        //展示时间序列
+        statement.execute("SHOW TIMESERIES root.demo");
+        outputResult(statement.getResultSet());
+        //展示设备
+        statement.execute("SHOW DEVICES");
+        outputResult(statement.getResultSet());
+        //计算时间序列个数
+        statement.execute("COUNT TIMESERIES root");
+        outputResult(statement.getResultSet());
+        //计算给定级别的nodes个数
+        statement.execute("COUNT NODES root LEVEL=3");
+        outputResult(statement.getResultSet());
+        //计算时间序列以级别3分组的个数
+        statement.execute("COUNT TIMESERIES root GROUP BY LEVEL=3");
+        outputResult(statement.getResultSet());
+
+        //批量执行插入语句
+        statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
+        statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
+        statement.addBatch("insert into root.demo(timestamp,s0) values(2,15);");
+        statement.addBatch("insert into root.demo(timestamp,s0) values(2,17);");
+        statement.addBatch("insert into root.demo(timestamp,s0) values(4,12);");
+        statement.executeBatch();
+        statement.clearBatch();
+
+        //查询语句
+        String sql = "select * from root.demo";
+        ResultSet resultSet = statement.executeQuery(sql);
+        System.out.println("sql: " + sql);
+        outputResult(resultSet);
+
+        //精确的查询语句
+        sql = "select s0 from root.demo where time = 4;";
+        resultSet = statement.executeQuery(sql);
+        System.out.println("sql: " + sql);
+        outputResult(resultSet);
+
+        //时间范围查询
+        sql = "select s0 from root.demo where time >= 2 and time < 5;";
+        resultSet = statement.executeQuery(sql);
+        System.out.println("sql: " + sql);
+        outputResult(resultSet);
+
+        //聚合查询
+        sql = "select count(s0) from root.demo;";
+        resultSet = statement.executeQuery(sql);
+        System.out.println("sql: " + sql);
+        outputResult(resultSet);
+
+        //删除时间序列
+        statement.execute("delete timeseries root.demo.s0");
+
+        //关闭连接
+        statement.close();
+        connection.close();
+    }
+
+
+    public static Connection getConnection() {
+        // JDBC driver name and database URL
+        String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
+        String url = "jdbc:iotdb://127.0.0.1:6667/";
+
+        // Database credentials
+        String username = "root";
+        String password = "root";
+
+        Connection connection = null;
+        try {
+            Class.forName(driver);
+            connection = DriverManager.getConnection(url, username, password);
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+        return connection;
+    }
+
+
+    /**
+     * This is an example of outputting the results in the ResultSet
+     */
+    private static void outputResult(ResultSet resultSet) throws SQLException {
+        if (resultSet != null) {
+            System.out.println("--------------------------");
+            final ResultSetMetaData metaData = resultSet.getMetaData();
+            final int columnCount = metaData.getColumnCount();
+            for (int i = 0; i < columnCount; i++) {
+                System.out.print(metaData.getColumnLabel(i + 1) + " ");
+            }
+            System.out.println();
+            while (resultSet.next()) {
+                for (int i = 1; ; i++) {
+                    System.out.print(resultSet.getString(i));
+                    if (i < columnCount) {
+                        System.out.print(", ");
+                    } else {
+                        System.out.println();
+                        break;
+                    }
+                }
+            }
+            System.out.println("--------------------------\n");
+        }
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java b/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
new file mode 100644
index 0000000..11259c1
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.demo;
+
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.StatementExecutionException;
+import org.apache.iotdb.session.Session;
+import org.apache.iotdb.session.SessionDataSet;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.read.common.Field;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 原生api demo代码
+ */
+public class NativeAPI {
+
+    public static void main(String[] args) throws IoTDBConnectionException, StatementExecutionException {
+        //建立连接
+        Session session = new Session("localhost", 6667, "root", "root");
+        session.open();
+//        SessionPool sessionPool = new SessionPool("localhost", 6667,"root","root",3);
+//        sessionPool.insertRecord();
+        //创建存储组
+        session.setStorageGroup("root.fyx");
+        //创建时间序列
+        /**
+         *   path:层级路径
+         *  TSDataType数据类型:六种                 支持编码方式
+         *          boolean              PLAIN,RLE
+         *          int32                PLAIN,RLE,TS_2DIFF,GORILLA
+         *          int64                PLAIN,RLE,TS_2DIFF,GORILLA
+         *          float                PLAIN,RLE,TS_2DIFF,GORILLA
+         *          double               PLAIN,RLE,TS_2DIFF,GORILLA
+         *          text(字符串)         PLAIN
+         *
+         *  TSEncoding编码方式:
+         *        PLAIN编码:不编码 压缩效率高 空间存储效率低
+         *       二阶差分编码(TS_2DIFF):适合单调序列数据 不适合编码波动较大的数据
+         *       游程编码(RLE):比较适合整数值连续出现的序列
+         *       GORILLA编码:无损编码,它比较适合编码前后值比较接近的数值序列
+         *       定频数据编码(REGULAR):仅适用于整型 允许数据缺失
+         *
+         *  CompressionType压缩方式:
+         *        UMCOMPRESSED
+         *        SNAPPY
+         *        LZ4
+         *        GZIP
+         *        SDT
+         *        PAA
+         *        PLA
+         */
+        session.createTimeseries("root.fyx.cq.dev.temp", TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY, null, null, null, null);
+        //创建多个时间序列
+//        session.createMultiTimeseries();
+        //插入数据
+        List<String> measurements = new ArrayList<>();
+        List<TSDataType> types = new ArrayList<>();
+        measurements.add("temp");
+        types.add(TSDataType.FLOAT);
+        for (long time = 0; time < 10; time++) {
+            List<Object> values = new ArrayList<>();
+            values.add(time * 6.6f);
+            //如果不加type,服务器会做类型推断,会有额外耗时
+            session.insertRecord("root.fyx.cq.dev", time, measurements, types, values);
+        }
+        //执行非查询语句的sql
+        session.executeNonQueryStatement("insert into root.fyx.cq.dev(timestamp,temp) values(now(),66.66)");
+        //执行查询语句的sql
+        SessionDataSet sessionDataSet = session.executeQueryStatement("select * from root.fyx.cq.dev");
+        //数据处理
+        int fetchSize = sessionDataSet.getFetchSize();
+        List<String> columnNames = sessionDataSet.getColumnNames();
+        List<TSDataType> columnTypes = sessionDataSet.getColumnTypes();
+        System.out.println(columnNames);
+        System.out.println(columnTypes);
+        if (fetchSize > 0) {
+            while (sessionDataSet.hasNext()) {
+                RowRecord next = sessionDataSet.next();
+                List<Field> fields = next.getFields();
+                // 查询结果第一个为时间戳
+                long timestamp = next.getTimestamp();
+                System.out.print(timestamp + "\t");
+                for (int i = 0; i < fields.size(); i++) {
+                    Field field = fields.get(i);
+                    // 这里的需要按照类型获取
+                    System.out.print(field.getObjectValue(field.getDataType()));
+                }
+                System.out.println();
+            }
+        }
+        sessionDataSet.closeOperationHandle();
+        //删除时间序列
+        session.deleteTimeseries("root.fyx.cq.dev.temp");
+        //删除存储组
+        session.deleteStorageGroup("root.fyx");
+        session.close();
+    }
+
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java b/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
new file mode 100644
index 0000000..59be4fa
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.filter;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 拦截器
+ */
+public class TokenFilter implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws BaseException {
+        JWTVerifier jwtVerifier;
+        try {
+            jwtVerifier = JWT.require(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress())).build();
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+            throw new BaseException(ErrorCode.SET_JWT_FAIL, ErrorCode.SET_JWT_FAIL_MSG);
+        }
+        try {
+            String authorization = request.getHeader("Authorization");
+            jwtVerifier.verify(authorization);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new BaseException(ErrorCode.TOKEN_ERR, ErrorCode.TOKEN_ERR_MSG);
+        }
+        return true;
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java
new file mode 100644
index 0000000..a9db0bb
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.springframework.stereotype.Component;
+
+@Component
+public interface ConnectionMapper extends BaseMapper<Connection> {
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java
new file mode 100644
index 0000000..b870411
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.iotdb.admin.model.entity.Device;
+import org.springframework.stereotype.Component;
+
+@Component
+public interface DeviceMapper extends BaseMapper<Device> {
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java
new file mode 100644
index 0000000..5752ff6
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.iotdb.admin.model.entity.StorageGroup;
+import org.springframework.stereotype.Component;
+
+@Component
+public interface GroupMapper extends BaseMapper<StorageGroup> {
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java
new file mode 100644
index 0000000..be3a017
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.iotdb.admin.model.entity.Measurement;
+import org.springframework.stereotype.Component;
+
+@Component
+public interface MeasurementMapper extends BaseMapper<Measurement> {
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java
new file mode 100644
index 0000000..d0c8858
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.iotdb.admin.model.entity.Query;
+import org.springframework.stereotype.Component;
+
+@Component
+public interface QueryMapper extends BaseMapper<Query> {
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java
new file mode 100644
index 0000000..55889c2
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.iotdb.admin.model.entity.User;
+import org.springframework.stereotype.Component;
+
+@Component
+public interface UserMapper extends BaseMapper<User> {
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
new file mode 100644
index 0000000..a87dac6
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+import org.hibernate.validator.constraints.Range;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class ConnectionDTO implements Serializable {
+
+    @NotBlank(message = "主机地址不能为空或为null")
+    @Pattern(regexp = "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$", message = "主机号输入不合法")
+    private String host;
+
+    @NotNull(message = "端口号不能为null")
+    @Range(min = 0, max = 65535, message = "端口号输入不合法")
+    private Integer port;
+
+    @NotBlank(message = "用户名不能为空或为null")
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
+    private String username;
+
+    @NotBlank(message = "密码不能为空或为null")
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
+    private String password;
+
+}
+
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
new file mode 100644
index 0000000..c04efa3
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class CountDTO<T> implements Serializable {
+
+    private List<T> objects;
+    private Integer totalCount;
+    private Integer totalPage;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
new file mode 100644
index 0000000..5050673
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class DeviceDTO implements Serializable {
+
+    private String timeseries;
+
+    private String dataType;
+
+    private String encoding;
+
+    private String description;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
new file mode 100644
index 0000000..3733e54
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class DeviceInfoDTO implements Serializable {
+
+    private List<DeviceDTO> deviceDTOList;
+
+    @NotNull(message = "设备名不能为null")
+    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+    private String deviceName;
+
+    private String description;
+
+    private Integer deviceId;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
new file mode 100644
index 0000000..5aa6070
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class GroupDTO implements Serializable {
+
+    @NotNull(message = "存储组名不能为null")
+    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+    private String groupName;
+    private String description;
+    private Long ttl;
+    private String ttlUnit;
+    private Integer groupId;
+
+}
+
+
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
new file mode 100644
index 0000000..6d2ba60
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 传输role信息类
+ */
+@Data
+public class IotDBRole implements Serializable {
+
+    @Length(min = 4, message = "长度必须大于等于4")
+    private String roleName;
+
+    private List<String> privileges;
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
new file mode 100644
index 0000000..767ad92
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+/**
+ * 传输User信息类
+ */
+@Data
+public class IotDBUser implements Serializable {
+
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+    private String userName;
+
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+    private String password;
+
+//    private List<String> privileges;
+//
+//    private List<String> roles;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java
new file mode 100644
index 0000000..562fc62
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class IotDBUserDTO implements Serializable {
+
+    private List<PrivilegeInfoDTO> privilegesInfos;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
new file mode 100644
index 0000000..b9e6fc7
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class MeasurementDTO implements Serializable {
+
+    private String timeseries;
+    private String alias;
+    private String storagegroup;
+    private String dataType;
+    private String encoding;
+    private String compression;
+    private String tags;
+    private String attributes;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
new file mode 100644
index 0000000..69488b6
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class PrivilegeInfoDTO implements Serializable {
+
+    // 0 1 2 3 对应 root、storageGroup、device、timeseries
+    private Integer type;
+    private List<String> groupPaths;
+    private List<String> devicePaths;
+    private List<String> timeseriesPaths;
+    private List<String> privileges;
+    private List<String> cancelPrivileges;
+    private List<String> delGroupPaths;
+    private List<String> delDevicePaths;
+    private List<String> delTimeseriesPaths;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java
new file mode 100644
index 0000000..ca8a86a
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class QueryDTO implements Serializable {
+
+
+    @NotNull(message = "未指定脚本名")
+    private String queryName;
+
+    private String sqls;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
new file mode 100644
index 0000000..4d0c8ba
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class SearchDTO implements Serializable {
+
+    private List<String> sqls;
+
+    @NotNull(message = "不能为null")
+    private Long timestamp;
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java
new file mode 100644
index 0000000..ecf72cf
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 传输时间序列信息的类
+ */
+@Data
+public class Timeseries implements Serializable {
+
+    private List<String> measurements = new ArrayList<>();
+
+    private List<String> types = new ArrayList<>();
+
+    private long time;
+
+    private List<String> values;
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
new file mode 100644
index 0000000..6672db9
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+import org.hibernate.validator.constraints.Range;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class Connection implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    @NotBlank(message = "主机地址不能为空或为null")
+    @Pattern(regexp = "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$", message = "主机号输入不合法")
+    private String host;
+
+    @NotNull(message = "端口号不能为null")
+    @Range(min = 0, max = 65535, message = "端口号输入不合法")
+    private Integer port;
+
+    @NotBlank(message = "用户名不能为空或为null")
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
+    private String username;
+
+    @NotBlank(message = "密码不能为空或为null")
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
+    private String password;
+
+    @NotBlank(message = "连接名不能为空或为null")
+    @Length(min = 3, max = 100, message = "连接名长度必须在3-100之间")
+    @Pattern(regexp = "^[^ ]+$", message = "连接名不能包含空格")
+    private String alias;
+
+    @NotNull(message = "用户id不能为null")
+    private Integer userId;
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
new file mode 100644
index 0000000..8d0abc4
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class Device implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    @NotNull(message = "未指定所属主机")
+    private String host;
+
+    private String description;
+
+    @NotBlank
+    @Length(min = 4, message = "创建者名长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
+    private String creator;
+
+    @NotNull(message = "未指定创建时间")
+    private Long createTime;
+
+    @NotBlank
+    @Pattern(regexp = "^[^ ]+$", message = "设备名不能包含空格")
+    private String deviceName;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
new file mode 100644
index 0000000..c6178a6
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.entity;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class Measurement implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    @NotNull(message = "未指定所属主机")
+    private String host;
+
+    @NotNull(message = "未指定测点名")
+    private String measurementName;
+
+    private String description;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
new file mode 100644
index 0000000..0d98620
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+@Data
+public class Query implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    @NotNull(message = "未指定所属连接id")
+    private Integer connectionId;
+
+    @NotNull(message = "未指定脚本名")
+    private String queryName;
+
+    private String sqls;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
new file mode 100644
index 0000000..51e9e0e
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class StorageGroup implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    @NotNull(message = "未指定所属主机")
+    private String host;
+
+    private String description;
+
+    @NotBlank
+    @Length(min = 4, message = "创建者名长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
+    private String creator;
+
+    @NotNull(message = "未指定创建时间")
+    private Long createTime;
+
+    @NotBlank
+    private String groupName;
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
new file mode 100644
index 0000000..9df52b7
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Null;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+@Data
+public class User implements Serializable {
+
+    @Null
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    @NotBlank
+    @Length(min = 4, message = "长度必须大于等于4")
+    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+    private String name;
+
+    @NotBlank
+    @Length(min = 6, message = "长度必须大于等于6")
+    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+    private String password;
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
new file mode 100644
index 0000000..07f1179
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+/**
+ * 返回信息类
+ */
+@Data
+public class BaseVO<T> {
+
+    /**
+     * 0 表示成功 其他表示错误类型
+     */
+    private String code;
+
+    /**
+     * 定义出错时候用户可读的信息
+     */
+    private String message;
+
+    /**
+     * 这是一个返回数据的通用类型模板
+     */
+    private T data;
+
+    public BaseVO() {
+    }
+
+    public BaseVO(String code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public static <T> BaseVO<T> success(String message, T data) {
+        return new BaseVO<>("0", message, data);
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
new file mode 100644
index 0000000..da2e511
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 展示别名及serverId
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ConnVO implements Serializable {
+
+    private Integer id;
+    private String alias;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
new file mode 100644
index 0000000..dbc50ce
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 展示用户的连接列表
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ConnectionVO implements Serializable {
+
+    List<ConnVO> aliasList;
+    Integer userId;
+    String name;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
new file mode 100644
index 0000000..60a5a21
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class DeviceInfo implements Serializable {
+
+    private String deviceName;
+    private String description;
+    private String creator;
+    private Integer line;
+    private Integer deviceId;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
new file mode 100644
index 0000000..88f47bd
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class DeviceInfoVO implements Serializable {
+
+    private List<DeviceInfo> deviceInfos;
+    private Integer totalCount;
+    private Integer totalPage;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
new file mode 100644
index 0000000..de0fec7
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class DeviceVO implements Serializable {
+
+    private String description;
+    private String creator;
+    private String time;
+    private Integer deviceId;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
new file mode 100644
index 0000000..5a3b320
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GroupInfoVO implements Serializable {
+
+    private String groupName;
+    private Integer deviceCount;
+    private String description;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
new file mode 100644
index 0000000..efbf29c
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class GroupVO implements Serializable {
+
+    private String groupName;
+    private String alias;
+    private String description;
+    private String creator;
+    private String createTime;
+    private String ttl;
+    private String ttiUnit;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java
new file mode 100644
index 0000000..f5976ad
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class IotDBUserVO implements Serializable {
+
+    private String userName;
+    private String password;
+    private List<PrivilegeInfo> privilegesInfo;
+//    private List<RoleWithPrivilegesVO> roleWithPrivileges;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
new file mode 100644
index 0000000..3e7574d
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class MeasurementVO implements Serializable {
+
+    private String timeseries;
+    private String dataType;
+    private String encoding;
+    private String description;
+    private String newValue;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
new file mode 100644
index 0000000..35334dc
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class MeasuremtnInfoVO implements Serializable {
+
+    private List<MeasurementVO> measurementVOList;
+    private Integer totalCount;
+    private Integer totalPage;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java
new file mode 100644
index 0000000..0c9884e
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class PathVO implements Serializable {
+
+    private String groupName;
+    private String deviceName;
+    private String timeseriesName;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java
new file mode 100644
index 0000000..f1fc85a
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class PrivilegeInfo implements Serializable {
+
+    // 0 1 2 3 对应 root、storageGroup、device、timeseries
+    private Integer type;
+    private List<String> groupPaths;
+    private List<String> devicePaths;
+    private List<String> timeseriesPaths;
+    private List<String> privileges;
+    private List<String> allTimeseriesPaths;
+    private List<String> allDevicePaths;
+    private List<String> allGroupPaths;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
new file mode 100644
index 0000000..51d6ddc
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class QueryVO implements Serializable {
+
+    private Integer id;
+    private String queryName;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
new file mode 100644
index 0000000..6b34ee1
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class RecordVO implements Serializable {
+
+    private List<Date> timeList;
+    private List<Long> valueList;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java
new file mode 100644
index 0000000..21ecfd7
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 角色及其对应权限
+ */
+@Data
+public class RoleWithPrivilegesVO implements Serializable {
+
+    private String role;
+    private String privilege;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
new file mode 100644
index 0000000..c810248
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * sql查询的元数据列表和数据列表
+ */
+@Data
+public class SqlResultVO implements Serializable {
+
+    private List<String> metaDataList;
+    private List<List<String>> valueList;
+    private String queryTime;
+    private Long line;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
new file mode 100644
index 0000000..f6876a6
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.model.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class StorageGroupVO implements Serializable {
+
+    private String groupName;
+    private Integer groupId;
+}
\ No newline at end of file
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java b/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
new file mode 100644
index 0000000..5b63a64
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.ConnVO;
+
+import java.util.List;
+
+public interface ConnectionService {
+
+    List<ConnVO> getAllConnections(Integer id);
+
+    void insert(Connection connection) throws BaseException;
+
+    void deleteById(Integer serverId, Integer userId) throws BaseException;
+
+    Connection getById(Integer serverId) throws BaseException;
+
+    void check(Integer serverId, Integer userId) throws BaseException;
+
+    void update(Connection connection) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java b/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
new file mode 100644
index 0000000..5d9d202
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.entity.Device;
+import org.apache.iotdb.admin.model.vo.DeviceVO;
+
+import java.util.List;
+
+public interface DeviceService {
+
+    List<Device> getDevices(String host, List<String> deviceNames);
+
+    void deleteDeviceInfo(String host, String groupName) throws BaseException;
+
+    void deleteDeviceInfoByDeviceName(String host, String deviceName) throws BaseException;
+
+    void setDeviceInfo(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+
+    DeviceVO getDevice(String host, String deviceName);
+
+    void updateDeviceInfo(DeviceInfoDTO deviceInfoDTO) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java b/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
new file mode 100644
index 0000000..1155d55
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.dto.GroupDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.entity.StorageGroup;
+
+import java.util.List;
+
+public interface GroupService {
+
+    List<String> getGroupDescription(String host, List<String> groupNames) throws BaseException;
+
+    void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
+
+    boolean isExist(String host, String groupName);
+
+    void deleteGroupInfo(String host, String groupName) throws BaseException;
+
+    StorageGroup getGroupInfo(String host, String groupName);
+
+    void updateStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
+
+    Integer getGroupId(String host, String groupName);
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
new file mode 100644
index 0000000..82c15a3
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.dto.*;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.IotDBUserVO;
+import org.apache.iotdb.admin.model.vo.RecordVO;
+import org.apache.iotdb.admin.model.vo.SqlResultVO;
+
+import java.util.List;
+
+public interface IotDBService {
+
+    List<String> getAllStorageGroups(Connection connection) throws BaseException;
+
+    void saveStorageGroup(Connection connection, String groupName) throws BaseException;
+
+    void deleteStorageGroup(Connection connection, String groupName) throws BaseException;
+
+    CountDTO getDevicesByGroup(Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword) throws BaseException;
+
+    CountDTO getMeasurementsByDevice(Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword) throws BaseException;
+
+    List<String> getIotDBUserList(Connection connection) throws BaseException;
+
+    List<String> getIotDBRoleList(Connection connection) throws BaseException;
+
+    IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException;
+
+    void deleteIotDBUser(Connection connection, String userName) throws BaseException;
+
+    void deleteIotDBRole(Connection connection, String roleName) throws BaseException;
+
+    void setIotDBUser(Connection connection, IotDBUser iotDBUserVO) throws BaseException;
+
+    void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException;
+
+    void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries) throws BaseException;
+
+    void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException;
+
+    SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException;
+
+    List<Integer> getDevicesCount(Connection connection, List<String> groupNames) throws BaseException;
+
+    void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException;
+
+    void cancelGroupTtl(Connection connection, String groupName) throws BaseException;
+
+    Integer getDeviceCount(Connection connection, String groupName) throws BaseException;
+
+    List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames) throws BaseException;
+
+    void deleteTimeseriesByDevice(Connection connection, String deviceName) throws BaseException;
+
+    void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+
+    Integer getMeasurementsCount(Connection connection, String deviceName) throws BaseException;
+
+    String getLastMeasurementValue(Connection connection, String timeseries) throws BaseException;
+
+    String getGroupTTL(Connection connection, String groupName) throws BaseException;
+
+    List<String> getDevices(Connection connection, String groupName) throws BaseException;
+
+    List<String> getTimeseries(Connection connection, String deviceName) throws BaseException;
+
+    void setUserPrivileges(Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO) throws BaseException;
+
+    RecordVO getRecords(Connection connection, String deviceName, String timeseriesName) throws BaseException;
+
+    List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp) throws BaseException;
+
+    void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException;
+
+    void stopQuery(Integer serverId, Long timestamp) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
new file mode 100644
index 0000000..64240db
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
+
+public interface MeasurementService {
+
+    void deleteMeasurementInfo(String host, String groupName) throws BaseException;
+
+    void deleteMeasurementInfoByDeviceName(String host, String deviceName) throws BaseException;
+
+    void setMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+
+    String getDescription(String host, String timeseries) throws BaseException;
+
+    void updateMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java b/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
new file mode 100644
index 0000000..613966f
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.entity.Query;
+import org.apache.iotdb.admin.model.vo.QueryVO;
+
+import java.util.List;
+
+public interface QueryService {
+
+    void save(Integer serverId, Query query) throws BaseException;
+
+    void update(Integer serverId, Query query) throws BaseException;
+
+    List<QueryVO> getQueryList(Integer serverId);
+
+    void deleteQuery(Integer queryId) throws BaseException;
+
+    Query getQuery(Integer queryId) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java b/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
new file mode 100644
index 0000000..d263646
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.model.entity.User;
+
+public interface UserService {
+
+    User login(String name, String password) throws BaseException;
+
+    void insert(User user) throws BaseException;
+
+    void delete(Integer userId) throws BaseException;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
new file mode 100644
index 0000000..40dedbc
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.ConnectionMapper;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.ConnVO;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connection> implements ConnectionService {
+
+    @Autowired
+    private ConnectionMapper connectionMapper;
+
+    @Override
+    public List<ConnVO> getAllConnections(Integer userId) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("user_id", userId);
+        List<Connection> connections = connectionMapper.selectList(queryWrapper);
+        List<ConnVO> ConnVOs = new ArrayList();
+        for (Connection connection : connections) {
+            ConnVOs.add(new ConnVO(connection.getId(), connection.getAlias()));
+        }
+        return ConnVOs;
+    }
+
+    @Override
+    public void insert(Connection connection) throws BaseException {
+        String alias = connection.getAlias();
+        Integer userId = connection.getUserId();
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("user_id", userId);
+        queryWrapper.eq("alias", alias);
+        Connection existConnection = connectionMapper.selectOne(queryWrapper);
+        // 别名唯一
+        if (existConnection != null) {
+            throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
+        }
+        if ("127.0.0.1".equals(connection.getHost())) {
+            connection.setHost("localhost");
+        }
+        int flag = connectionMapper.insert(connection);
+        if (flag <= 0) {
+            throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void deleteById(Integer serverId, Integer userId) throws BaseException {
+        try {
+            connectionMapper.deleteById(serverId);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_CONN_FAIL, ErrorCode.DELETE_CONN_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public Connection getById(Integer serverId) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("id", serverId);
+        try {
+            Connection connection = connectionMapper.selectOne(queryWrapper);
+            if (connection == null) {
+                throw new BaseException(ErrorCode.NO_CONN, ErrorCode.NO_CONN_MSG);
+            }
+            return connection;
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.GET_CONN_FAIL, ErrorCode.GET_CONN_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void check(Integer serverId, Integer userId) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("id", serverId);
+        queryWrapper.eq("user_id", userId);
+        Connection connection = connectionMapper.selectOne(queryWrapper);
+        if (connection == null) {
+            throw new BaseException(ErrorCode.CHECK_FAIL, ErrorCode.CHECK_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void update(Connection connection) throws BaseException {
+        String alias = connection.getAlias();
+        Integer userId = connection.getUserId();
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("user_id", userId);
+        queryWrapper.eq("alias", alias);
+        Connection existConnection = connectionMapper.selectOne(queryWrapper);
+        // 别名唯一
+        if (existConnection != null && !connection.getId().equals(existConnection.getId())) {
+            throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
+        }
+        int flag = connectionMapper.updateById(connection);
+        if (flag <= 0) {
+            throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
+        }
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
new file mode 100644
index 0000000..d507d91
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.DeviceMapper;
+import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.entity.Device;
+import org.apache.iotdb.admin.model.vo.DeviceVO;
+import org.apache.iotdb.admin.service.DeviceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
+
+
+    @Autowired
+    private DeviceMapper deviceMapper;
+
+    @Override
+    public List<Device> getDevices(String host, List<String> deviceNames) {
+        List<Device> devices = new ArrayList<>();
+        for (String deviceName : deviceNames) {
+            QueryWrapper queryWrapper = new QueryWrapper();
+            queryWrapper.eq("host", host);
+            queryWrapper.eq("device_name", deviceName);
+            Device device = deviceMapper.selectOne(queryWrapper);
+            devices.add(device);
+        }
+        return devices;
+    }
+
+    @Override
+    public void deleteDeviceInfo(String host, String groupName) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.like("device_name", groupName);
+        try {
+            deviceMapper.delete(queryWrapper);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_DEVICE_INFO_FAIL, ErrorCode.DELETE_DEVICE_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void deleteDeviceInfoByDeviceName(String host, String deviceName) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("device_name", deviceName);
+        try {
+            deviceMapper.delete(queryWrapper);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_DEVICE_INFO_FAIL, ErrorCode.DELETE_DEVICE_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void setDeviceInfo(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", connection.getHost());
+        queryWrapper.eq("device_name", deviceInfoDTO.getDeviceName());
+        Device existDevice = deviceMapper.selectOne(queryWrapper);
+        if (existDevice == null) {
+            Device device = new Device();
+            device.setCreator(connection.getUsername());
+            device.setDeviceName(deviceInfoDTO.getDeviceName());
+            device.setCreateTime(System.currentTimeMillis());
+            device.setHost(connection.getHost());
+            device.setDescription(deviceInfoDTO.getDescription());
+            int flag = deviceMapper.insert(device);
+            if (flag <= 0) {
+                throw new BaseException(ErrorCode.SET_DEVICE_INFO_FAIL, ErrorCode.SET_DEVICE_INFO_FAIL_MSG);
+            }
+            return;
+        }
+        existDevice.setDescription(deviceInfoDTO.getDescription());
+        int flag = deviceMapper.updateById(existDevice);
+        if (flag <= 0) {
+            throw new BaseException(ErrorCode.SET_DEVICE_INFO_FAIL, ErrorCode.SET_DEVICE_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public DeviceVO getDevice(String host, String deviceName) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("device_name", deviceName);
+        Device device = deviceMapper.selectOne(queryWrapper);
+        // 非系统创建的设备没有设备信息
+        DeviceVO deviceVO = new DeviceVO();
+        if (device != null) {
+            deviceVO.setCreator(device.getCreator());
+            deviceVO.setDescription(device.getDescription());
+            deviceVO.setDeviceId(device.getId());
+            Long createTime = device.getCreateTime();
+            Date date = new Date(createTime);
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+            String time = sdf.format(date);
+            deviceVO.setTime(time);
+            return deviceVO;
+        }
+        return deviceVO;
+    }
+
+    @Override
+    public void updateDeviceInfo(DeviceInfoDTO deviceInfoDTO) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("id", deviceInfoDTO.getDeviceId());
+        Device existDevice = deviceMapper.selectOne(queryWrapper);
+        if (existDevice != null) {
+            existDevice.setDescription(deviceInfoDTO.getDescription());
+            deviceMapper.updateById(existDevice);
+            return;
+        }
+        throw new BaseException(ErrorCode.NO_DEVICE_INFO, ErrorCode.NO_DEVICE_INFO_MSG);
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
new file mode 100644
index 0000000..7ae2122
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.GroupMapper;
+import org.apache.iotdb.admin.model.dto.GroupDTO;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.entity.StorageGroup;
+import org.apache.iotdb.admin.service.GroupService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class GroupServiceImpl extends ServiceImpl<GroupMapper, StorageGroup> implements GroupService {
+
+
+    @Autowired
+    private GroupMapper groupMapper;
+
+    @Override
+    public List<String> getGroupDescription(String host, List<String> groupNames) throws BaseException {
+        List<String> descriptions = new ArrayList<>();
+        for (String groupName : groupNames) {
+            descriptions.add(getDescription(host, groupName));
+        }
+        return descriptions;
+    }
+
+    @Override
+    public void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        String host = connection.getHost();
+        String groupName = groupDTO.getGroupName();
+        String description = groupDTO.getDescription();
+        if ("127.0.0.1".equals(host)) {
+            host = "localhost";
+        }
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("group_name", groupName);
+        StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
+        if (storageGroup != null) {
+            storageGroup.setDescription(description);
+            int flag = groupMapper.updateById(storageGroup);
+            if (flag <= 0) {
+                throw new BaseException(ErrorCode.INSERT_GROUP_INFO_FAIL, ErrorCode.INSERT_GROUP_INFO_FAIL_MSG);
+            }
+            return;
+        }
+        String username = connection.getUsername();
+        StorageGroup group = new StorageGroup();
+        group.setCreateTime(System.currentTimeMillis());
+        group.setCreator(username);
+        group.setGroupName(groupName);
+        group.setDescription(description);
+        group.setHost(host);
+        int flag = groupMapper.insert(group);
+        if (flag <= 0) {
+            throw new BaseException(ErrorCode.INSERT_GROUP_INFO_FAIL, ErrorCode.INSERT_GROUP_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public boolean isExist(String host, String groupName) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("group_name", groupName);
+        StorageGroup group = groupMapper.selectOne(queryWrapper);
+        if (group != null) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void deleteGroupInfo(String host, String groupName) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("group_name", groupName);
+        try {
+            groupMapper.delete(queryWrapper);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_GROUP_INFO_FAIL, ErrorCode.DELETE_GROUP_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public StorageGroup getGroupInfo(String host, String groupName) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("group_name", groupName);
+        return groupMapper.selectOne(queryWrapper);
+    }
+
+    @Override
+    public void updateStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", connection.getHost());
+        queryWrapper.eq("group_name", groupDTO.getGroupName());
+        StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
+        if (storageGroup != null) {
+            storageGroup.setDescription(groupDTO.getDescription());
+            int flag = groupMapper.updateById(storageGroup);
+            if (flag <= 0) {
+                throw new BaseException(ErrorCode.UPDATE_GROUP_INFO_FAIL, ErrorCode.UPDATE_GROUP_INFO_FAIL_MSG);
+            }
+            return;
+        }
+        throw new BaseException(ErrorCode.NO_GROUP_INFO, ErrorCode.NO_GROUP_INFO_MSG);
+    }
+
+    @Override
+    public Integer getGroupId(String host, String groupName) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("group_name", groupName);
+        StorageGroup group = groupMapper.selectOne(queryWrapper);
+        if (group != null) {
+            return group.getId();
+        }
+        return null;
+    }
+
+    private String getDescription(String host, String groupName) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("group_name", groupName);
+        StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
+        if (storageGroup != null) {
+            return storageGroup.getDescription();
+        }
+        return null;
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
new file mode 100644
index 0000000..5a69eac
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
@@ -0,0 +1,1857 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.model.dto.*;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.*;
+import org.apache.iotdb.admin.service.IotDBService;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.StatementExecutionException;
+import org.apache.iotdb.session.pool.SessionDataSetWrapper;
+import org.apache.iotdb.session.pool.SessionPool;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.sql.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.*;
+import java.util.concurrent.*;
+
+@Service
+public class IotDBServiceImpl implements IotDBService {
+
+    private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
+
+    private static final HashMap<String, Boolean> SPECIAL_PRIVILEGES = new HashMap();
+
+    private static final String NO_NEED_PRIVILEGES = "SET_STORAGE_GROUP";
+
+    private static final List<String> PRIVILEGES = new ArrayList<>();
+
+    private static final HashMap<String, Boolean> QUERY_STOP = new HashMap<>();
+
+    static {
+        SPECIAL_PRIVILEGES.put("CREATE_TIMESERIES", true);
+        SPECIAL_PRIVILEGES.put("INSERT_TIMESERIES", true);
+        SPECIAL_PRIVILEGES.put("READ_TIMESERIES", true);
+        SPECIAL_PRIVILEGES.put("DELETE_TIMESERIES", true);
+    }
+
+    static {
+        PRIVILEGES.add("SET_STORAGE_GROUP");
+        PRIVILEGES.add("CREATE_TIMESERIES");
+        PRIVILEGES.add("INSERT_TIMESERIES");
+        PRIVILEGES.add("READ_TIMESERIES");
+        PRIVILEGES.add("DELETE_TIMESERIES");
+        PRIVILEGES.add("CREATE_USER");
+        PRIVILEGES.add("DELETE_USER");
+        PRIVILEGES.add("MODIFY_PASSWORD");
+        PRIVILEGES.add("LIST_USER");
+        PRIVILEGES.add("GRANT_USER_PRIVILEGE");
+        PRIVILEGES.add("REVOKE_USER_PRIVILEGE");
+        PRIVILEGES.add("CREATE_FUNCTION");
+        PRIVILEGES.add("DROP_FUNCTION");
+        PRIVILEGES.add("CREATE_TRIGGER");
+        PRIVILEGES.add("DROP_TRIGGER");
+        PRIVILEGES.add("START_TRIGGER");
+        PRIVILEGES.add("STOP_TRIGGER");
+    }
+
+
+    @Override
+    public List<String> getAllStorageGroups(Connection connection) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "show storage group";
+        List<String> users = executeQueryOneColumn(sessionPool, sql);
+        sessionPool.close();
+        return users;
+    }
+
+    @Override
+    public void saveStorageGroup(Connection connection, String groupName) throws BaseException {
+        paramValid(groupName);
+        SessionPool sessionPool = getSessionPool(connection);
+        try {
+            sessionPool.setStorageGroup(groupName);
+        } catch (StatementExecutionException e) {
+            // 300为存储组重复或者其前/后路径上已经有存储组了
+            if (e.getStatusCode() == 602) {
+                throw new BaseException(ErrorCode.NO_PRI_SET_GROUP, ErrorCode.NO_PRI_SET_GROUP_MSG);
+            }
+            if (e.getStatusCode() == 300) {
+                throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
+            }
+            logger.error(e.getMessage());
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public void deleteStorageGroup(Connection connection, String groupName) throws BaseException {
+        paramValid(groupName);
+        SessionPool sessionPool = getSessionPool(connection);
+        try {
+            sessionPool.deleteStorageGroup(groupName);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            if (e.getStatusCode() == 602) {
+                throw new BaseException(ErrorCode.NO_PRI_DELETE_GROUP, ErrorCode.NO_PRI_DELETE_GROUP_MSG);
+            }
+            throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public CountDTO getDevicesByGroup(Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword) throws BaseException {
+        paramValid(groupName);
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "show devices " + groupName;
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            List<String> values = new ArrayList<>();
+            int count = 0;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+                    if (keyword != null || "".equals(keyword)) {
+                        String deviceName = fields.get(0).toString();
+                        deviceName = StringUtils.removeStart(deviceName, groupName + ".");
+                        if (deviceName.contains(keyword)) {
+                            count++;
+                        } else {
+                            continue;
+                        }
+                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+                            values.add(fields.get(0).toString());
+                        }
+                    } else {
+                        count++;
+                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+                            values.add(fields.get(0).toString());
+                        }
+                    }
+                }
+            }
+            CountDTO countDTO = new CountDTO();
+            countDTO.setObjects(values);
+            countDTO.setTotalCount(count);
+            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+            countDTO.setTotalPage(totalPage);
+            return countDTO;
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public CountDTO getMeasurementsByDevice(Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword) throws BaseException {
+        paramValid(deviceName);
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "show timeseries " + deviceName;
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            List<MeasurementDTO> results = new ArrayList<>();
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            int count = 0;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+                    if (keyword != null || "".equals(keyword)) {
+                        String measurementName = fields.get(0).toString();
+                        measurementName = StringUtils.removeStart(measurementName, deviceName + ".");
+                        if (measurementName.contains(keyword)) {
+                            count++;
+                        } else {
+                            continue;
+                        }
+                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+                            MeasurementDTO t = new MeasurementDTO();
+                            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+                            for (int i = 0; i < fields.size(); i++) {
+                                Field field = MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+                                field.setAccessible(true);
+                                field.set(t, fields.get(i).toString());
+                            }
+                            results.add(t);
+                        }
+                    } else {
+                        count++;
+                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+                            MeasurementDTO t = new MeasurementDTO();
+                            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+                            for (int i = 0; i < fields.size(); i++) {
+                                Field field = MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+                                field.setAccessible(true);
+                                field.set(t, fields.get(i).toString());
+                            }
+                            results.add(t);
+                        }
+                    }
+                }
+            }
+            CountDTO countDTO = new CountDTO();
+            countDTO.setObjects(results);
+            countDTO.setTotalCount(count);
+            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+            countDTO.setTotalPage(totalPage);
+            return countDTO;
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        } catch (Exception e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+        }
+    }
+
+    @Override
+    public List<String> getIotDBUserList(Connection connection) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "list user";
+        List<String> users = executeQueryOneColumn(sessionPool, sql);
+        sessionPool.close();
+        return users;
+    }
+
+    @Override
+    public List<String> getIotDBRoleList(Connection connection) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "list role";
+        List<String> roles = executeQueryOneColumn(sessionPool, sql);
+        sessionPool.close();
+        return roles;
+    }
+
+    @Override
+    public IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException {
+        paramValid(userName);
+        IotDBUserVO iotDBUserVO = new IotDBUserVO();
+        iotDBUserVO.setUserName(userName);
+        if (userName.equals(connection.getUsername())) {
+            iotDBUserVO.setPassword(connection.getPassword());
+        } else {
+            iotDBUserVO.setPassword(null);
+        }
+        if ("root".equalsIgnoreCase(userName)) {
+            List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
+            PrivilegeInfo privilegeInfo = new PrivilegeInfo();
+            privilegeInfo.setType(0);
+            privilegeInfo.setPrivileges(PRIVILEGES);
+            privilegeInfos.add(privilegeInfo);
+            iotDBUserVO.setPrivilegesInfo(privilegeInfos);
+            return iotDBUserVO;
+        }
+        SessionPool sessionpool = getSessionPool(connection);
+        String sql = "list user privileges " + userName;
+        try {
+            SessionDataSetWrapper sessionDataSetWrapper = sessionpool.executeQueryStatement(sql);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            if (batchSize > 0) {
+                List<String> privileges = new ArrayList<>();
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord next = sessionDataSetWrapper.next();
+                    List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+                    for (int i = 0; i < fields.size(); i++) {
+                        org.apache.iotdb.tsfile.read.common.Field field = fields.get(i);
+                        if (i == 0) {
+                            if (field != null && field.toString().length() > 0) {
+                                break;
+                            }
+                            continue;
+                        }
+                        privileges.add(field.toString());
+                    }
+                }
+                // privileges String内容形式 "path : 权限1 权限2 权限3"
+                // 组装成权限信息集合
+                List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
+                if (privileges != null && privileges.size() > 0) {
+                    privilegeInfos = privilegesStrSwitchToObject(sessionpool, privileges);
+                }
+                iotDBUserVO.setPrivilegesInfo(privilegeInfos);
+            }
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.GET_USER_FAIL, ErrorCode.GET_USER_FAIL_MSG);
+        } finally {
+            if (sessionpool != null) {
+                sessionpool.close();
+            }
+        }
+        return iotDBUserVO;
+    }
+
+    @Override
+    public void deleteIotDBUser(Connection connection, String userName) throws BaseException {
+        paramValid(userName);
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "drop user " + userName;
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public void deleteIotDBRole(Connection connection, String roleName) throws BaseException {
+        paramValid(roleName);
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "drop role " + roleName;
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public void setIotDBUser(Connection connection, IotDBUser iotDBUser) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String userName = iotDBUser.getUserName();
+        String password = iotDBUser.getPassword();
+        String sql = "create user " + userName + " '" + password + "'";
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+//        // 用户角色
+//        for (String role : iotDBUser.getRoles()) {
+//            paramValid(role);
+//            sql = "grant " + role + " to " + userName;
+//            customExecute(conn, sql);
+//        }
+//        // 用户授权
+//        List<String> privileges = iotDBUser.getPrivileges();
+//        for (String privilege : privileges) {
+//            sql = handlerPrivilegeStrToSql(privilege, userName, null);
+//            if (sql != null) {
+//                customExecute(conn, sql);
+//            }
+//        }
+    }
+
+    @Override
+    public void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String roleName = iotDBRole.getRoleName();
+        String sql = "create role " + roleName;
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+            List<String> privileges = iotDBRole.getPrivileges();
+            for (String privilege : privileges) {
+                sql = handlerPrivilegeStrToSql(privilege, null, roleName);
+                if (sql != null) {
+                    sessionPool.executeNonQueryStatement(sql);
+                }
+            }
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+//    @Override
+//    public SqlResultVO query(Connection connection, String sql) throws BaseException {
+//        java.sql.Connection conn = getConnection(connection);
+//        SqlResultVO sqlResultVO = sqlQuery(conn, sql);
+//        closeConnection(conn);
+//        return sqlResultVO;
+//    }
+
+    @Override
+    public void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        try {
+            List<TSDataType> types = handleTypeStr(timeseries.getTypes());
+            List<Object> values = handleValueStr(timeseries.getValues(), types);
+            sessionPool.insertRecord(deviceName, timeseries.getTime(), timeseries.getMeasurements(), types, values);
+        } catch (IoTDBConnectionException e) {
+            throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+
+    }
+
+    @Override
+    public void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        try {
+            sessionPool.deleteTimeseries(timeseriesName);
+        } catch (IoTDBConnectionException e) {
+            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            if (e.getStatusCode() == 602) {
+                throw new BaseException(ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+            }
+            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException {
+        paramValid(deviceName);
+        java.sql.Connection conn = getConnection(connection);
+        String sql = "show timeseries " + deviceName;
+        SqlResultVO resultVO = sqlQuery(conn, sql);
+        closeConnection(conn);
+        return resultVO;
+    }
+
+    @Override
+    public List<Integer> getDevicesCount(Connection connection, List<String> groupNames) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        List<Integer> devicesCount = new ArrayList<>();
+        for (String groupName : groupNames) {
+            String sql = "count devices " + groupName;
+            String value = executeQueryOneValue(sessionPool, sql);
+            if (value == null) {
+                devicesCount.add(0);
+                continue;
+            }
+            Integer count = Integer.valueOf(value);
+            devicesCount.add(count);
+        }
+        sessionPool.close();
+        return devicesCount;
+    }
+
+    @Override
+    public void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "set ttl to " + groupName + " " + l;
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            if (e.getStatusCode() == 602) {
+                throw new BaseException(ErrorCode.NO_PRI_SET_TTL, ErrorCode.NO_PRI_SET_TTL_MSG);
+            }
+            throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
+        } finally {
+            sessionPool.close();
+        }
+    }
+
+    @Override
+    public void cancelGroupTtl(Connection connection, String groupName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "unset ttl to " + groupName;
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+        } finally {
+            sessionPool.close();
+        }
+    }
+
+    @Override
+    public Integer getDeviceCount(Connection connection, String groupName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "count devices " + groupName;
+        String value = executeQueryOneValue(sessionPool, sql);
+        if (value == null) {
+            return 0;
+        }
+        Integer count = Integer.valueOf(value);
+        return count;
+    }
+
+    @Override
+    public List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        List<Integer> lines = new ArrayList<>();
+        for (String deviceName : deviceNames) {
+            String sql = "count timeseries " + deviceName;
+            String value = executeQueryOneValue(sessionPool, sql);
+            if (value == null) {
+                lines.add(0);
+                continue;
+            }
+            Integer count = Integer.valueOf(value);
+            lines.add(count);
+        }
+        sessionPool.close();
+        return lines;
+    }
+
+    @Override
+    public void deleteTimeseriesByDevice(Connection connection, String deviceName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "delete timeseries " + deviceName + ".*";
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            if (e.getStatusCode() == 602) {
+                throw new BaseException(ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+            }
+            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        List<String> typesStr = new ArrayList<>();
+        List<String> encodingsStr = new ArrayList<>();
+        List<String> measurements = new ArrayList<>();
+        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+            typesStr.add(deviceDTO.getDataType());
+            encodingsStr.add(deviceDTO.getEncoding());
+            measurements.add(deviceDTO.getTimeseries());
+        }
+        List<TSDataType> types = handleTypeStr(typesStr);
+        List<TSEncoding> encodings = handleEncodingStr(encodingsStr);
+        List<CompressionType> compressionTypes = new ArrayList<>();
+        for (int i = 0; i < types.size(); i++) {
+            compressionTypes.add(CompressionType.SNAPPY);
+        }
+        try {
+            sessionPool.createMultiTimeseries(measurements, types, encodings, compressionTypes, null, null, null, null);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            if (e.getMessage().contains("No permissions")) {
+                throw new BaseException(ErrorCode.NO_PRI_CREATE_TIMESERIES, ErrorCode.NO_PRI_CREATE_TIMESERIES_MSG);
+            }
+            if (!e.getMessage().contains("PathAlreadyExistException")) {
+                logger.error(e.getMessage());
+                throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
+            }
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+    }
+
+    @Override
+    public Integer getMeasurementsCount(Connection connection, String deviceName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "count timeseries " + deviceName;
+        String valueStr = executeQueryOneValue(sessionPool, sql);
+        return Integer.valueOf(valueStr);
+    }
+
+    @Override
+    public String getLastMeasurementValue(Connection connection, String timeseries) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        int index = timeseries.lastIndexOf(".");
+        String sql = "select last_value(" + timeseries.substring(index + 1) + ") from " + timeseries.substring(0, index);
+        String value;
+        try {
+            value = executeQueryOneValue(sessionPool, sql);
+        } finally {
+            sessionPool.close();
+        }
+        return value;
+    }
+
+    @Override
+    public String getGroupTTL(Connection connection, String groupName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "show ttl on " + groupName;
+        String queryField = "ttl";
+        String ttl = executeQueryOneLine(sessionPool, sql, queryField);
+        return ttl;
+    }
+
+    @Override
+    public List<String> getDevices(Connection connection, String groupName) throws BaseException {
+        paramValid(groupName);
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "show devices " + groupName;
+        List<String> devicesName = executeQueryOneColumn(sessionPool, sql);
+        return devicesName;
+    }
+
+    @Override
+    public List<String> getTimeseries(Connection connection, String deviceName) throws BaseException {
+        paramValid(deviceName);
+        SessionPool sessionPool = getSessionPool(connection);
+        String sql = "show timeseries " + deviceName;
+        SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, true);
+        List<String> metaDataList = sqlResultVO.getMetaDataList();
+        int index = -1;
+        if (metaDataList != null) {
+            for (int i = 0; i < metaDataList.size(); i++) {
+                if ("timeseries".equalsIgnoreCase(metaDataList.get(i))) {
+                    index = i;
+                    break;
+                }
+            }
+        }
+        if (index == -1) {
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        }
+        List<List<String>> valueList = sqlResultVO.getValueList();
+        List<String> timeseries = new ArrayList<>();
+        for (List<String> list : valueList) {
+            timeseries.add(list.get(index));
+        }
+        return timeseries;
+    }
+
+    @Override
+    public void setUserPrivileges(Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        // 授权
+        List<String> privileges = privilegeInfoDTO.getPrivileges();
+        if (notNullAndNotZero(privileges)) {
+            grantOrRevoke("grant", privileges, userName, privilegeInfoDTO, sessionPool);
+        }
+        // 取消授权
+        List<String> cancelPrivileges = privilegeInfoDTO.getCancelPrivileges();
+        if (notNullAndNotZero(cancelPrivileges)) {
+            grantOrRevoke("revoke", cancelPrivileges, userName, privilegeInfoDTO, sessionPool);
+        }
+        cancelPathPrivileges(userName, privilegeInfoDTO, sessionPool);
+        sessionPool.close();
+    }
+
+    private void cancelPathPrivileges(String userName, PrivilegeInfoDTO privilegeInfoDTO, SessionPool sessionPool) {
+        Integer type = privilegeInfoDTO.getType();
+        List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
+        List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
+        List<String> delTimeseriesPaths = privilegeInfoDTO.getDelTimeseriesPaths();
+        switch (type) {
+            case 1:
+                if (notNullAndNotZero(delGroupPaths)) {
+                    Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
+                    for (String delGroupPath : delGroupPaths) {
+                        for (String privilegesStr : privileges) {
+                            String sql = "revoke user " + userName + " privileges '" + privilegesStr + "' on root."
+                                + delGroupPath;
+                            try {
+                                sessionPool.executeNonQueryStatement(sql);
+                            } catch (StatementExecutionException e) {
+                                logger.error(e.getMessage());
+                            } catch (IoTDBConnectionException e) {
+                                logger.error(e.getMessage());
+                            }
+                        }
+                    }
+                }
+                break;
+            case 2:
+                if (notNullAndNotZero(delDevicePaths)) {
+                    Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
+                    String onlyGroupPath = delGroupPaths.get(0);
+                    for (String delDevicePath : delDevicePaths) {
+                        for (String privilegesStr : privileges) {
+                            String sql = "revoke user " + userName + " privileges '" + privilegesStr + "' on root."
+                                + onlyGroupPath + "." + delDevicePath;
+                            try {
+                                sessionPool.executeNonQueryStatement(sql);
+                            } catch (StatementExecutionException e) {
+                                logger.error(e.getMessage());
+                            } catch (IoTDBConnectionException e) {
+                                logger.error(e.getMessage());
+                            }
+                        }
+                    }
+                }
+                break;
+            case 3:
+                if (notNullAndNotZero(delTimeseriesPaths)) {
+                    Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
+                    String onlyGroupPath = delGroupPaths.get(0);
+                    String onlyDevicePath = delDevicePaths.get(0);
+                    for (String delTimeseriesPath : delTimeseriesPaths) {
+                        for (String privilegesStr : privileges) {
+                            String sql = "revoke user " + userName + " privileges '" + privilegesStr + "' on root."
+                                + onlyGroupPath + "." + onlyDevicePath + "." + delTimeseriesPath;
+                            try {
+                                sessionPool.executeNonQueryStatement(sql);
+                            } catch (StatementExecutionException e) {
+                                logger.error(e.getMessage());
+                            } catch (IoTDBConnectionException e) {
+                                logger.error(e.getMessage());
+                            }
+                        }
+                    }
+                }
+                break;
+        }
+    }
+
+    @Override
+    public RecordVO getRecords(Connection connection, String deviceName, String timeseriesName) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        RecordVO recordVO = new RecordVO();
+        List<Date> timeList = new ArrayList<>();
+        List<Long> valueList = new ArrayList<>();
+        String sql = "select time," + timeseriesName + " from " + deviceName + " order by time desc limit 200 offset 0";
+        try {
+            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord next = sessionDataSetWrapper.next();
+                    Date date = new Date(next.getTimestamp());
+                    timeList.add(date);
+                    List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+                    Long value = Long.valueOf(fields.get(0).toString());
+                    valueList.add(value);
+                }
+            }
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
+        }
+        recordVO.setTimeList(timeList);
+        recordVO.setValueList(valueList);
+        return recordVO;
+    }
+
+    @Override
+    public List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        List<SqlResultVO> results;
+        String id_plus_timestamp;
+        try {
+            results = new ArrayList<>();
+            Integer id = connection.getId();
+            id_plus_timestamp = id + ":" + timestamp;
+            QUERY_STOP.put(id_plus_timestamp, true);
+            for (String sql : sqls) {
+                int firstSpaceIndex = sql.indexOf(" ");
+                String judge = sql.substring(0, firstSpaceIndex);
+                if ("show".equalsIgnoreCase(judge) || "count".equalsIgnoreCase(judge) || "list".equalsIgnoreCase(judge)) {
+                    SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, false);
+                    results.add(sqlResultVO);
+                    continue;
+                }
+                if ("select".equalsIgnoreCase(judge)) {
+                    SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, true);
+                    results.add(sqlResultVO);
+                    continue;
+                }
+                try {
+                    if (QUERY_STOP.get(id_plus_timestamp)) {
+                        String sqlCheck = sql.toLowerCase();
+                        if (sqlCheck != null && sqlCheck.contains("insert")) {
+                            String s = sqlCheck;
+                            String[] split = s.split("\\.");
+                            if (split.length <= 2) {
+                                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
+                            }
+                        }
+                        if (sqlCheck != null && sqlCheck.contains("create timeseries")) {
+                            String s = sqlCheck;
+                            String[] split = s.split("\\.");
+                            if (split.length <= 3) {
+                                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
+                            }
+                        }
+                        long start = System.currentTimeMillis();
+                        sessionPool.executeNonQueryStatement(sql);
+                        long end = System.currentTimeMillis();
+                        double time = (end - start + 0.0d) / 1000;
+                        String queryTime = time + "s";
+                        SqlResultVO sqlResultVO = new SqlResultVO();
+                        sqlResultVO.setQueryTime(queryTime);
+                        sqlResultVO.setLine(0L);
+                        results.add(sqlResultVO);
+                    }
+                } catch (StatementExecutionException e) {
+                    logger.error(e.getMessage());
+                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
+                } catch (IoTDBConnectionException e) {
+                    logger.error(e.getMessage());
+                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
+                }
+            }
+        } finally {
+            if (sessionPool != null) {
+                sessionPool.close();
+            }
+        }
+        QUERY_STOP.remove(id_plus_timestamp);
+        return results;
+    }
+
+    @Override
+    public void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException {
+        SessionPool sessionPool = getSessionPool(connection);
+        String userName = iotDBUser.getUserName();
+        String newPWD = iotDBUser.getPassword();
+        String sql = "alter user " + userName + " set password '" + newPWD + "'";
+        try {
+            sessionPool.executeNonQueryStatement(sql);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.UPDATE_PWD_FAIL, ErrorCode.UPDATE_PWD_FAIL_MSG);
+        } catch (IoTDBConnectionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void stopQuery(Integer serverId, Long timestamp) throws BaseException {
+        String notStopKey = serverId + ":" + timestamp;
+        if (QUERY_STOP.containsKey(notStopKey)) {
+            QUERY_STOP.put(notStopKey, false);
+            return;
+        }
+        throw new BaseException(ErrorCode.NO_QUERY, ErrorCode.NO_QUERY_MSG);
+    }
+
+
+    private void grantOrRevoke(String word, List<String> privileges, String userName, PrivilegeInfoDTO privilegesInfo, SessionPool sessionPool)
+        throws BaseException {
+        Integer type = privilegesInfo.getType();
+//        String privilegesStr = String.join("','", privileges); 一起存会有bug
+        for (String privilegesStr : privileges) {
+            if (type == 0) {
+                String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root";
+                try {
+                    sessionPool.executeNonQueryStatement(sql);
+                } catch (StatementExecutionException e) {
+                    logger.error(e.getMessage());
+                } catch (IoTDBConnectionException e) {
+                    logger.error(e.getMessage());
+                }
+                continue;
+            }
+            if (type == 1) {
+                List<String> groupPaths = privilegesInfo.getGroupPaths();
+                if (notNullAndNotZero(groupPaths)) {
+                    for (String groupPath : groupPaths) {
+                        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root."
+                            + groupPath;
+                        try {
+                            sessionPool.executeNonQueryStatement(sql);
+                        } catch (StatementExecutionException e) {
+                            logger.error(e.getMessage());
+                        } catch (IoTDBConnectionException e) {
+                            logger.error(e.getMessage());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (type == 2) {
+                List<String> groupPaths = privilegesInfo.getGroupPaths();
+                List<String> devicePaths = privilegesInfo.getDevicePaths();
+                if (notNullAndNotZero(groupPaths) && groupPaths.size() == 1 && notNullAndNotZero(devicePaths)) {
+                    String onlyGroupPath = groupPaths.get(0);
+                    for (String devicePath : devicePaths) {
+                        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root."
+                            + onlyGroupPath + "." + devicePath;
+                        try {
+                            sessionPool.executeNonQueryStatement(sql);
+                        } catch (StatementExecutionException e) {
+                            logger.error(e.getMessage());
+                        } catch (IoTDBConnectionException e) {
+                            logger.error(e.getMessage());
+                        }
+                    }
+                }
+                continue;
+            }
+            if (type == 3) {
+                List<String> groupPaths = privilegesInfo.getGroupPaths();
+                List<String> devicePaths = privilegesInfo.getDevicePaths();
+                List<String> timeseriesPaths = privilegesInfo.getTimeseriesPaths();
+                if (notNullAndNotZero(groupPaths) && groupPaths.size() == 1 && notNullAndNotZero(devicePaths)
+                    && devicePaths.size() == 1 && notNullAndNotZero(timeseriesPaths)) {
+                    String onlyGroupPath = groupPaths.get(0);
+                    String onlyDevicePath = devicePaths.get(0);
+                    for (String timeseriesPath : timeseriesPaths) {
+                        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root."
+                            + onlyGroupPath + "." + onlyDevicePath + "." + timeseriesPath;
+                        try {
+                            sessionPool.executeNonQueryStatement(sql);
+                        } catch (StatementExecutionException e) {
+                            logger.error(e.getMessage());
+                        } catch (IoTDBConnectionException e) {
+                            logger.error(e.getMessage());
+                        }
+                    }
+                }
+                continue;
+            }
+            throw new BaseException(ErrorCode.NO_TYPE, ErrorCode.NO_TYPE_MSG);
+        }
+    }
+
+
+    /**
+     * 判断集合不为空且长度大于0
+     */
+    private boolean notNullAndNotZero(List list) {
+        if (list != null && list.size() > 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private String executeQueryOneLine(SessionPool sessionPool, String sql, String queryField) throws BaseException {
+        try {
+            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+            int index = -1;
+            for (int i = 0; i < columnNames.size(); i++) {
+                if (queryField.equals(columnNames.get(i))) {
+                    index = i;
+                }
+            }
+            if (index == -1) {
+                throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+            }
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            if (batchSize > 0) {
+                if (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    return rowRecord.getFields().get(index).toString();
+                }
+            }
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        }
+        throw new BaseException(ErrorCode.NO_GROUP, ErrorCode.NO_GROUP_MSG);
+    }
+
+    private SqlResultVO executeQuery(SessionPool sessionPool, String sql, Boolean closePool) throws BaseException {
+        SqlResultVO sqlResultVO = new SqlResultVO();
+        List<List<String>> valuelist = new ArrayList<>();
+        try {
+            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            long start = System.currentTimeMillis();
+            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+            sqlResultVO.setMetaDataList(columnNames);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            // 记录行数
+            long count = 0;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    List<String> strList = new ArrayList<>();
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    count++;
+                    for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
+                        strList.add(field.toString());
+                    }
+                    valuelist.add(strList);
+                }
+                long end = System.currentTimeMillis();
+                double time = (end - start + 0.0d) / 1000;
+                String queryTime = time + "s";
+                sqlResultVO.setQueryTime(queryTime);
+                sqlResultVO.setLine(count);
+            }
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        } finally {
+            if (sessionPool != null && closePool) {
+                sessionPool.close();
+            }
+        }
+        sqlResultVO.setValueList(valuelist);
+        return sqlResultVO;
+    }
+
+    private SqlResultVO executeQuery(SessionPool sessionPool, String sql, Boolean closePool, String notStopKey, boolean timeFlag) throws BaseException {
+        SqlResultVO sqlResultVO = new SqlResultVO();
+        List<List<String>> valuelist = new ArrayList<>();
+        try {
+            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            long start = System.currentTimeMillis();
+            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+            sqlResultVO.setMetaDataList(columnNames);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            // 记录行数
+            long count = 0;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext() && QUERY_STOP.get(notStopKey)) {
+                    List<String> strList = new ArrayList<>();
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    if (timeFlag) {
+                        long timestamp = rowRecord.getTimestamp();
+                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+                        Date date = new Date(timestamp);
+                        String timeStr = simpleDateFormat.format(date);
+                        strList.add(timeStr);
+                    }
+                    count++;
+                    for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
+                        strList.add(field.toString());
+                    }
+                    valuelist.add(strList);
+                }
+                long end = System.currentTimeMillis();
+                double time = (end - start + 0.0d) / 1000;
+                String queryTime = time + "s";
+                sqlResultVO.setQueryTime(queryTime);
+                sqlResultVO.setLine(count);
+            }
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            if (e.getStatusCode() == 602) {
+                throw new BaseException(ErrorCode.NO_PRI_TIMESERIES_DATA, ErrorCode.NO_PRI_TIMESERIES_DATA_MSG);
+            }
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        } finally {
+            if (sessionPool != null && closePool) {
+                sessionPool.close();
+            }
+        }
+        sqlResultVO.setValueList(valuelist);
+        return sqlResultVO;
+    }
+
+
+    private <T> CountDTO executeQuery(Class<T> clazz, SessionPool sessionPool, String sql, Integer pageSize, Integer pageNum, String keyword)
+        throws BaseException {
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            List<T> results = new ArrayList<>();
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            int count = 0;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    count++;
+                    if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+                        T t = clazz.newInstance();
+                        List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+                        List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+                        for (int i = 0; i < fields.size(); i++) {
+                            Field field = clazz.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+                            field.setAccessible(true);
+                            field.set(t, fields.get(i).toString());
+                        }
+                        results.add(t);
+                    }
+                }
+            }
+            CountDTO countDTO = new CountDTO();
+            countDTO.setObjects(results);
+            countDTO.setTotalCount(count);
+            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+            countDTO.setTotalPage(totalPage);
+            return countDTO;
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        } catch (Exception e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+        }
+    }
+
+    private String executeQueryOneValue(SessionPool sessionPool, String sql) throws BaseException {
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            String value = null;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+                    value = fields.get(0).toString();
+                    break;
+                }
+            }
+            return value;
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            if (e.getStatusCode() == 602 && sql != null && sql.contains("select")) {
+                throw new BaseException(ErrorCode.NO_PRI_READ_TIMESERIES, ErrorCode.NO_PRI_READ_TIMESERIES_MSG);
+            }
+            throw new BaseException(ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+        }
+    }
+
+    private CountDTO executeQueryOneColumn(SessionPool sessionPool, String sql, Integer pageSize, Integer pageNum) throws BaseException {
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            List<String> values = new ArrayList<>();
+            int count = 0;
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    count++;
+                    if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+                        List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+                        values.add(fields.get(0).toString());
+                    }
+                }
+            }
+            CountDTO countDTO = new CountDTO();
+            countDTO.setObjects(values);
+            countDTO.setTotalCount(count);
+            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+            countDTO.setTotalPage(totalPage);
+            return countDTO;
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+        }
+    }
+
+    private List<String> executeQueryOneColumn(SessionPool sessionPool, String sql) throws BaseException {
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            Callable call = () -> sessionPool.executeQueryStatement(sql);
+            ExecutorService service = Executors.newFixedThreadPool(1);
+            Future submit = service.submit(call);
+            sessionDataSetWrapper = (SessionDataSetWrapper) submit.get(60, TimeUnit.SECONDS);
+            int batchSize = sessionDataSetWrapper.getBatchSize();
+            List<String> values = new ArrayList<>();
+            if (batchSize > 0) {
+                while (sessionDataSetWrapper.hasNext()) {
+                    RowRecord rowRecord = sessionDataSetWrapper.next();
+                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+                    values.add(fields.get(0).toString());
+                }
+            }
+            return values;
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+            if (e.getMessage().contains("600")) {
+                throw new BaseException(ErrorCode.WRONG_USER, ErrorCode.WRONG_USER_MSG);
+            }
+            throw new BaseException(ErrorCode.CONN_REFUSED, ErrorCode.CONN_REFUSED_MSG);
+        } catch (TimeoutException e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+        }
+    }
+
+
+    private List<PrivilegeInfo> privilegesStrSwitchToObject(SessionPool sessionPool, List<String> privileges) throws BaseException {
+        List<PrivilegeInfo> results = new ArrayList<>();
+        List<String> pathStr = new ArrayList<>();
+        List<List<String>> privilegeStr = new ArrayList<>();
+        HashMap<String, Boolean> rootPrivileges = new HashMap();
+        // 遍历集合 将路径和权限集合分别装 过程中 将root相关内容处理
+        for (int i = 0; i < privileges.size(); i++) {
+            String[] split = privileges.get(i).split(":");
+            String[] s = split[1].trim().split(" ");
+            String path = split[0].trim();
+            //为root特殊处理
+            if ("root".equals(path)) {
+                for (String s1 : s) {
+                    if (rootPrivileges.containsKey(s1)) {
+                        continue;
+                    }
+                    rootPrivileges.put(s1, true);
+                }
+                continue;
+            }
+            List<String> list = new ArrayList<>();
+            pathStr.add(path);
+            // 其他粒度下 只需要存储SPECIAL_PRIVILEGES四种权限
+            for (String s1 : s) {
+                if (SPECIAL_PRIVILEGES.containsKey(s1)) {
+                    list.add(s1);
+                    continue;
+                }
+                // 除了root这一层级 其他此权限不生效 不添加进root权限集合
+                if (NO_NEED_PRIVILEGES.equals(s1)) {
+                    continue;
+                }
+                if (rootPrivileges.containsKey(s1)) {
+                    continue;
+                }
+                rootPrivileges.put(s1, true);
+            }
+            privilegeStr.add(list);
+        }
+        // 先处理root 生成对象
+        Set<String> strings = rootPrivileges.keySet();
+        List<String> rootPrivilege = Arrays.asList(strings.toArray(new String[0]));
+        if (rootPrivilege != null && rootPrivilege.size() > 0) {
+            PrivilegeInfo privilegeInfo = new PrivilegeInfo();
+            privilegeInfo.setType(0);
+            privilegeInfo.setPrivileges(rootPrivilege);
+            results.add(privilegeInfo);
+        }
+        // 处理非root  String存储形式 "权限1 权限2 权限3.." List存储相同并集下的path路径
+        Map<String, List<String>> privilegeOne = new HashMap<>();
+        Map<String, List<String>> privilegeTwo = new HashMap<>();
+        Map<String, List<String>> privilegeThree = new HashMap<>();
+        for (int i = 0; i < pathStr.size(); i++) {
+            String s = pathStr.get(i);
+            List<String> list = privilegeStr.get(i);
+            String str = String.join(" ", list);
+            // 通过路径获取所属粒度
+            int type = findType(sessionPool, s);
+            if (type == 1) {
+                // 判断相同的权限集合 放入同一list
+                if (privilegeOne.containsKey(str)) {
+                    List<String> typeList = privilegeOne.get(str);
+                    typeList.add(s);
+                    continue;
+                }
+                ArrayList<String> newStr = new ArrayList();
+                newStr.add(s);
+                privilegeOne.put(str, newStr);
+                continue;
+            }
+            if (type == 2) {
+                // 判断相同的权限集合 放入同一list
+                if (privilegeTwo.containsKey(str)) {
+                    List<String> typeList = privilegeTwo.get(str);
+                    // 相同粒度 同一范围下做前缀判断 相同则为一个并集
+                    int existEnd = typeList.get(0).lastIndexOf(".");
+                    int end = s.lastIndexOf(".");
+                    if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
+                        typeList.add(s);
+                        continue;
+                    }
+                }
+                ArrayList<String> newStr = new ArrayList();
+                newStr.add(s);
+                privilegeTwo.put(str, newStr);
+                continue;
+            }
+            if (type == 3) {
+                if (privilegeThree.containsKey(str)) {
+                    List<String> typeList = privilegeThree.get(str);
+                    int existEnd = typeList.get(0).lastIndexOf(".");
+                    int end = s.lastIndexOf(".");
+                    if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
+                        typeList.add(s);
+                        continue;
+                    }
+                }
+                ArrayList<String> newStr = new ArrayList();
+                newStr.add(s);
+                privilegeThree.put(str, newStr);
+            }
+        }
+        Set<String> oneKeys = privilegeOne.keySet();
+        Set<String> twoKeys = privilegeTwo.keySet();
+        Set<String> threeKeys = privilegeThree.keySet();
+        // 封装成PrivilegeInfo返回 字符串处理
+        for (String oneKey : oneKeys) {
+            PrivilegeInfo oneInfo = new PrivilegeInfo();
+            List<String> groupPath = new ArrayList<>();
+            List<String> list = privilegeOne.get(oneKey);
+            for (String s : list) {
+                String groupName = s.replaceFirst("root.", "");
+                groupPath.add(groupName);
+            }
+            List<String> privilegesOne = Arrays.asList(oneKey.split(" "));
+            String sql = "show storage group";
+            List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
+            List<String> allGroupPaths = new ArrayList<>();
+            for (String s : allGroupPathsStr) {
+                String field = s.replaceFirst("root.", "");
+                allGroupPaths.add(field);
+            }
+            // 展示数据
+            oneInfo.setType(1);
+            oneInfo.setPrivileges(privilegesOne);
+            // allxxx内容为前端编辑修改时需要的数据
+            oneInfo.setGroupPaths(groupPath);
+            oneInfo.setAllGroupPaths(allGroupPaths);
+            results.add(oneInfo);
+        }
+        for (String twoKey : twoKeys) {
+            PrivilegeInfo twoInfo = new PrivilegeInfo();
+            List<String> groupPath = new ArrayList<>();
+            List<String> devicePath = new ArrayList<>();
+            List<String> list = privilegeTwo.get(twoKey);
+            // 得到 组名、设备名、测点名  便于后续字符串操作
+            PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
+            groupPath.add(pathVO.getGroupName());
+            for (String s : list) {
+                String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
+                devicePath.add(deviceName);
+            }
+            List<String> privilegesTwo = Arrays.asList(twoKey.split(" "));
+            String sql = "show storage group";
+            List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
+            List<String> allGroupPaths = new ArrayList<>();
+            for (String s : allGroupPathsStr) {
+                String field = s.replaceFirst("root.", "");
+                allGroupPaths.add(field);
+            }
+            int end = list.get(0).lastIndexOf(".");
+            sql = "show devices " + list.get(0).substring(0, end) + ".*";
+            List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
+            List<String> allDevicePaths = new ArrayList<>();
+            for (String s : allDevicePathsStr) {
+                String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
+                allDevicePaths.add(field);
+            }
+            // 展示数据
+            twoInfo.setType(2);
+            twoInfo.setPrivileges(privilegesTwo);
+            twoInfo.setGroupPaths(groupPath);
+            twoInfo.setDevicePaths(devicePath);
+            // allxxx内容为前端编辑修改时需要的数据
+            twoInfo.setAllGroupPaths(allGroupPaths);
+            twoInfo.setAllDevicePaths(allDevicePaths);
+            results.add(twoInfo);
+        }
+        for (String threeKey : threeKeys) {
+            PrivilegeInfo threeInfo = new PrivilegeInfo();
+            List<String> groupPath = new ArrayList<>();
+            List<String> devicePath = new ArrayList<>();
+            List<String> timeseriesPath = new ArrayList<>();
+            List<String> list = privilegeThree.get(threeKey);
+            // 得到 组名、设备名、测点名  便于后续字符串操作
+            PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
+            groupPath.add(pathVO.getGroupName());
+            devicePath.add(pathVO.getDeviceName());
+            for (String s : list) {
+                String timeseriesName = s.replaceFirst("root." + pathVO.getGroupName() + "." + pathVO.getDeviceName() + ".", "");
+                timeseriesPath.add(timeseriesName);
+            }
+            List<String> privilegesOne = Arrays.asList(threeKey.split(" "));
+            String sql = "show storage group";
+            List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
+            List<String> allGroupPaths = new ArrayList<>();
+            for (String s : allGroupPathsStr) {
+                String field = s.replaceFirst("root.", "");
+                allGroupPaths.add(field);
+            }
+            sql = "show devices root." + pathVO.getGroupName() + ".*";
+            List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
+            List<String> allDevicePaths = new ArrayList<>();
+            for (String s : allDevicePathsStr) {
+                String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
+                allDevicePaths.add(deviceName);
+            }
+            int end = list.get(0).lastIndexOf(".");
+            sql = "show timeseries " + list.get(0).substring(0, end) + ".*";
+            List<String> allTimeseriesPathsStr = executeQueryOneColumn(sessionPool, sql);
+            List<String> allTimeseriesPaths = new ArrayList<>();
+            for (String s : allTimeseriesPathsStr) {
+                String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
+                allTimeseriesPaths.add(field);
+            }
+            // 展示数据
+            threeInfo.setType(3);
+            threeInfo.setPrivileges(privilegesOne);
+            threeInfo.setGroupPaths(groupPath);
+            threeInfo.setDevicePaths(devicePath);
+            threeInfo.setTimeseriesPaths(timeseriesPath);
+            // allxxx内容为前端编辑修改时需要的数据
+            threeInfo.setAllGroupPaths(allGroupPaths);
+            threeInfo.setAllDevicePaths(allDevicePaths);
+            threeInfo.setAllTimeseriesPaths(allTimeseriesPaths);
+            results.add(threeInfo);
+        }
+        return results;
+    }
+
+    private PathVO splitPathToPathVO(SessionPool sessionPool, String s) throws BaseException {
+        PathVO pathVO = new PathVO();
+        while (!"root".equals(s)) {
+            String sql = "count devices " + s;
+            Integer isDevice = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+            sql = "count storage group " + s;
+            Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+            // 为测点
+            if (isDevice == 0 && isGroup == 0) {
+                int mid = s.lastIndexOf(".");
+                String timeseriesName = s.substring(mid + 1);
+                pathVO.setTimeseriesName(timeseriesName);
+                s = s.substring(0, mid);
+                continue;
+            }
+            // 既是存储组也是实体
+            if (isDevice == 1 && isGroup == 1) {
+                String deviceName = s.replaceFirst("root.", "");
+                String groupName = s.replaceFirst("root.", "");
+                pathVO.setGroupName(groupName);
+                pathVO.setDeviceName(deviceName);
+                break;
+            }
+            // 是存储组 判断是否还为实体
+            if (isDevice > 1 && isGroup == 1) {
+                sql = "show devices " + s;
+                List<String> list = executeQueryOneColumn(sessionPool, sql);
+                if (list.contains(s)) {
+                    String deviceName = s.replaceFirst("root.", "");
+                    String groupName = s.replaceFirst("root.", "");
+                    pathVO.setGroupName(groupName);
+                    pathVO.setDeviceName(deviceName);
+                    break;
+                }
+                String groupName = s.replaceFirst("root.", "");
+                pathVO.setGroupName(groupName);
+            }
+            // 为存储组
+            if (isDevice == 0 && isGroup == 1) {
+                String groupName = s.replaceFirst("root.", "");
+                pathVO.setGroupName(groupName);
+                break;
+            }
+            // 实体 实体之下还可以有实体 需要遍历有多少层级
+            if (isDevice >= 1 && isGroup == 0) {
+                String oldS = s;
+                while (true) {
+                    int mid = s.lastIndexOf(".");
+                    s = s.substring(0, mid);
+                    sql = "count storage group " + s;
+                    isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+                    if (isGroup > 0) {
+                        String deviceName = oldS.replaceFirst(s + ".", "");
+                        String groupName = s.replaceFirst("root.", "");
+                        pathVO.setGroupName(groupName);
+                        pathVO.setDeviceName(deviceName);
+                        break;
+                    }
+                }
+                break;
+            }
+        }
+        return pathVO;
+    }
+
+    private int findType(SessionPool sessionPool, String s) throws BaseException {
+        // 主要用于判断s路径是否已经不存在 iotdb存在已删除路径的权限还会展示出来的问题
+        String sql = "count timeseries " + s;
+        SessionDataSetWrapper sessionDataSetWrapper = null;
+        try {
+            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+        } catch (IoTDBConnectionException e) {
+            logger.error(e.getMessage());
+            return -1;
+        } catch (StatementExecutionException e) {
+            logger.error(e.getMessage());
+            return -1;
+        } finally {
+            if (sessionDataSetWrapper != null) {
+                sessionDataSetWrapper.close();
+            }
+        }
+        sql = "count storage group " + s;
+        Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+        if (isGroup == 1) {
+            return 1;
+        }
+        // 无效路径 既不是root 也不是存储组 不展示到页面
+        if (isGroup > 1) {
+            return -1;
+        }
+        sql = "count devices " + s;
+        Integer isDevices = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+        if (isDevices == 1) {
+            return 2;
+        }
+        return 3;
+    }
+
+    private List<TSEncoding> handleEncodingStr(List<String> encoding) {
+        List<TSEncoding> list = new ArrayList<>();
+        for (String s : encoding) {
+            switch (s) {
+                case "PLAIN":
+                    list.add(TSEncoding.PLAIN);
+                    break;
+                case "PLAIN_DICTIONARY":
+                    list.add(TSEncoding.PLAIN_DICTIONARY);
+                    break;
+                case "RLE":
+                    list.add(TSEncoding.RLE);
+                    break;
+                case "DIFF":
+                    list.add(TSEncoding.DIFF);
+                    break;
+                case "TS_2DIFF":
+                    list.add(TSEncoding.TS_2DIFF);
+                    break;
+                case "BITMAP":
+                    list.add(TSEncoding.BITMAP);
+                    break;
+                case "GORILLA_V1":
+                    list.add(TSEncoding.GORILLA_V1);
+                    break;
+                case "REGULAR":
+                    list.add(TSEncoding.REGULAR);
+                    break;
+                case "GORILLA":
+                    list.add(TSEncoding.GORILLA);
+                    break;
+            }
+        }
+        return list;
+    }
+
+    private List<Object> handleValueStr(List<String> values, List<TSDataType> types) throws BaseException {
+        List<Object> list = new ArrayList<>();
+        for (int i = 0; i < types.size(); i++) {
+            TSDataType type = types.get(i);
+            if (type == TSDataType.BOOLEAN) {
+                Integer booleanNum = Integer.valueOf(values.get(i));
+                Boolean flag = null;
+                if (booleanNum == 0) {
+                    flag = false;
+                }
+                if (booleanNum == 1) {
+                    flag = true;
+                }
+                if (flag != null) {
+                    list.add(flag);
+                    continue;
+                }
+                throw new BaseException(ErrorCode.DB_BOOL_WRONG, ErrorCode.DB_BOOL_WRONG_MSG);
+            }
+            if (type == TSDataType.INT32 || type == TSDataType.INT64) {
+                Integer intNum = Integer.valueOf(values.get(i));
+                list.add(intNum);
+                continue;
+            }
+            if (type == TSDataType.FLOAT) {
+                Float floatNum = Float.valueOf(values.get(i));
+                list.add(floatNum);
+                continue;
+            }
+            if (type == TSDataType.DOUBLE) {
+                Double doubleNum = Double.valueOf(values.get(i));
+                list.add(doubleNum);
+                continue;
+            }
+            list.add(values.get(i));
+        }
+        return list;
+    }
+
+    private List<TSDataType> handleTypeStr(List<String> types) throws BaseException {
+        List<TSDataType> list = new ArrayList<>();
+        for (String type : types) {
+            TSDataType tsDataType;
+            switch (type) {
+                case "BOOLEAN":
+                    tsDataType = TSDataType.BOOLEAN;
+                    break;
+                case "INT32":
+                    tsDataType = TSDataType.INT32;
+                    break;
+                case "INT64":
+                    tsDataType = TSDataType.INT64;
+                    break;
+                case "FLOAT":
+                    tsDataType = TSDataType.FLOAT;
+                    break;
+                case "DOUBLE":
+                    tsDataType = TSDataType.DOUBLE;
+                    break;
+                case "TEXT":
+                    tsDataType = TSDataType.TEXT;
+                    break;
+                default:
+                    throw new BaseException(ErrorCode.DB_DATATYPE_WRONG, ErrorCode.DB_DATATYPE_WRONG_MSG);
+            }
+            list.add(tsDataType);
+        }
+        return list;
+    }
+
+
+    public static java.sql.Connection getConnection(Connection connection) throws BaseException {
+        String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
+        String url = "jdbc:iotdb://" + connection.getHost() + ":" + connection.getPort() + "/";
+        String username = connection.getUsername();
+        String password = connection.getPassword();
+        java.sql.Connection conn;
+        try {
+            Class.forName(driver);
+            conn = DriverManager.getConnection(url, username, password);
+        } catch (ClassNotFoundException e) {
+            throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
+        } catch (SQLException e) {
+            throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
+        }
+        return conn;
+    }
+
+    public static SessionPool getSessionPool(Connection connection) throws BaseException {
+        String host = connection.getHost();
+        Integer port = connection.getPort();
+        String username = connection.getUsername();
+        String password = connection.getPassword();
+        SessionPool sessionPool = null;
+        try {
+            sessionPool = new SessionPool(host, port, username, password, 3);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+        }
+        return sessionPool;
+    }
+//    public static SessionPool getSession(Connection connection) throws BaseException {
+//        if(sessionPool == null){
+//            host = connection.getHost();
+//            port = connection.getPort();
+//            username = connection.getUsername();
+//            password = connection.getPassword();
+//            sessionPool = new SessionPool(host,port,username,password,3);
+//            return sessionPool;
+//        }
+//        if(host == connection.getHost() && port.equals(connection.getPort()) && username == connection.getUsername() && password == connection.getPassword()){
+//            return sessionPool;
+//        }
+//        sessionPool.close();
+//        host = connection.getHost();
+//        port = connection.getPort();
+//        username = connection.getUsername();
+//        password = connection.getPassword();
+//        sessionPool = new SessionPool(host,port,username,password,3);
+//        return sessionPool;
+//    }
+
+    private void closeConnection(java.sql.Connection conn) throws BaseException {
+        try {
+            if (conn != null) {
+                conn.close();
+            }
+        } catch (SQLException e) {
+            throw new BaseException(ErrorCode.CLOSE_DBCONN_FAIL, ErrorCode.CLOSE_DBCONN_FAIL_MSG);
+        }
+    }
+
+    private String handlerPrivilegeStrToSql(String privilege, String userName, String roleName) {
+        int i = privilege.indexOf(":");
+        String path = privilege.substring(0, i).trim();
+        String[] privileges = privilege.substring(i + 1).trim().split(" ");
+        int len = privileges.length;
+        if (len == 0) {
+            return null;
+        }
+        StringBuilder str = new StringBuilder();
+        if (userName != null) {
+            str.append("grant user " + userName + " privileges ");
+        } else {
+            str.append("grant role " + roleName + " privileges ");
+        }
+        for (int j = 0; i < len - 1; j++) {
+            str.append("'" + privileges[j] + "',");
+        }
+        str.append("'" + privileges[len - 1] + "' on " + path);
+        return str.toString();
+    }
+
+
+    private SqlResultVO sqlQuery(java.sql.Connection conn, String sql) throws BaseException {
+        PreparedStatement statement = null;
+        ResultSet resultSet = null;
+        try {
+            statement = conn.prepareStatement(sql);
+            resultSet = statement.executeQuery();
+            ResultSetMetaData metaData = resultSet.getMetaData();
+            int columnCount = metaData.getColumnCount();
+            SqlResultVO sqlResultVO = new SqlResultVO();
+            List<String> metaDataList = new ArrayList<>();
+            for (int i = 0; i < columnCount; i++) {
+                metaDataList.add(metaData.getColumnLabel(i + 1));
+            }
+            sqlResultVO.setMetaDataList(metaDataList);
+            List<List<String>> valuelist = new ArrayList<>();
+            while (resultSet.next()) {
+                List<String> strList = new ArrayList<>();
+                for (int i = 0; i < columnCount; i++) {
+                    strList.add(resultSet.getString(i + 1));
+                }
+                valuelist.add(strList);
+            }
+            sqlResultVO.setValueList(valuelist);
+            return sqlResultVO;
+        } catch (SQLException e) {
+            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+        } finally {
+            if (resultSet != null) {
+                try {
+                    resultSet.close();
+                } catch (SQLException e) {
+                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+                }
+            }
+            if (statement != null) {
+                try {
+                    statement.close();
+                } catch (SQLException e) {
+                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+                }
+            }
+            closeConnection(conn);
+        }
+    }
+
+    /**
+     * 防止sql注入对参数进行校验不能有空格
+     *
+     * @param field 拼接sql的字段
+     */
+    private void paramValid(String field) throws BaseException {
+        if (field != null) {
+            if (!field.matches("^[^ ]+$")) {
+                throw new BaseException(ErrorCode.SQL_PARAM_WRONG, ErrorCode.SQL_PARAM_WRONG_MSG);
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
new file mode 100644
index 0000000..52a6f65
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.MeasurementMapper;
+import org.apache.iotdb.admin.model.dto.DeviceDTO;
+import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
+import org.apache.iotdb.admin.model.entity.Measurement;
+import org.apache.iotdb.admin.service.MeasurementService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class MeasurementServiceImpl extends ServiceImpl<MeasurementMapper, Measurement> implements MeasurementService {
+
+    @Autowired
+    private MeasurementMapper measurementMapper;
+
+    private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
+
+    @Override
+    public void deleteMeasurementInfo(String host, String groupName) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.like("measurement_name", groupName);
+        try {
+            measurementMapper.delete(queryWrapper);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_MEASUREMENT_INFO_FAIL, ErrorCode.DELETE_MEASUREMENT_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void deleteMeasurementInfoByDeviceName(String host, String deviceName) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.like("measurement_name", deviceName);
+        try {
+            measurementMapper.delete(queryWrapper);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_MEASUREMENT_INFO_FAIL, ErrorCode.DELETE_MEASUREMENT_INFO_FAIL_MSG);
+        }
+    }
+
+    @Override
+    public void setMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException {
+        List<String> descriptions = new ArrayList<>();
+        List<String> measurements = new ArrayList<>();
+        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+            descriptions.add(deviceDTO.getDescription());
+            measurements.add(deviceDTO.getTimeseries());
+        }
+        for (int i = 0; i < measurements.size(); i++) {
+            Measurement mea = new Measurement();
+            mea.setDescription(descriptions.get(i));
+            mea.setMeasurementName(measurements.get(i));
+            mea.setHost(host);
+            int flag = measurementMapper.insert(mea);
+            if (flag <= 0) {
+                throw new BaseException(ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
+            }
+        }
+    }
+
+    @Override
+    public String getDescription(String host, String timeseries) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("host", host);
+        queryWrapper.eq("measurement_name", timeseries);
+        Measurement measurement = null;
+        try {
+            measurement = measurementMapper.selectOne(queryWrapper);
+        } catch (Exception e) {
+            logger.error(e.getMessage());
+            throw new BaseException(ErrorCode.GET_MSM_DES_FAIL, ErrorCode.GET_MSM_DES_FAIL_MSG);
+        }
+        if (measurement != null) {
+            return measurement.getDescription();
+        }
+        return null;
+    }
+
+    @Override
+    public void updateMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException {
+        List<String> descriptions = new ArrayList<>();
+        List<String> measurements = new ArrayList<>();
+        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+            descriptions.add(deviceDTO.getDescription());
+            measurements.add(deviceDTO.getTimeseries());
+        }
+        for (int i = 0; i < measurements.size(); i++) {
+            QueryWrapper queryWrapper = new QueryWrapper();
+            queryWrapper.eq("host", host);
+            queryWrapper.eq("measurement_name", measurements.get(i));
+            Measurement existMeasurement = measurementMapper.selectOne(queryWrapper);
+            // 未创建的测点
+            if (existMeasurement == null) {
+                Measurement mea = new Measurement();
+                mea.setDescription(descriptions.get(i));
+                mea.setMeasurementName(measurements.get(i));
+                mea.setHost(host);
+                int flag = measurementMapper.insert(mea);
+                if (flag <= 0) {
+                    throw new BaseException(ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
+                }
+                continue;
+            }
+            // 已创建的测点更新描述
+            existMeasurement.setDescription(descriptions.get(i));
+            int flag = measurementMapper.updateById(existMeasurement);
+            if (flag <= 0) {
+                throw new BaseException(ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
+            }
+        }
+    }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
new file mode 100644
index 0000000..76dd6ae
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.QueryMapper;
+import org.apache.iotdb.admin.model.entity.Query;
+import org.apache.iotdb.admin.model.vo.QueryVO;
+import org.apache.iotdb.admin.service.QueryService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class QueryServiceImpl extends ServiceImpl<QueryMapper, Query> implements QueryService {
+
+    @Autowired
+    private QueryMapper queryMapper;
+
+    @Override
+    public void save(Integer serverId, Query inputQuery) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("connection_id", serverId);
+        queryWrapper.eq("query_name", inputQuery.getQueryName());
+        Query query = queryMapper.selectOne(queryWrapper);
+        if (query == null) {
+            Query newQuery = new Query();
+            newQuery.setConnectionId(serverId);
+            newQuery.setQueryName(inputQuery.getQueryName());
+            newQuery.setSqls(inputQuery.getSqls());
+            queryMapper.insert(newQuery);
+            return;
+        }
+        throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
+    }
+
+    @Override
+    public void update(Integer serverId, Query inputQuery) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("id", inputQuery.getId());
+        Query query = queryMapper.selectOne(queryWrapper);
+        if (query != null) {
+            query.setQueryName(inputQuery.getQueryName());
+            query.setSqls(inputQuery.getSqls());
+            queryMapper.updateById(query);
+            return;
+        }
+        throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
+    }
+
+    @Override
+    public List<QueryVO> getQueryList(Integer serverId) {
+        QueryWrapper<Query> queryWrapper = new QueryWrapper();
+        queryWrapper.eq("connection_id", serverId);
+        List<Query> queries = queryMapper.selectList(queryWrapper);
+        List<QueryVO> queryVOList = new ArrayList<>();
+        for (Query query : queries) {
+            QueryVO queryVO = new QueryVO();
+            BeanUtils.copyProperties(query, queryVO);
+            queryVOList.add(queryVO);
+        }
+        return queryVOList;
+    }
+
+    @Override
+    public void deleteQuery(Integer queryId) throws BaseException {
+        QueryWrapper<Query> queryWrapper = new QueryWrapper();
+        queryWrapper.eq("id", queryId);
+        int flag = queryMapper.delete(queryWrapper);
+        if (flag <= 0) {
+            throw new BaseException(ErrorCode.QUERY_NOT_EXIST, ErrorCode.QUERY_NOT_EXIST_MSG);
+        }
+    }
+
+    @Override
+    public Query getQuery(Integer queryId) throws BaseException {
+        QueryWrapper<Query> queryWrapper = new QueryWrapper();
+        queryWrapper.eq("id", queryId);
+        Query query = queryMapper.selectOne(queryWrapper);
+        if (query == null) {
+            throw new BaseException(ErrorCode.QUERY_NOT_EXIST, ErrorCode.QUERY_NOT_EXIST_MSG);
+        }
+        return query;
+    }
+
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/UserServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..8610c39
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/UserServiceImpl.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.UserMapper;
+import org.apache.iotdb.admin.model.entity.User;
+import org.apache.iotdb.admin.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
+
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Autowired
+    private BCryptPasswordEncoder bCryptPasswordEncoder;
+
+    @Override
+    public User login(String name, String password) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("name", name);
+        User user = userMapper.selectOne(queryWrapper);
+        if (user != null) {
+            if (!bCryptPasswordEncoder.matches(password, user.getPassword())) {
+                throw new BaseException(ErrorCode.LOGIN_FAIL_PWD, ErrorCode.LOGIN_FAIL_PWD_MSG);
+            }
+            return user;
+        } else {
+            throw new BaseException(ErrorCode.LOGIN_FAIL_USER, ErrorCode.LOGIN_FAIL_USER_MSG);
+        }
+    }
+
+    @Override
+    public void insert(User user) throws BaseException {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.eq("name", user.getName());
+        User existUser = userMapper.selectOne(queryWrapper);
+        if (existUser == null) {
+            user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
+            try {
+                userMapper.insert(user);
+            } catch (Exception e) {
+                throw new BaseException(ErrorCode.INSERT_USER_FAIL, ErrorCode.INSERT_USER_FAIL_MSG);
+            }
+        } else {
+            throw new BaseException(ErrorCode.USER_EXIST, ErrorCode.USER_EXIST_MSG);
+        }
+    }
+
+    @Override
+    public void delete(Integer userId) throws BaseException {
+        try {
+            userMapper.deleteById(userId);
+        } catch (Exception e) {
+            throw new BaseException(ErrorCode.DELETE_USER_FAIL, ErrorCode.DELETE_USER_FAIL_MSG);
+        }
+    }
+
+
+}
diff --git a/backend/src/main/resources/META-INF/app.properties b/backend/src/main/resources/META-INF/app.properties
new file mode 100644
index 0000000..ca3692a
--- /dev/null
+++ b/backend/src/main/resources/META-INF/app.properties
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+app.name=test
\ No newline at end of file
diff --git a/backend/src/main/resources/application-dev.properties b/backend/src/main/resources/application-dev.properties
new file mode 100644
index 0000000..4a14685
--- /dev/null
+++ b/backend/src/main/resources/application-dev.properties
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# 指定日志配置文件的位置
+logging.config=classpath:log4j2.xml
+
+# 配置端口号和上下文根
+server.port=8080
+server.servlet.context-path=/api
+
+# 指定数据源和连接驱动
+# 如下配置数据源的方式会导致项目重新打包后数据丢失,仅为了开发时方便测试,实际部署项目时请参考application-prod.properties文件配置
+spring.datasource.url=jdbc:sqlite::resource:sqlite/iotdb.db
+spring.datasource.driver-class-name=org.sqlite.JDBC
\ No newline at end of file
diff --git a/backend/src/main/resources/application-prod.properties b/backend/src/main/resources/application-prod.properties
new file mode 100644
index 0000000..b6b57f8
--- /dev/null
+++ b/backend/src/main/resources/application-prod.properties
@@ -0,0 +1,30 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# 指定日志配置文件的位置
+logging.config=classpath:log4j2-prod.xml
+
+# 配置端口号和上下文根
+server.port=8081
+server.servlet.context-path=/api
+
+# 指定数据源和连接驱动
+# 请将backend/src/main/resources/sqlite下的iotdb.db文件复制一份到你的服务器上,并将以下路径修改为你的iotdb.db文件路径
+spring.datasource.url=jdbc:sqlite:/usr/local/iotdb/data/iotdb1.db
+spring.datasource.driver-class-name=org.sqlite.JDBC
\ No newline at end of file
diff --git a/backend/src/main/resources/application-test.properties b/backend/src/main/resources/application-test.properties
new file mode 100644
index 0000000..2d959b0
--- /dev/null
+++ b/backend/src/main/resources/application-test.properties
@@ -0,0 +1,26 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+logging.config=classpath:log4j2.xml
+
+server.port=8079
+server.servlet.context-path=/api
+
+spring.datasource.url=jdbc:sqlite:/usr/local/iotdb/data/iotdb.db
+spring.datasource.driver-class-name=org.sqlite.JDBC
\ No newline at end of file
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
new file mode 100644
index 0000000..5aa2fca
--- /dev/null
+++ b/backend/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# 指定配置文件。dev、prod、test分别表示开发、生产、测试环境
+spring.profiles.active=dev
\ No newline at end of file
diff --git a/backend/src/main/resources/log4j2-prod.xml b/backend/src/main/resources/log4j2-prod.xml
new file mode 100644
index 0000000..3a0f519
--- /dev/null
+++ b/backend/src/main/resources/log4j2-prod.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<configuration status="ERROR">
+
+    <Properties>
+        <!--应用名-->
+        <property name="app">IoTDB-Workbench</property>
+        <property name="log.root.level">INFO</property>
+        <property name="log.home">/data/applogs/app-prod</property>
+        <property name="log.default.pattern">%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [${app}] %l %m%n</property>
+        <property name="log.stats.pattern">%m%n</property>
+    </Properties>
+
+    <appenders>
+        <Console name="STDOUT" target="SYSTEM_OUT">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+        </Console>
+
+        <RollingFile name="ROLLING_DEBUG" fileName="${log.home}/${app}_debug.log"
+                     filePattern="${log.home}/debug.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <!--<DirectWriteRolloverStrategy maxFiles="10"/>-->
+            <Filters>
+                <ThresholdFilter level="DEBUG" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+        <RollingFile name="ROLLING_INFO" fileName="${log.home}/${app}_info.log"
+                     filePattern="${log.home}/info.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <Filters>
+                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
+                <ThresholdFilter level="INFO" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+        <RollingFile name="ROLLING_WARN" fileName="${log.home}/${app}_warn.log"
+                     filePattern="${log.home}/warn.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <Filters>
+                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
+                <ThresholdFilter level="WARN" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+        <RollingFile name="ROLLING_ERROR" fileName="${log.home}/${app}_error.log"
+                     filePattern="${log.home}/error.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <!--<DirectWriteRolloverStrategy maxFiles="10"/>-->
+            <Filters>
+                <ThresholdFilter level="ERROR" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+
+
+    </appenders>
+
+    <loggers>
+        <!--level日志级别: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
+        <Root level="${log.root.level}">
+            <AppenderRef ref="STDOUT"/>
+            <AppenderRef ref="ROLLING_INFO"/>
+            <AppenderRef ref="ROLLING_WARN"/>
+            <AppenderRef ref="ROLLING_ERROR"/>
+            <!--<AppenderRef ref="ROLLING_DEBUG"/>-->
+        </Root>
+
+
+        <!--<logger name="com.alibaba" level="ERROR"/>-->
+        <!--<logger name="org" level="ERROR"/>-->
+
+    </loggers>
+
+</configuration>
+
diff --git a/backend/src/main/resources/log4j2.xml b/backend/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..21772ee
--- /dev/null
+++ b/backend/src/main/resources/log4j2.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<configuration status="ERROR">
+
+    <Properties>
+        <!--应用名-->
+        <property name="app">IoTDB-Workbench</property>
+        <property name="log.root.level">INFO</property>
+        <property name="log.home">/data/applogs/app-test</property>
+        <property name="log.default.pattern">%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p] [${app}] %l %m%n</property>
+        <property name="log.stats.pattern">%m%n</property>
+    </Properties>
+
+    <appenders>
+        <Console name="STDOUT" target="SYSTEM_OUT">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+        </Console>
+
+        <RollingFile name="ROLLING_DEBUG" fileName="${log.home}/${app}_debug.log"
+                     filePattern="${log.home}/debug.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <!--<DirectWriteRolloverStrategy maxFiles="10"/>-->
+            <Filters>
+                <ThresholdFilter level="DEBUG" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+        <RollingFile name="ROLLING_INFO" fileName="${log.home}/${app}_info.log"
+                     filePattern="${log.home}/info.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <Filters>
+                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
+                <ThresholdFilter level="INFO" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+        <RollingFile name="ROLLING_WARN" fileName="${log.home}/${app}_warn.log"
+                     filePattern="${log.home}/warn.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <Filters>
+                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
+                <ThresholdFilter level="WARN" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+        <RollingFile name="ROLLING_ERROR" fileName="${log.home}/${app}_error.log"
+                     filePattern="${log.home}/error.log.%i">
+            <PatternLayout>
+                <Pattern>${log.default.pattern}</Pattern>
+            </PatternLayout>
+            <Policies>
+                <SizeBasedTriggeringPolicy size="100 MB" />
+            </Policies>
+            <DefaultRolloverStrategy max="10"/>
+            <!--<DirectWriteRolloverStrategy maxFiles="10"/>-->
+            <Filters>
+                <ThresholdFilter level="ERROR" onMatch="ACCEPT"/>
+            </Filters>
+        </RollingFile>
+
+
+
+    </appenders>
+
+    <loggers>
+        <!--level日志级别: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
+        <Root level="${log.root.level}">
+            <AppenderRef ref="STDOUT"/>
+            <AppenderRef ref="ROLLING_INFO"/>
+            <AppenderRef ref="ROLLING_WARN"/>
+            <AppenderRef ref="ROLLING_ERROR"/>
+            <!--<AppenderRef ref="ROLLING_DEBUG"/>-->
+        </Root>
+
+
+        <!--<logger name="com.alibaba" level="ERROR"/>-->
+        <!--<logger name="org" level="ERROR"/>-->
+
+    </loggers>
+
+</configuration>
+
diff --git a/backend/src/test/java/org/apache/iotdb/admin/DemoJDBC.java b/backend/src/test/java/org/apache/iotdb/admin/DemoJDBC.java
new file mode 100644
index 0000000..dcf0780
--- /dev/null
+++ b/backend/src/test/java/org/apache/iotdb/admin/DemoJDBC.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * ${DESCRIPTION}
+ *
+ * @author fanli
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class DemoJDBC {
+
+
+    @Test
+    public void testSelect() {
+
+    }
+}
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
new file mode 100644
index 0000000..df531d9
--- /dev/null
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.Rollback;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.RequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.net.InetAddress;
+import java.util.Calendar;
+
+@SpringBootTest
+class ConnectionControllerTest {
+
+    private MockMvc mvc;
+
+    @Autowired
+    private WebApplicationContext wac;
+
+    private String token = getToken();
+
+    @Transactional
+    @Rollback
+    @Test
+    void saveOrUpdateConnection() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"alias\": \"tttt\",\n" +
+                "  \"host\": \"localhost\",\n" +
+                "  \"password\": \"root\",\n" +
+                "  \"port\": 6667,\n" +
+                "  \"userId\": 1,\n" +
+                "  \"username\": \"root\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Transactional
+    @Rollback
+    @Test
+    void deleteConnection() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .delete("http://127.0.0.1:8080/api/servers/1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Test
+    void getConnection() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Test
+    void getAllConnections() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers")
+            .contextPath("/api")
+            .param("userId", "1")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    private String getToken() {
+        Calendar instance = Calendar.getInstance();
+        try {
+            instance.add(Calendar.HOUR, 24);
+            String token = JWT.create()
+                .withClaim("userId", 1)
+                .withClaim("name", "root")
+                .withExpiresAt(instance.getTime())
+                .sign(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()));
+            return token;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java
new file mode 100644
index 0000000..d724a47
--- /dev/null
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java
@@ -0,0 +1,380 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.RequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.net.InetAddress;
+import java.util.Calendar;
+
+@SpringBootTest
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+class IotDBControllerTest {
+
+    private MockMvc mvc;
+    @Autowired
+    private WebApplicationContext wac;
+
+
+    private String token = getToken();
+
+    private String getToken() {
+        Calendar instance = Calendar.getInstance();
+        try {
+            instance.add(Calendar.HOUR, 24);
+            String token = JWT.create()
+                .withClaim("userId", 1)
+                .withClaim("name", "root")
+                .withExpiresAt(instance.getTime())
+                .sign(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()));
+            return token;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    @Order(1)
+    @Test
+    void saveStorageGroup() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/storageGroups")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"description\": \"a group\",\n" +
+                "  \"groupName\": \"group1\",\n" +
+                "  \"ttl\": 1,\n" +
+                "  \"ttlUnit\": \"day\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+        request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/storageGroups")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"description\": \"a group2\",\n" +
+                "  \"groupName\": \"group2\",\n" +
+                "  \"ttl\": 2,\n" +
+                "  \"ttlUnit\": \"day\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(2)
+    @Test
+    void getAllStorageGroupsInfo() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/info")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(3)
+    @Test
+    void getAllStorageGroups() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(4)
+    @Test
+    void getStorageGroup() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(5)
+    @Test
+    void deleteStorageGroup() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .delete("http://127.0.0.1:8080/api/servers/1/storageGroups/group2")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(6)
+    @Test
+    void saveOrUpdateDevice() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"description\": \"a device1\",\n" +
+                "  \"deviceDTOList\": [\n" +
+                "    {\n" +
+                "      \"dataType\": \"INT64\",\n" +
+                "      \"description\": \"a dev1\",\n" +
+                "      \"encoding\": \"PLAIN\",\n" +
+                "      \"timeseries\": \"s1\"\n" +
+                "    }\n" +
+                "  ],\n" +
+                "  \"deviceName\": \"dev1\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+        request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"description\": \"a device1\",\n" +
+                "  \"deviceDTOList\": [\n" +
+                "    {\n" +
+                "      \"dataType\": \"INT64\",\n" +
+                "      \"description\": \"a dev1\",\n" +
+                "      \"encoding\": \"PLAIN\",\n" +
+                "      \"timeseries\": \"s1\"\n" +
+                "    }\n" +
+                "  ],\n" +
+                "  \"deviceName\": \"dev2\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(7)
+    @Test
+    void getDeviceInfo() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/dev1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(8)
+    @Test
+    void getDevicesInfoByGroupName() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/info")
+            .param("pageSize", "10")
+            .param("pageNum", "1")
+            .param("keyword", "d")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(9)
+    @Test
+    void getDevicesByGroupName() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(10)
+    @Test
+    void deleteDevice() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .delete("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/dev2")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(11)
+    @Test
+    void getMeasurementsByDeviceName() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/dev1/info")
+            .param("pageSize", "10")
+            .param("pageNum", "1")
+            .param("keyword", "s")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(12)
+    @Test
+    void getMeasurementInfo() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/dev1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(13)
+    @Test
+    void getTimeseries() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/dev1/timeseries")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(14)
+    @Test
+    void deleteTimeseries() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .delete("http://127.0.0.1:8080/api/servers/1/storageGroups/group1/devices/dev1/timeseries/s1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(15)
+    @Test
+    void setIotDBUser() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/users")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"password\": \"1234\",\n" +
+                "  \"userName\": \"lisi\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(16)
+    @Test
+    void getIotDBUserList() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/users")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(17)
+    @Test
+    void setUserPrivileges() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/users/lisi")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"cancelPrivileges\": [],\n" +
+                "  \"delDevicePaths\": [],\n" +
+                "  \"delGroupPaths\": [],\n" +
+                "  \"delTimeseriesPaths\": [],\n" +
+                "  \"devicePaths\": [],\n" +
+                "  \"groupPaths\": [\n" +
+                "    \"group1\"\n" +
+                "  ],\n" +
+                "  \"privileges\": [\n" +
+                "    \"CREATE_TIMESERIES\"\n" +
+                "  ],\n" +
+                "  \"timeseriesPaths\": [],\n" +
+                "  \"type\": 1\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(18)
+    @Test
+    void getIotDBUser() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .get("http://127.0.0.1:8080/api/servers/1/users/lisi")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(19)
+    @Test
+    void updatePassword() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .post("http://127.0.0.1:8080/api/servers/1/users/pwd")
+            .contextPath("/api")
+            .content("{\n" +
+                "  \"password\": \"2222\",\n" +
+                "  \"userName\": \"lisi\"\n" +
+                "}")
+            .header("Authorization", token)
+            .header("Content-Type", "application/json");
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(20)
+    @Test
+    void deleteIotDBUser() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .delete("http://127.0.0.1:8080/api/servers/1/users/lisi")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+    @Order(21)
+    @Test
+    void deleteStorageGroup2() throws Exception {
+        mvc = MockMvcBuilders.webAppContextSetup(wac).build();
+        RequestBuilder request = MockMvcRequestBuilders
+            .delete("http://127.0.0.1:8080/api/servers/1/storageGroups/group1")
+            .contextPath("/api")
+            .header("Authorization", token);
+        mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
+    }
+
+}
\ No newline at end of file
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java
new file mode 100644
index 0000000..cc06ff8
--- /dev/null
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
... 179 lines suppressed ...


[iotdb-web-workbench] 34/34: Merge pull request #17 from ljn55966005/dev-0.13.0-metircs

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit a234f79bda1d0d13cdf6fb4c653dc54f75bd1251
Merge: 1c98cd8 29a7091
Author: Jialin Qiao <qj...@mails.tsinghua.edu.cn>
AuthorDate: Wed Aug 3 20:30:51 2022 +0800

    Merge pull request #17 from ljn55966005/dev-0.13.0-metircs

 backend/pom.xml                                    |    4 +-
 .../iotdb/admin/common/exception/ErrorCode.java    |    4 +
 .../iotdb/admin/controller/FileController.java     |   11 +
 .../iotdb/admin/controller/IotDBController.java    |  110 +-
 .../iotdb/admin/controller/MetricsController.java  |  166 ++
 .../ViewModeMapper.java}                           |   16 +-
 .../admin/model/dto/AuthorityPrivilegeDTO.java     |    1 +
 ...tyPrivilegeDTO.java => DataModelDetailDTO.java} |   12 +-
 ...uthorityPrivilegeDTO.java => QueryInfoDTO.java} |   14 +-
 .../{vo/NodeTreeVO.java => entity/ViewMode.java}   |   34 +-
 .../QueryDataDo.java}                              |   12 +-
 .../apache/iotdb/admin/model/vo/DataCountVO.java   |    5 +-
 .../apache/iotdb/admin/model/vo/DataModelVO.java   |   10 +
 .../model/vo/{GroupInfoVO.java => GroupInfo.java}  |    3 +-
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |    6 +-
 ...{DataCountVO.java => JVMMetricsListDataVO.java} |    8 +-
 ...ntVO.java => MetircsQueryClassificationVO.java} |   11 +-
 .../{NodeTreeVO.java => MetricsChartDataVO.java}   |   27 +-
 .../{DataCountVO.java => MetricsConnectionVO.java} |   10 +-
 .../{DataCountVO.java => MetricsDataCountVO.java}  |   14 +-
 ...taCountVO.java => MetricsDataForDiagramVO.java} |   10 +-
 ...{DataCountVO.java => MetricsDataForListVO.java} |   12 +-
 .../{DataCountVO.java => MetricsListDataVO.java}   |   12 +-
 .../apache/iotdb/admin/model/vo/NodeTreeVO.java    |    9 +
 ...DataCountVO.java => QueryClassificationVO.java} |   11 +-
 .../vo/{DataCountVO.java => QueryData1VO.java}     |    9 +-
 .../{DataCountVO.java => QueryDataForListVO.java}  |   12 +-
 .../vo/{DataCountVO.java => QueryDataStrVO.java}   |   15 +-
 .../vo/{DataCountVO.java => QueryDataStrVO1.java}  |    9 +-
 .../vo/{DataCountVO.java => QueryDataVO.java}      |   15 +-
 .../vo/{DataCountVO.java => QueryInfoVO.java}      |   15 +-
 .../vo/{DataCountVO.java => QueryMetricsVO.java}   |   12 +-
 .../apache/iotdb/admin/service/IotDBService.java   |   33 +-
 .../MetricsResultService.java}                     |   29 +-
 .../apache/iotdb/admin/service/MetricsService.java |   55 +
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 2029 +++++++++++++++++++-
 .../service/impl/MetricsResultServiceImpl.java     |  297 +++
 .../admin/service/impl/MetricsServiceImpl.java     | 1760 +++++++++++++++++
 backend/src/main/resources/sqlite/iotdb.db         |  Bin 36864 -> 53248 bytes
 39 files changed, 4535 insertions(+), 287 deletions(-)


[iotdb-web-workbench] 07/34: init init add apache license files

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit b6c31c77528ec289365051750a1429241b0a7b64
Author: 小果花 <lo...@foxmail.com>
AuthorDate: Wed Aug 25 14:54:57 2021 +0800

    init
    init
    add apache license files
---
 backend/.gitignore                                 |  10 +++
 backend/doc/code-guidelines.zip                    | Bin 0 -> 9427033 bytes
 ...57\246\347\273\206\351\205\215\347\275\256.jpg" | Bin 0 -> 286055 bytes
 .../doc/image/maven\351\205\215\347\275\256.jpg"   | Bin 0 -> 96532 bytes
 ...05\215\347\275\256\346\226\207\344\273\266.png" | Bin 0 -> 128969 bytes
 ...26\207\344\273\266\344\275\215\347\275\256.png" | Bin 0 -> 60565 bytes
 backend/doc/image/pom.PNG                          | Bin 0 -> 60121 bytes
 ...20\257\345\212\250\346\210\220\345\212\237.PNG" | Bin 0 -> 153254 bytes
 "backend/doc/image/\346\211\223\345\214\205.png"   | Bin 0 -> 22644 bytes
 ...05\215\347\275\256\346\226\207\344\273\266.PNG" | Bin 0 -> 15910 bytes
 backend/gradlew.bat                                |  89 +++++++++++++++++++++
 backend/src/main/resources/sqlite/iotdb.db         | Bin 0 -> 36864 bytes
 12 files changed, 99 insertions(+)

diff --git a/backend/.gitignore b/backend/.gitignore
new file mode 100755
index 0000000..406063e
--- /dev/null
+++ b/backend/.gitignore
@@ -0,0 +1,10 @@
+.gradle
+.gradle/
+gradle/
+build/
+.idea/
+.mvn/
+*.iml
+target/
+*.versionsBackup
+
diff --git a/backend/doc/code-guidelines.zip b/backend/doc/code-guidelines.zip
new file mode 100644
index 0000000..629bd4f
Binary files /dev/null and b/backend/doc/code-guidelines.zip differ
diff --git "a/backend/doc/image/maven\350\257\246\347\273\206\351\205\215\347\275\256.jpg" "b/backend/doc/image/maven\350\257\246\347\273\206\351\205\215\347\275\256.jpg"
new file mode 100644
index 0000000..c9d1bb7
Binary files /dev/null and "b/backend/doc/image/maven\350\257\246\347\273\206\351\205\215\347\275\256.jpg" differ
diff --git "a/backend/doc/image/maven\351\205\215\347\275\256.jpg" "b/backend/doc/image/maven\351\205\215\347\275\256.jpg"
new file mode 100644
index 0000000..5e8d188
Binary files /dev/null and "b/backend/doc/image/maven\351\205\215\347\275\256.jpg" differ
diff --git "a/backend/doc/image/nginx\351\205\215\347\275\256\346\226\207\344\273\266.png" "b/backend/doc/image/nginx\351\205\215\347\275\256\346\226\207\344\273\266.png"
new file mode 100644
index 0000000..6a9e085
Binary files /dev/null and "b/backend/doc/image/nginx\351\205\215\347\275\256\346\226\207\344\273\266.png" differ
diff --git "a/backend/doc/image/nginx\351\205\215\347\275\256\346\226\207\344\273\266\344\275\215\347\275\256.png" "b/backend/doc/image/nginx\351\205\215\347\275\256\346\226\207\344\273\266\344\275\215\347\275\256.png"
new file mode 100644
index 0000000..6a594f0
Binary files /dev/null and "b/backend/doc/image/nginx\351\205\215\347\275\256\346\226\207\344\273\266\344\275\215\347\275\256.png" differ
diff --git a/backend/doc/image/pom.PNG b/backend/doc/image/pom.PNG
new file mode 100644
index 0000000..1b2bfce
Binary files /dev/null and b/backend/doc/image/pom.PNG differ
diff --git "a/backend/doc/image/\345\220\257\345\212\250\346\210\220\345\212\237.PNG" "b/backend/doc/image/\345\220\257\345\212\250\346\210\220\345\212\237.PNG"
new file mode 100644
index 0000000..1c501c9
Binary files /dev/null and "b/backend/doc/image/\345\220\257\345\212\250\346\210\220\345\212\237.PNG" differ
diff --git "a/backend/doc/image/\346\211\223\345\214\205.png" "b/backend/doc/image/\346\211\223\345\214\205.png"
new file mode 100644
index 0000000..04e9f01
Binary files /dev/null and "b/backend/doc/image/\346\211\223\345\214\205.png" differ
diff --git "a/backend/doc/image/\351\205\215\347\275\256\346\226\207\344\273\266.PNG" "b/backend/doc/image/\351\205\215\347\275\256\346\226\207\344\273\266.PNG"
new file mode 100644
index 0000000..9b7ac6f
Binary files /dev/null and "b/backend/doc/image/\351\205\215\347\275\256\346\226\207\344\273\266.PNG" differ
diff --git a/backend/gradlew.bat b/backend/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/backend/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/backend/src/main/resources/sqlite/iotdb.db b/backend/src/main/resources/sqlite/iotdb.db
new file mode 100644
index 0000000..5a23664
Binary files /dev/null and b/backend/src/main/resources/sqlite/iotdb.db differ


[iotdb-web-workbench] 05/34: Add GH actions

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 6a80ff02a672220457b3c8acc2973654455aa121
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 10:54:52 2021 +0200

    Add GH actions
---
 .github/workflows/default.yml | 55 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml
new file mode 100644
index 0000000..efd1c77
--- /dev/null
+++ b/.github/workflows/default.yml
@@ -0,0 +1,55 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Main Mac and Linux
+
+on:
+  push:
+    branches:
+      - master
+      - 'rel/*'
+      - Vector
+    paths-ignore:
+      - 'docs/**'
+  pull_request:
+    branches:
+      - master
+      - 'rel/*'
+      - cluster_new
+      - Vector
+    paths-ignore:
+      - 'docs/**'
+  # allow manually run the action:
+  workflow_dispatch:
+
+env:
+  MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3
+
+jobs:
+  unix:
+    strategy:
+      fail-fast: false
+      max-parallel: 20
+      matrix:
+        java: [ 8, 11, 16 ]
+        os: [ ubuntu-latest, macos-latest ]
+    runs-on: ${{ matrix.os}}
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up JDK ${{ matrix.java }}
+        uses: actions/setup-java@v1
+        with:
+          java-version: ${{ matrix.java }}
+      - name: Cache Maven packages
+        uses: actions/cache@v2
+        with:
+          path: ~/.m2
+          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+          restore-keys: ${{ runner.os }}-m2-
+      - name: Check Apache Rat
+        run: cd backend && mvn -B apache-rat:check -P site -P code-coverage
+      - name: IT/UT Test
+        shell: bash
+        # we do not compile client-cpp for saving time, it is tested in client.yml
+        run:  cd backend && mvn -B clean post-integration-test -Dtest.port.closed=true -P '!testcontainer'


[iotdb-web-workbench] 33/34: Merge pull request #22 from wd94/v1.3pr

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 1c98cd85ce40e24b9ee53924cbfc3c1d139d8a98
Merge: 161c24e c64dae3
Author: Jialin Qiao <qj...@mails.tsinghua.edu.cn>
AuthorDate: Wed Aug 3 20:30:29 2022 +0800

    Merge pull request #22 from wd94/v1.3pr

 frontend/package-lock.json                         |  16 +-
 frontend/public/index.html                         |   3 +
 frontend/src/App.vue                               |  43 +-
 frontend/src/components/FormTable.vue              |   2 +-
 frontend/src/components/StandTable.vue             |  24 +-
 frontend/src/components/TreeSelect.vue             |  18 +
 .../useElementResize.js.js}                        |   0
 .../variables.scss => hooks/useLanguageWatch.js}   |  53 +-
 frontend/src/i18n/cn.js                            |  95 +++-
 frontend/src/i18n/de.js                            |  95 +++-
 frontend/src/i18n/en.js                            |  93 ++-
 frontend/src/main.js                               |   8 +
 frontend/src/plugins/element_plus.js               |  23 +-
 frontend/src/plugins/event_bus.js                  |  18 +
 frontend/src/plugins/index.js                      |  18 +
 frontend/src/router/index.js                       |  17 +
 frontend/src/store/index.js                        |  18 +
 frontend/src/styles/element.scss                   |  57 +-
 frontend/src/styles/variables.scss                 |   5 +-
 frontend/src/util/axios.js                         |   2 +-
 frontend/src/util/constant.js                      |  18 +
 frontend/src/util/export.js                        |  18 +
 frontend/src/util/setOperation.js                  |  18 +
 frontend/src/views/About/index.vue                 |  15 +-
 frontend/src/views/Control/api/index.js            |  81 +++
 .../src/views/Control/components/indicator.vue     |  77 +++
 .../views/Control/components/indicatorChart.vue    | 115 ++++
 .../src/views/Control/components/indicatorList.vue | 370 ++++++++++++
 .../views/Control/components/indicatorPanel.vue    | 414 ++++++++++++++
 frontend/src/views/Control/components/query.vue    | 536 ++++++++++++++++++
 frontend/src/views/Control/hooks/useInitChart.js   | 625 +++++++++++++++++++++
 frontend/src/views/Control/index.vue               | 420 ++++++++++++++
 .../views/DataBaseM/components/dataListTree.vue    | 154 +++--
 frontend/src/views/DataBaseM/index.vue             |   6 +-
 frontend/src/views/Device/index.vue                |  24 +-
 frontend/src/views/DeviceMessage/index.vue         |  73 ++-
 frontend/src/views/Login/index.vue                 |  19 +-
 frontend/src/views/Root/index.vue                  |  34 +-
 frontend/src/views/Source/components/dataModal.vue |  37 +-
 .../src/views/Source/components/dataModalAll.vue   | 180 +++---
 .../src/views/Source/components/permitDialog.vue   |  22 +-
 .../views/Source/components/role/AuthManage.vue    |  18 +
 .../views/Source/components/role/DataManage.vue    |  18 +
 .../Source/components/role/DialogGrantUser.vue     |  18 +
 .../src/views/Source/components/role/Index.vue     |  18 +
 .../views/Source/components/role/PowerManage.vue   |  18 +
 .../src/views/Source/components/role/RoleInfo.vue  |  23 +-
 .../src/views/Source/components/role/RoleList.vue  |  22 +-
 frontend/src/views/Source/index.vue                |  69 ++-
 frontend/src/views/SqlSerch/index.vue              | 148 +++--
 frontend/src/views/storage/index.vue               |   9 +-
 frontend/src/views/storage/newStorage.vue          |   2 +-
 frontend/vue.config.js                             |  20 +-
 53 files changed, 3913 insertions(+), 334 deletions(-)


[iotdb-web-workbench] 17/34: Revert "Allow css to fail (#3)"

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit c1cddfbd63def705c9b9e89ca406a503d7416088
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Mon Sep 20 16:48:46 2021 +0200

    Revert "Allow css to fail (#3)"
    
    This reverts commit abf021a8
---
 .github/workflows/frontend.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index ffd2581..58a3b31 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -30,7 +30,6 @@ jobs:
       - name: lint
         run: cd frontend && npm run lint
       - name: lint-css
-        continue-on-error: true
         run: cd frontend && npm run lint-css
     
   test:


[iotdb-web-workbench] 15/34: Create frontend jobs (#1)

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 28a05bbd0a08acde2a5cb0836544304085998247
Author: Niklas Merz <ni...@linux.com>
AuthorDate: Sat Sep 11 17:06:45 2021 +0200

    Create frontend jobs (#1)
    
    * Frontend action
    
    * Allow continue on error for lint steps
    
    * Multiple jobs
    
    * Use same settings as default workflow
---
 .github/workflows/frontend.yml | 61 +++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 2c19095..58a3b31 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -1,7 +1,4 @@
-# This workflow will build a Java project with Maven
-# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
-
-name: Frontend
+name: frontend
 
 on:
   push:
@@ -22,33 +19,35 @@ on:
   # allow manually run the action:
   workflow_dispatch:
 
-env:
-  MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3
-
-# TODO make npm specific workflow
-
 jobs:
-  unix:
-    strategy:
-      fail-fast: false
-      max-parallel: 20
-      matrix:
-        java: [ 8, 11, 13 ]
-        os: [ ubuntu-latest, macos-latest ]
-    runs-on: ${{ matrix.os}}
-
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@master
+      - name: npm install
+        run: cd frontend && npm install
+      - name: lint
+        run: cd frontend && npm run lint
+      - name: lint-css
+        run: cd frontend && npm run lint-css
+    
+  test:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@master
+      - name: npm install
+        run: cd frontend && npm install
+      - name: test
+        run: cd frontend && npm run test:unit
+  
+  build:
+    runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
-      - name: Set up JDK ${{ matrix.java }}
-        uses: actions/setup-java@v1
-        with:
-          java-version: ${{ matrix.java }}
-      - name: Cache Maven packages
-        uses: actions/cache@v2
-        with:
-          path: ~/.m2
-          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
-          restore-keys: ${{ runner.os }}-m2-
-      - name: Unit Tests
-        shell: bash
-        run: cd frontend && npm install && npm run lint && npm run test:unit
+      - uses: actions/setup-node@master
+      - name: npm install
+        run: cd frontend && npm install
+      - name: Build
+        run: cd frontend && npm run build
\ No newline at end of file


[iotdb-web-workbench] 01/34: initialize iotdb-web-workbench

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 5b67e29d70355fe1e8a47c132e3d871f002ec3b3
Author: xiangdong huang <sa...@gmail.com>
AuthorDate: Tue Aug 17 13:55:57 2021 +0800

    initialize iotdb-web-workbench
---
 .gitignore     | 109 ++++++++++++++++++++
 LICENSE        | 236 ++++++++++++++++++++++++++++++++++++++++++++
 LICENSE-binary | 306 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 NOTICE         |  24 +++++
 NOTICE-binary  |  24 +++++
 README.md      |  26 +++++
 README_zh.md   |  26 +++++
 7 files changed, 751 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a0b9c7b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,109 @@
+**/*.pid
+**/gc.log*
+**/logs/*
+**/lib/**
+**/data/**
+
+# Python runtime file
+**/__pycache__/**
+
+# Eclipse IDE files
+**/.classpath
+**/.project
+**/.settings/
+# src/main/resources/
+# intellij IDE files
+**/*.iml
+**/.idea/
+**/*.log
+**/*.ipr
+**/*.iws
+# Apple OS X related
+**/.DS_Store
+derby-tsfile-db
+
+# build generated
+**/target/
+
+# intermediately generated locally
+
+tsfile-timeseries/src/main/resources/logback.out.out.xml
+tsfile-timeseries/src/main/resources/logback.out.xml
+tsfile-service/derby-tsfile-db/
+tsfile-timeseries/src/test/resources/data
+src/main/resources/metadata/mlog.txt
+tsfile-jdbc/src/main/resources/output/queryRes.csv
+
+*.txt
+
+*.jar
+*.gz
+*.tar.gz
+*.tar
+#src/test/resources/logback.xml
+
+### CSV ###
+*.csv
+### Maven ###
+grafana/target/
+!grafana/.mvn/wrapper/maven-wrapper.jar
+grafana/.mvn/
+
+grafana/logs/
+*.log
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+
+### NetBeans ###
+**/nbproject/private/
+**/nbbuild/
+**/dist/
+**/nbdist/
+**/.nb-gradle/
+grafana/data/
+
+### vscode project
+**/.vscode/
+
+
+grafana/data/test.csv
+**/lib/
+/target/
+*.tsfile
+tsfile/src/test/resources/*.ts
+
+### Apache release ###
+local-snapshots-dir/
+venv/
+
+partitions.tmp
+partitions
+node_identifier
+
+### temporary file of the distributed version ###
+remote/
+
+# gitpod
+.theia/
+
+classes/
+
+### Cmake files ###
+*.cmake
+Makefile
+**/CMakeFiles/
+
+### cluster test data
+node1/
+node2/
+node3/
+
+# Exclude copied license
+/client-py/LICENSE
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d84f2bd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,236 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
+--------------------------------------------------------------------------------
+                           APACHE IOTDB SUBCOMPONENTS
+--------------------------------------------------------------------------------
+
+The following class is copied from maven-wrapper (https://github.com/takari/maven-wrapper),
+which is under Apache License 2.0:
+
+./.mvn/wrapper/MavenWrapperDownloader.java
+
+--------------------------------------------------------------------------------
+
+The following class is modified from Apache commons-collections
+
+./tsfile/src/main/java/org/apache/iotdb/tsfile/utils/Murmur128Hash.java
+Relevant pr is: https://github.com/apache/commons-collections/pull/83/
+
+--------------------------------------------------------------------------------
+
+The following files include code modified from Michael Burman's gorilla-tsc project.
+
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/GorillaEncoderV2.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/IntGorillaEncoder.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/LongGorillaEncoder.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/SinglePrecisionEncoderV2.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/encoder/DoublePrecisionEncoderV2.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/GorillaDecoderV2.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/IntGorillaDecoder.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/LongGorillaDecoder.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/SinglePrecisionDecoderV2.java
+./tsfile/src/main/java/org/apache/iotdb/tsfile/encoding/decoder/DoublePrecisionDecoderV2.java
+
+Copyright: 2016-2018 Michael Burman and/or other contributors
+Project page: https://github.com/burmanm/gorilla-tsc
+License: http://www.apache.org/licenses/LICENSE-2.0
diff --git a/LICENSE-binary b/LICENSE-binary
new file mode 100644
index 0000000..ce5c2aa
--- /dev/null
+++ b/LICENSE-binary
@@ -0,0 +1,306 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
+
+================================================================
+APACHE IOTDB SUBCOMPONENTS:
+
+Apache IoTDB project includes a number of submodules with separate copyright notices
+and license terms. Your use of these submodules is subject to the terms and
+conditions of the following licenses.
+
+================================================================
+
+The binary distribution of this product bundles these dependencies under the
+following license. See licenses/ for text of these licenses.
+
+Apache Software Foundation License 2.0
+--------------------------------------
+commons-cli:commons-cli:1.3.1
+commons-codec:commons-codec:1.13
+org.apache.commons:commons-collections4:4.4
+commons-io:commons-io:2.5
+org.apache.commons:commons-lang3:3.8.1
+commons-lang:commons-lang:2.6
+com.nimbusds:content-type:2.0
+com.google.code.gson:gson:2.8.6
+com.google.guava.guava:24.1.1
+com.fasterxml.jackson.core:jackson-annotations:2.10.0
+com.fasterxml.jackson.core:jackson-core:2.10.0
+com.fasterxml.jackson.core:jackson-databind:2.10.0
+javax.inject:javax.inject:1
+net.jpountz.lz4:1.3.0
+com.github.stephenc.jcip:jcip-annotations:1.0-1
+com.github.ben-manes.caffeine:caffeine:2.9.1
+org.eclipse.jetty:jetty-http:9.4.24.v20191120
+org.eclipse.jetty:jetty-io:9.4.24.v20191120
+org.eclipse.jetty:jetty-security:9.4.24.v20191120
+org.eclipse.jetty:jetty-server:9.4.24.v20191120
+org.eclipse.jetty:jetty-servlet:9.4.24.v20191120
+org.eclipse.jetty:jetty-util:9.4.24.v20191120
+org.eclipse.jetty:jetty-webapp:9.4.24.v20191120
+org.eclipse.jetty:jetty-xml:9.4.24.v20191120
+io.jsonwebtoken:jjwt-api:0.10.7
+io.jsonwebtoken:jjwt-impl:0.10.7
+io.jsonwebtoken:jjwt-jackson:0.10.7
+net.minidev:json-smart:2.3
+com.google.code.findbugs:jsr305:3.0.2
+com.nimbusds:lang-tag:1.4.4
+com.librato.metrics:librato-java:2.1.0
+org.apache.thrift:libthrift:0.14.1
+io.dropwizard.metrics:metrics-core:3.2.6
+io.dropwizard.metrics:metrics-json:3.2.6
+io.dropwizard.metrics:metrics-jvm:3.2.6
+com.librato.metrics:metrics-librato:5.1.0
+de.fraunhofer.iosb.io.moquette:moquette-broker:0.14.3
+io.netty:netty-buffer:4.1.53.Final
+io.netty:netty-codec:4.1.53.Final
+io.netty:netty-codec-http:4.1.53.Final
+io.netty:netty-codec-mqtt:4.1.53.Final
+io.netty:netty-common:4.1.53.Final
+io.netty:netty-handler:4.1.53.Final
+io.netty:netty-resolver:4.1.53.Final
+io.netty:netty-transport:4.1.53.Final
+io.netty:netty-transport-native-epoll:4.1.53.Final:linux-x86_64
+io.netty:netty-transport-native-unix-common:4.1.53.Final
+com.nimbusds:nimbus-jose-jwt:8.14.1
+com.nimbusds:oauth2-oidc-sdk:8.3
+org.osgi:org.osgi.core:6.0.0
+org.osgi:osgi.cmpn:6.0.0
+org.ops4j.pax.jdbc:pax-jdbc-common:1.4.5
+org.xerial.snappy:snappy-java:1.1.8.4
+io.airlift.airline:0.8
+net.minidev:accessors-smart:1.2
+
+BSD 2-Clause
+------------
+jline:jline:2.14.5
+
+
+BSD 3-Clause
+------------
+org.antlr:antlr-runtime:4.8-1
+org.ow2.asm:asm:5.0.4
+org.jline:jline:3.10.0
+
+
+MIT License
+------------
+org.slf4j:slf4j-api
+me.tongfei:progressbar:0.7.3
+com.bugsnag:bugsnag:3.6.1
+org.slf4j:jcl-over-slf4j:1.7.25
+
+
+EPL 1.0
+------------
+com.h2database:h2-mvstore:1.4.199
+ch.qos.logback:logback-classic:1.2.3
+ch.qos.logback:logback-core:1.2.3
+
+
+CDDL 1.1
+------------
+javax.annotation:javax.annotation-api:1.3.2
+javax.servlet:javax.servlet-api:3.1.0
+javax.xml.bind:jaxb-api:2.4.0-b180725.0427
+org.glassfish.jaxb:jaxb-runtime:2.4.0-b180725.0644
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..e983e45
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,24 @@
+Apache IoTDB
+Copyright 2018-2021 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+============================================================================
+
+IoTDB project uses 4 Chinese Patents:
+* 201711384490X
+* 201810111712.9
+* 201711322631.5
+* 201711319331.1
+
+According to the Apache 2.0 License. The owner of the patents, Tsinghua University,
+grant the users the right to the use of patent under the requirement of Apache 2.0 License.
+
+============================================================================
+
+Apache Commons Collections
+Copyright 2001-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/NOTICE-binary b/NOTICE-binary
new file mode 100644
index 0000000..e983e45
--- /dev/null
+++ b/NOTICE-binary
@@ -0,0 +1,24 @@
+Apache IoTDB
+Copyright 2018-2021 The Apache Software Foundation.
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+============================================================================
+
+IoTDB project uses 4 Chinese Patents:
+* 201711384490X
+* 201810111712.9
+* 201711322631.5
+* 201711319331.1
+
+According to the Apache 2.0 License. The owner of the patents, Tsinghua University,
+grant the users the right to the use of patent under the requirement of Apache 2.0 License.
+
+============================================================================
+
+Apache Commons Collections
+Copyright 2001-2019 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..06ee6a0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,26 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+[English](./README.md) | [中文](./README_ZH.md)
+
+# Overview
+
+This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+
diff --git a/README_zh.md b/README_zh.md
new file mode 100644
index 0000000..06ee6a0
--- /dev/null
+++ b/README_zh.md
@@ -0,0 +1,26 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+[English](./README.md) | [中文](./README_ZH.md)
+
+# Overview
+
+This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
+


[iotdb-web-workbench] 06/34: Support till version 13

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 0ed1b608019c5806519a35772b7fd36828c3d8cd
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 11:01:52 2021 +0200

    Support till version 13
---
 .github/workflows/default.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml
index efd1c77..d0b7938 100644
--- a/.github/workflows/default.yml
+++ b/.github/workflows/default.yml
@@ -31,7 +31,7 @@ jobs:
       fail-fast: false
       max-parallel: 20
       matrix:
-        java: [ 8, 11, 16 ]
+        java: [ 8, 11, 13 ]
         os: [ ubuntu-latest, macos-latest ]
     runs-on: ${{ matrix.os}}
 


[iotdb-web-workbench] 22/34: enable issues

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 5e7d9170e38a1264fec1392af4431c9d14cc2ac4
Author: qiaojialin <64...@qq.com>
AuthorDate: Sat Oct 9 09:08:15 2021 +0800

    enable issues
---
 .asf.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.asf.yaml b/.asf.yaml
index 1366c39..842e2c2 100644
--- a/.asf.yaml
+++ b/.asf.yaml
@@ -27,4 +27,4 @@ github:
     - admin
   features:
     wiki: true
-    issue: true
\ No newline at end of file
+    issues: true
\ No newline at end of file


[iotdb-web-workbench] 03/34: feat(docs)添加apache 许可注释

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit dd0821f19ed61942bc4bf3730d2e5b3364222dc9
Author: huangrui <hu...@163.com>
AuthorDate: Thu Sep 2 17:49:35 2021 +0800

    feat(docs)添加apache 许可注释
---
 frontend/.eslintrc.js                              |  74 ++++++-----
 frontend/.prettierrc.js                            |  19 +++
 frontend/.stylelintrc.js                           |  21 ++-
 frontend/babel.config.js                           |  19 +++
 frontend/src/App.vue                               |   5 +
 frontend/src/components/Echarts.vue                |   5 +
 frontend/src/components/FormTable.vue              |   5 +
 frontend/src/components/HelloWorld.vue             |   5 +
 frontend/src/components/StandTable.vue             |   5 +
 frontend/src/directive/icon.js                     |  19 +++
 frontend/src/directive/index.js                    |  19 +++
 frontend/src/i18n/cn.js                            |  19 +++
 frontend/src/i18n/de.js                            |  19 +++
 frontend/src/i18n/en.js                            |  19 +++
 frontend/src/i18n/index.js                         |  19 +++
 frontend/src/main.js                               |  19 +++
 frontend/src/router/index.js                       |  19 +++
 frontend/src/store/dataBaseM/index.js              |  19 +++
 frontend/src/store/moduleA/index.js                |  19 +++
 frontend/src/store/storage/index.js                |  19 +++
 frontend/src/styles/element.scss                   |  19 +++
 frontend/src/styles/reset.scss                     | 142 +++++++++++++++++----
 frontend/src/styles/variables.scss                 |  21 ++-
 frontend/src/util/api_axios.js                     |  19 +++
 frontend/src/util/axios.js                         |  19 +++
 frontend/src/views/About/index.vue                 |   5 +
 .../views/DataBaseM/components/dataListTree.vue    |   5 +
 .../src/views/DataBaseM/components/iconTypes.vue   |   5 +
 .../src/views/DataBaseM/hooks/useElementResize.js  |  19 +++
 frontend/src/views/DataBaseM/index.vue             |   5 +
 frontend/src/views/Device/api/index.js             |  19 +++
 frontend/src/views/Device/index.vue                |   5 +
 frontend/src/views/DeviceMessage/api/index.js      |  19 +++
 .../src/views/DeviceMessage/components/action.vue  |   5 +
 frontend/src/views/DeviceMessage/index.vue         |   5 +
 frontend/src/views/Home.vue                        |   5 +
 frontend/src/views/Login/index.vue                 |   5 +
 frontend/src/views/Root/hooks/useLangSwitch.js     |  19 +++
 frontend/src/views/Root/index.vue                  |   5 +
 frontend/src/views/Source/components/empty.vue     |   5 +
 frontend/src/views/Source/components/newSource.vue |   5 +
 frontend/src/views/Source/index.vue                |   5 +
 frontend/src/views/SqlSerch/api/index.js           |  19 +++
 .../src/views/SqlSerch/components/codemirror.vue   |   5 +
 .../src/views/SqlSerch/components/eltooltip.vue    |   5 +
 .../src/views/SqlSerch/components/formserch.vue    |   5 +
 .../views/SqlSerch/components/formserchData.vue    |   5 +
 .../src/views/SqlSerch/components/sqlDrawer.vue    |   5 +
 frontend/src/views/SqlSerch/hooks/codemirror.js    |  19 +++
 frontend/src/views/SqlSerch/hooks/function.js      |  19 +++
 frontend/src/views/SqlSerch/hooks/keywords.js      |  19 +++
 frontend/src/views/SqlSerch/hooks/selectList.js    |  19 +++
 .../src/views/SqlSerch/hooks/useElementResize.js   |  19 +++
 frontend/src/views/SqlSerch/index.vue              |   5 +
 frontend/src/views/storage/index.vue               |   5 +
 frontend/src/views/storage/newStorage.vue          |   5 +
 frontend/vue.config.js                             |  19 +++
 57 files changed, 844 insertions(+), 57 deletions(-)

diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js
index 2bbdd2c..6dee65b 100644
--- a/frontend/.eslintrc.js
+++ b/frontend/.eslintrc.js
@@ -1,35 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 module.exports = {
-    root: true,
-    env: {
-        browser: true,
-        node: true,
+  root: true,
+  env: {
+    browser: true,
+    node: true,
+  },
+  extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier'],
+  parserOptions: {
+    parser: 'babel-eslint',
+    ecmaVersion: 7,
+    sourceType: 'module',
+    ecmaFeatures: {
+      jsx: true,
     },
-    extends: [
-        "plugin:vue/vue3-essential",
-        "eslint:recommended",
-        "@vue/prettier",
-    ],
-    parserOptions: {
-        parser: "babel-eslint",
-        ecmaVersion: 7,
-        sourceType: "module",
-        ecmaFeatures: {
-            jsx: true,
-        },
+  },
+  rules: {
+    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+  },
+  overrides: [
+    {
+      files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
+      env: {
+        mocha: true,
+      },
     },
-    rules: {
-        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
-        "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
-    },
-    overrides: [
-        {
-            files: [
-                "**/__tests__/*.{j,t}s?(x)",
-                "**/tests/unit/**/*.spec.{j,t}s?(x)",
-            ],
-            env: {
-                mocha: true,
-            },
-        },
-    ],
+  ],
 };
diff --git a/frontend/.prettierrc.js b/frontend/.prettierrc.js
index ac684b0..39027d1 100644
--- a/frontend/.prettierrc.js
+++ b/frontend/.prettierrc.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 module.exports = {
   tabWidth: 2,
   singleQuote: true,
diff --git a/frontend/.stylelintrc.js b/frontend/.stylelintrc.js
index fa6ec3d..fc0b58d 100644
--- a/frontend/.stylelintrc.js
+++ b/frontend/.stylelintrc.js
@@ -1,4 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 module.exports = {
-  extends: ["stylelint-config-standard-scss", "stylelint-config-prettier"],
+  extends: ['stylelint-config-standard-scss', 'stylelint-config-prettier'],
   rules: {},
 };
diff --git a/frontend/babel.config.js b/frontend/babel.config.js
index 25d8020..742f9ca 100644
--- a/frontend/babel.config.js
+++ b/frontend/babel.config.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 module.exports = {
   presets: ['@vue/cli-plugin-babel/preset'],
   plugins: [
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 4914bd6..bd6b8d3 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <router-view />
 </template>
diff --git a/frontend/src/components/Echarts.vue b/frontend/src/components/Echarts.vue
index 0e09ac6..d6ab738 100644
--- a/frontend/src/components/Echarts.vue
+++ b/frontend/src/components/Echarts.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div id="myChart" class="echartsBox"></div>
 </template>
diff --git a/frontend/src/components/FormTable.vue b/frontend/src/components/FormTable.vue
index 1fc9bb6..7c07c8b 100644
--- a/frontend/src/components/FormTable.vue
+++ b/frontend/src/components/FormTable.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <el-form :model="formData" :rules="rules" :inline="inline" :label-position="labelPosition" :class="(inline ? 'demo-form-inline' : '', 'form_style')">
     <el-form-item v-for="item of formItem" :key="item.itemID" :label="$t(item.label)" :prop="item.itemID" :style="{ width: item.labelWidth }">
diff --git a/frontend/src/components/HelloWorld.vue b/frontend/src/components/HelloWorld.vue
index a3d9977..b498bda 100644
--- a/frontend/src/components/HelloWorld.vue
+++ b/frontend/src/components/HelloWorld.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="hello">欢迎加入IoTDB前端开发</div>
 </template>
diff --git a/frontend/src/components/StandTable.vue b/frontend/src/components/StandTable.vue
index 09f01c3..4a02caf 100644
--- a/frontend/src/components/StandTable.vue
+++ b/frontend/src/components/StandTable.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div>
     <el-table
diff --git a/frontend/src/directive/icon.js b/frontend/src/directive/icon.js
index 38deee7..ab5fcd2 100644
--- a/frontend/src/directive/icon.js
+++ b/frontend/src/directive/icon.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 export default (app) => {
   app.directive('icon', {
     mounted(el, binding) {
diff --git a/frontend/src/directive/index.js b/frontend/src/directive/index.js
index 0cc975b..4464bed 100644
--- a/frontend/src/directive/index.js
+++ b/frontend/src/directive/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import icon from './icon.js';
 
 export default (app) => {
diff --git a/frontend/src/i18n/cn.js b/frontend/src/i18n/cn.js
index e675fd3..5f39d31 100644
--- a/frontend/src/i18n/cn.js
+++ b/frontend/src/i18n/cn.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import zhLocale from 'element-plus/lib/locale/lang/zh-cn';
 
 const cn = {
diff --git a/frontend/src/i18n/de.js b/frontend/src/i18n/de.js
index 822cbf1..83e16b5 100644
--- a/frontend/src/i18n/de.js
+++ b/frontend/src/i18n/de.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import deLocale from 'element-plus/lib/locale/lang/de';
 
 const de = {
diff --git a/frontend/src/i18n/en.js b/frontend/src/i18n/en.js
index 174c4ff..9ff584f 100644
--- a/frontend/src/i18n/en.js
+++ b/frontend/src/i18n/en.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import enLocale from 'element-plus/lib/locale/lang/en';
 
 const en = {
diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js
index 7a6602a..6a09651 100644
--- a/frontend/src/i18n/index.js
+++ b/frontend/src/i18n/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import en from './en.js';
 import de from './de.js';
 import cn from './cn.js';
diff --git a/frontend/src/main.js b/frontend/src/main.js
index f563dec..4f5b46e 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { createApp } from 'vue';
 import App from './App.vue';
 import router from './router';
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index b1d2c92..afa0ff9 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { createRouter, createWebHashHistory } from 'vue-router';
 import Root from '../views/Root';
 import Login from '../views/Login';
diff --git a/frontend/src/store/dataBaseM/index.js b/frontend/src/store/dataBaseM/index.js
index 7abf0ba..fb5b3c2 100644
--- a/frontend/src/store/dataBaseM/index.js
+++ b/frontend/src/store/dataBaseM/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 const dataBaseM = {
   state: () => {},
   mutations: {},
diff --git a/frontend/src/store/moduleA/index.js b/frontend/src/store/moduleA/index.js
index 347bd2e..6c83b0b 100644
--- a/frontend/src/store/moduleA/index.js
+++ b/frontend/src/store/moduleA/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 const moduleA = {
   state: () => {},
   mutations: {},
diff --git a/frontend/src/store/storage/index.js b/frontend/src/store/storage/index.js
index 7a81421..316ac3c 100644
--- a/frontend/src/store/storage/index.js
+++ b/frontend/src/store/storage/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 const storage = {
   state: () => {},
   mutations: {
diff --git a/frontend/src/styles/element.scss b/frontend/src/styles/element.scss
index 6e804cc..893ee8e 100644
--- a/frontend/src/styles/element.scss
+++ b/frontend/src/styles/element.scss
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 .el-button--primary {
   background-color: $theme-color !important;
   border-color: $theme-color !important;
diff --git a/frontend/src/styles/reset.scss b/frontend/src/styles/reset.scss
index 33992e5..1b34ca9 100644
--- a/frontend/src/styles/reset.scss
+++ b/frontend/src/styles/reset.scss
@@ -1,21 +1,103 @@
-  
-// http://meyerweb.com/eric/tools/css/reset/
-//  v2.0 | 20110126
-//  License: none (public domain)
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, embed,
-figure, figcaption, footer, header, hgroup,
-menu, nav, output, ruby, section, summary,
-time, mark, audio, video {
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
   margin: 0;
   padding: 0;
   border: 0;
@@ -24,21 +106,34 @@ time, mark, audio, video {
   vertical-align: baseline;
 }
 // HTML5 display-role reset for older browsers
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
   display: block;
 }
 body {
   line-height: 1;
 }
-ol, ul {
+ol,
+ul {
   list-style: none;
 }
-blockquote, q {
+blockquote,
+q {
   quotes: none;
 }
-blockquote:before, blockquote:after,
-q:before, q:after {
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
   content: '';
   content: none;
 }
@@ -46,4 +141,3 @@ table {
   border-collapse: collapse;
   border-spacing: 0;
 }
-
diff --git a/frontend/src/styles/variables.scss b/frontend/src/styles/variables.scss
index 069a9d3..8396746 100644
--- a/frontend/src/styles/variables.scss
+++ b/frontend/src/styles/variables.scss
@@ -1 +1,20 @@
-$theme-color: #4575F6;
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+$theme-color: #4575f6;
diff --git a/frontend/src/util/api_axios.js b/frontend/src/util/api_axios.js
index 146859c..a3c2a57 100644
--- a/frontend/src/util/api_axios.js
+++ b/frontend/src/util/api_axios.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import axios from '.axios';
 
 //获取实体下物理量列表
diff --git a/frontend/src/util/axios.js b/frontend/src/util/axios.js
index 112a07b..4d88491 100644
--- a/frontend/src/util/axios.js
+++ b/frontend/src/util/axios.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import axios from 'axios';
 import { ElMessage } from 'element-plus';
 import router from '../router';
diff --git a/frontend/src/views/About/index.vue b/frontend/src/views/About/index.vue
index c038498..73ab67e 100644
--- a/frontend/src/views/About/index.vue
+++ b/frontend/src/views/About/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="about">
     <div class="header">
diff --git a/frontend/src/views/DataBaseM/components/dataListTree.vue b/frontend/src/views/DataBaseM/components/dataListTree.vue
index 5b02d1f..426b66b 100644
--- a/frontend/src/views/DataBaseM/components/dataListTree.vue
+++ b/frontend/src/views/DataBaseM/components/dataListTree.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="data-list-tree">
     <div class="data-list-top">
diff --git a/frontend/src/views/DataBaseM/components/iconTypes.vue b/frontend/src/views/DataBaseM/components/iconTypes.vue
index 2200cd8..04feac8 100644
--- a/frontend/src/views/DataBaseM/components/iconTypes.vue
+++ b/frontend/src/views/DataBaseM/components/iconTypes.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <span class="iconTypes">
     <span v-if="data.type === 'connection'" class="custom-tree-node-icon"
diff --git a/frontend/src/views/DataBaseM/hooks/useElementResize.js b/frontend/src/views/DataBaseM/hooks/useElementResize.js
index 5eefe07..24db48e 100644
--- a/frontend/src/views/DataBaseM/hooks/useElementResize.js
+++ b/frontend/src/views/DataBaseM/hooks/useElementResize.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { ref } from 'vue';
 
 function useLangSwitch(domRef, dividerWidth) {
diff --git a/frontend/src/views/DataBaseM/index.vue b/frontend/src/views/DataBaseM/index.vue
index 1bb838d..128f12b 100644
--- a/frontend/src/views/DataBaseM/index.vue
+++ b/frontend/src/views/DataBaseM/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="databasem">
     <el-container class="content-container">
diff --git a/frontend/src/views/Device/api/index.js b/frontend/src/views/Device/api/index.js
index c721f75..c3047d0 100644
--- a/frontend/src/views/Device/api/index.js
+++ b/frontend/src/views/Device/api/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import axios from '@/util/axios.js';
 
 //获取实体详情
diff --git a/frontend/src/views/Device/index.vue b/frontend/src/views/Device/index.vue
index 50086eb..67d58a6 100644
--- a/frontend/src/views/Device/index.vue
+++ b/frontend/src/views/Device/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div style="padding: 20px">
     <form-table :form="form"></form-table>
diff --git a/frontend/src/views/DeviceMessage/api/index.js b/frontend/src/views/DeviceMessage/api/index.js
index ea5f0ec..063f2b0 100644
--- a/frontend/src/views/DeviceMessage/api/index.js
+++ b/frontend/src/views/DeviceMessage/api/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import axios from '@/util/axios.js';
 
 //获取实体详情
diff --git a/frontend/src/views/DeviceMessage/components/action.vue b/frontend/src/views/DeviceMessage/components/action.vue
index f6a9624..0c835c8 100644
--- a/frontend/src/views/DeviceMessage/components/action.vue
+++ b/frontend/src/views/DeviceMessage/components/action.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div :id="id" class="echartsBox"></div>
 </template>
diff --git a/frontend/src/views/DeviceMessage/index.vue b/frontend/src/views/DeviceMessage/index.vue
index ddb0a17..2db9cc8 100644
--- a/frontend/src/views/DeviceMessage/index.vue
+++ b/frontend/src/views/DeviceMessage/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div>
     <div class="headerbox">
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index 2a91db7..4d79cbb 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="home">
     <HelloWorld msg="Welcome to Your Vue.js App" />
diff --git a/frontend/src/views/Login/index.vue b/frontend/src/views/Login/index.vue
index b13ca0a..a634bc2 100644
--- a/frontend/src/views/Login/index.vue
+++ b/frontend/src/views/Login/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="login">
     <div class="header">
diff --git a/frontend/src/views/Root/hooks/useLangSwitch.js b/frontend/src/views/Root/hooks/useLangSwitch.js
index 5e14769..14dda60 100644
--- a/frontend/src/views/Root/hooks/useLangSwitch.js
+++ b/frontend/src/views/Root/hooks/useLangSwitch.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { ref } from 'vue';
 import i18n from '@/i18n/index';
 import enLocale from 'element-plus/lib/locale/lang/en';
diff --git a/frontend/src/views/Root/index.vue b/frontend/src/views/Root/index.vue
index cc39ead..e5a5194 100644
--- a/frontend/src/views/Root/index.vue
+++ b/frontend/src/views/Root/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="root">
     <el-container>
diff --git a/frontend/src/views/Source/components/empty.vue b/frontend/src/views/Source/components/empty.vue
index 77032d5..3bdcb5e 100644
--- a/frontend/src/views/Source/components/empty.vue
+++ b/frontend/src/views/Source/components/empty.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="empty-page">
     <div class="img"></div>
diff --git a/frontend/src/views/Source/components/newSource.vue b/frontend/src/views/Source/components/newSource.vue
index e4c2250..2c0f070 100644
--- a/frontend/src/views/Source/components/newSource.vue
+++ b/frontend/src/views/Source/components/newSource.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="new-source">
     <el-dialog
diff --git a/frontend/src/views/Source/index.vue b/frontend/src/views/Source/index.vue
index 467f1a0..90230aa 100644
--- a/frontend/src/views/Source/index.vue
+++ b/frontend/src/views/Source/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="source-detail-container">
     <div class="info-box">
diff --git a/frontend/src/views/SqlSerch/api/index.js b/frontend/src/views/SqlSerch/api/index.js
index 09f461f..926405f 100644
--- a/frontend/src/views/SqlSerch/api/index.js
+++ b/frontend/src/views/SqlSerch/api/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import axios from '@/util/axios.js';
 
 //用于查询器查询
diff --git a/frontend/src/views/SqlSerch/components/codemirror.vue b/frontend/src/views/SqlSerch/components/codemirror.vue
index 9f21076..816fa28 100644
--- a/frontend/src/views/SqlSerch/components/codemirror.vue
+++ b/frontend/src/views/SqlSerch/components/codemirror.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="font_fmiy">
     <textarea ref="textarea" @input="change(value)"></textarea>
diff --git a/frontend/src/views/SqlSerch/components/eltooltip.vue b/frontend/src/views/SqlSerch/components/eltooltip.vue
index 19e7404..e2fa8fc 100644
--- a/frontend/src/views/SqlSerch/components/eltooltip.vue
+++ b/frontend/src/views/SqlSerch/components/eltooltip.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <el-tooltip class="item" effect="light" :content="$t(label)" placement="top">
     <slot></slot>
diff --git a/frontend/src/views/SqlSerch/components/formserch.vue b/frontend/src/views/SqlSerch/components/formserch.vue
index b9960a6..7fb275e 100644
--- a/frontend/src/views/SqlSerch/components/formserch.vue
+++ b/frontend/src/views/SqlSerch/components/formserch.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div>
     <div class="serch_div">
diff --git a/frontend/src/views/SqlSerch/components/formserchData.vue b/frontend/src/views/SqlSerch/components/formserchData.vue
index f40edde..ba528fd 100644
--- a/frontend/src/views/SqlSerch/components/formserchData.vue
+++ b/frontend/src/views/SqlSerch/components/formserchData.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div>
     <div class="serch_div">
diff --git a/frontend/src/views/SqlSerch/components/sqlDrawer.vue b/frontend/src/views/SqlSerch/components/sqlDrawer.vue
index e98bc22..a44e509 100644
--- a/frontend/src/views/SqlSerch/components/sqlDrawer.vue
+++ b/frontend/src/views/SqlSerch/components/sqlDrawer.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="drawer">
     <el-dialog :title="$t('device.newquery')" v-model="centerDialogVisible" width="30%" center @close="centerDialogV">
diff --git a/frontend/src/views/SqlSerch/hooks/codemirror.js b/frontend/src/views/SqlSerch/hooks/codemirror.js
index be2f775..4b88ec5 100644
--- a/frontend/src/views/SqlSerch/hooks/codemirror.js
+++ b/frontend/src/views/SqlSerch/hooks/codemirror.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import keywords from './keywords';
 import selectList from './selectList';
 function handleShowHint(cmInstance) {
diff --git a/frontend/src/views/SqlSerch/hooks/function.js b/frontend/src/views/SqlSerch/hooks/function.js
index c2ae850..02f567f 100644
--- a/frontend/src/views/SqlSerch/hooks/function.js
+++ b/frontend/src/views/SqlSerch/hooks/function.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 const list = [
   {
     label: 'sqlserch.Aggregate',
diff --git a/frontend/src/views/SqlSerch/hooks/keywords.js b/frontend/src/views/SqlSerch/hooks/keywords.js
index 0a723ce..369b333 100644
--- a/frontend/src/views/SqlSerch/hooks/keywords.js
+++ b/frontend/src/views/SqlSerch/hooks/keywords.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 let keywords = [
   'COMPDEV',
   'TEXT',
diff --git a/frontend/src/views/SqlSerch/hooks/selectList.js b/frontend/src/views/SqlSerch/hooks/selectList.js
index 475db9c..e293e10 100644
--- a/frontend/src/views/SqlSerch/hooks/selectList.js
+++ b/frontend/src/views/SqlSerch/hooks/selectList.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 const selectList = {
   SET: ['SET STORAGE GROUP TO <FullPath>', 'SET TTL TO <StorageGroupPath> <Integer>'],
   CREATE: [
diff --git a/frontend/src/views/SqlSerch/hooks/useElementResize.js b/frontend/src/views/SqlSerch/hooks/useElementResize.js
index 0c7682e..d308c19 100644
--- a/frontend/src/views/SqlSerch/hooks/useElementResize.js
+++ b/frontend/src/views/SqlSerch/hooks/useElementResize.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { ref } from 'vue';
 
 function useLangSwitch(domRef, divwerHeight) {
diff --git a/frontend/src/views/SqlSerch/index.vue b/frontend/src/views/SqlSerch/index.vue
index ffc24b5..9b962e7 100644
--- a/frontend/src/views/SqlSerch/index.vue
+++ b/frontend/src/views/SqlSerch/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <el-container>
     <el-container>
diff --git a/frontend/src/views/storage/index.vue b/frontend/src/views/storage/index.vue
index 0fdd19e..a3b31e9 100644
--- a/frontend/src/views/storage/index.vue
+++ b/frontend/src/views/storage/index.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="storage-container">
     <div class="base-info">
diff --git a/frontend/src/views/storage/newStorage.vue b/frontend/src/views/storage/newStorage.vue
index 2fefc3c..a651807 100644
--- a/frontend/src/views/storage/newStorage.vue
+++ b/frontend/src/views/storage/newStorage.vue
@@ -1,3 +1,8 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
+copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
+copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
+IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+
 <template>
   <div class="new-storage-container">
     <p>{{ $t('storagePage.alias') }}:{{ alias }}</p>
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index 47e57b0..f038053 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 const path = require('path');
 function resolve(dir) {
   return path.join(__dirname, dir);


[iotdb-web-workbench] 18/34: Merge pull request #4 from JulianFeinauer/haungrui777/master

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit b1f00b98589c3168d5b84af4006ecf4bb130cc47
Merge: fd390fd c1cddfb
Author: Julian <j....@pragmaticminds.de>
AuthorDate: Mon Sep 20 16:57:19 2021 +0200

    Merge pull request #4 from JulianFeinauer/haungrui777/master
    
    Frontend

 .github/workflows/default.yml                      |     2 +-
 .github/workflows/frontend.yml                     |    53 +
 frontend/.browserslistrc                           |     3 +
 frontend/.eslintignore                             |     1 +
 frontend/.eslintrc.js                              |    47 +
 frontend/.gitignore                                |    23 +
 frontend/.prettierrc.js                            |    24 +
 frontend/.stylelintrc.js                           |    30 +
 frontend/README.md                                 |   102 +
 frontend/babel.config.js                           |    34 +
 frontend/package-lock.json                         | 15843 +++++++++++++++++++
 frontend/package.json                              |    69 +
 frontend/public/iconfont.js                        |    76 +
 frontend/public/index.html                         |    37 +
 frontend/public/iotdb.ico                          |   Bin 0 -> 1150 bytes
 frontend/src/App.vue                               |    85 +
 frontend/src/assets/2d-code.png                    |   Bin 0 -> 22318 bytes
 frontend/src/assets/about-img.png                  |   Bin 0 -> 96789 bytes
 frontend/src/assets/empty.png                      |   Bin 0 -> 20406 bytes
 frontend/src/assets/login.png                      |   Bin 0 -> 73326 bytes
 frontend/src/assets/logo.png                       |   Bin 0 -> 7465 bytes
 frontend/src/components/Echarts.vue                |   192 +
 frontend/src/components/FormTable.vue              |   115 +
 frontend/src/components/HelloWorld.vue             |    39 +
 frontend/src/components/StandTable.vue             |   238 +
 frontend/src/directive/icon.js                     |    33 +
 frontend/src/directive/index.js                    |    24 +
 frontend/src/i18n/cn.js                            |   302 +
 frontend/src/i18n/de.js                            |   300 +
 frontend/src/i18n/en.js                            |   300 +
 frontend/src/i18n/index.js                         |    46 +
 frontend/src/main.js                               |    34 +
 frontend/src/router/index.js                       |   114 +
 frontend/src/shims-vue.d.ts                        |    20 +
 frontend/src/store/dataBaseM/index.js              |    26 +
 frontend/src/store/index.js                        |    61 +
 frontend/src/store/moduleA/index.js                |    26 +
 frontend/src/store/storage/index.js                |    34 +
 frontend/src/styles/element.scss                   |   127 +
 frontend/src/styles/reset.scss                     |   146 +
 frontend/src/styles/variables.scss                 |    20 +
 frontend/src/util/api_axios.js                     |    25 +
 frontend/src/util/axios.js                         |    83 +
 frontend/src/views/About/index.vue                 |   206 +
 .../views/DataBaseM/components/dataListTree.vue    |   403 +
 .../src/views/DataBaseM/components/iconTypes.vue   |    67 +
 .../src/views/DataBaseM/hooks/useElementResize.js  |    47 +
 frontend/src/views/DataBaseM/index.vue             |   327 +
 frontend/src/views/Device/api/index.js             |    37 +
 frontend/src/views/Device/index.vue                |   459 +
 frontend/src/views/DeviceMessage/api/index.js      |    37 +
 .../src/views/DeviceMessage/components/action.vue  |   108 +
 frontend/src/views/DeviceMessage/index.vue         |   398 +
 frontend/src/views/Home.vue                        |    57 +
 frontend/src/views/Login/index.vue                 |   262 +
 frontend/src/views/Root/hooks/useLangSwitch.js     |    43 +
 frontend/src/views/Root/index.vue                  |   187 +
 frontend/src/views/Source/components/empty.vue     |   100 +
 frontend/src/views/Source/components/newSource.vue |   311 +
 frontend/src/views/Source/index.vue                |  1373 ++
 frontend/src/views/SqlSerch/api/index.js           |    58 +
 .../src/views/SqlSerch/components/codemirror.vue   |   170 +
 .../src/views/SqlSerch/components/eltooltip.vue    |    37 +
 .../src/views/SqlSerch/components/formserch.vue    |   107 +
 .../views/SqlSerch/components/formserchData.vue    |   190 +
 .../src/views/SqlSerch/components/sqlDrawer.vue    |   123 +
 frontend/src/views/SqlSerch/hooks/codemirror.js    |    38 +
 frontend/src/views/SqlSerch/hooks/function.js      |    92 +
 frontend/src/views/SqlSerch/hooks/keywords.js      |   143 +
 frontend/src/views/SqlSerch/hooks/selectList.js    |    82 +
 .../src/views/SqlSerch/hooks/useElementResize.js   |    48 +
 frontend/src/views/SqlSerch/index.vue              |   512 +
 frontend/src/views/storage/index.vue               |   329 +
 frontend/src/views/storage/newStorage.vue          |   263 +
 frontend/tests/unit/example.spec.js                |    32 +
 frontend/vue.config.js                             |    44 +
 76 files changed, 25423 insertions(+), 1 deletion(-)


[iotdb-web-workbench] 32/34: fix(optimize code)

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit c64dae3744851efe8e83187c476e562612062a30
Author: 470058871@qq.com <47...@qq.com>
AuthorDate: Thu Jun 2 08:55:24 2022 +0800

    fix(optimize code)
---
 frontend/src/styles/element.scss    |  5 -----
 frontend/src/views/Source/index.vue |  4 ----
 frontend/vue.config.js              | 10 ----------
 3 files changed, 19 deletions(-)

diff --git a/frontend/src/styles/element.scss b/frontend/src/styles/element.scss
index fc556db..19691c8 100644
--- a/frontend/src/styles/element.scss
+++ b/frontend/src/styles/element.scss
@@ -50,11 +50,6 @@
     background-color: transparent !important;
     border-color: #15c294 !important;
   }
-  //   &:focus {
-  //     color: none !important;
-  //     background-color: transparent !important;
-  //     border-color: #15c294 !important;
-  //   }
 }
 .button-delete:hover {
   background: #fff !important;
diff --git a/frontend/src/views/Source/index.vue b/frontend/src/views/Source/index.vue
index e16e5bc..219c44a 100644
--- a/frontend/src/views/Source/index.vue
+++ b/frontend/src/views/Source/index.vue
@@ -816,10 +816,6 @@ export default {
       axios.post(`/servers/${serverId.value}/users/${baseInfoForm.userName}/authorityPrivilege`, { ...reqObj }).then((rs) => {
         if (rs && rs.code == 0) {
           ElMessage.success(t('sourcePage.successEditPermit'));
-          //   store.dispatch('fetchAllPrivileges', {
-          //     serverId: serverId.value,
-          //     userName: baseInfoForm.userName,
-          //   });
         }
       });
     };
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index a2636dc..a9800f5 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -38,14 +38,11 @@ module.exports = {
       },
     },
     extract: {
-      // 打包后css文件名称添加时间戳
       filename: `css/[name].${Version}.css`,
       chunkFilename: `css/chunk.[id].${Version}.css`,
     },
   },
   configureWebpack: {
-    // 重点
-    // 输出重构 打包编译后的js文件名称,添加时间戳.
     output: {
       filename: `js/[name].${Version}.js`,
       chunkFilename: `js/chunk.[id].${Version}.js`,
@@ -58,13 +55,6 @@ module.exports = {
         target: 'http://192.168.1.84:9090',
         progress: false,
       },
-      // '/user': {
-      //     target: 'http://119.84.128.59:8079/api',
-      //     changeOrigin: true,
-      //     pathRewrite: {
-      //         '^/user': ''
-      //     }
-      // },
     },
   },
 };


[iotdb-web-workbench] 13/34: [FRONTEND] Add workflow for frontend

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 9c84d53f1163e878e3bf575210ccd394a5d8bcbe
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 14:50:05 2021 +0200

    [FRONTEND] Add workflow for frontend
---
 .github/workflows/frontend.yml | 54 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
new file mode 100644
index 0000000..0022604
--- /dev/null
+++ b/.github/workflows/frontend.yml
@@ -0,0 +1,54 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Main Mac and Linux
+
+on:
+  push:
+    branches:
+      - master
+      - 'rel/*'
+      - Vector
+    paths-ignore:
+      - 'docs/**'
+  pull_request:
+    branches:
+      - master
+      - 'rel/*'
+      - cluster_new
+      - Vector
+    paths-ignore:
+      - 'docs/**'
+  # allow manually run the action:
+  workflow_dispatch:
+
+env:
+  MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3
+
+# TODO make npm specific workflow
+
+jobs:
+  unix:
+    strategy:
+      fail-fast: false
+      max-parallel: 20
+      matrix:
+        java: [ 8, 11, 13 ]
+        os: [ ubuntu-latest, macos-latest ]
+    runs-on: ${{ matrix.os}}
+
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up JDK ${{ matrix.java }}
+        uses: actions/setup-java@v1
+        with:
+          java-version: ${{ matrix.java }}
+      - name: Cache Maven packages
+        uses: actions/cache@v2
+        with:
+          path: ~/.m2
+          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+          restore-keys: ${{ runner.os }}-m2-
+      - name: Unit Tests
+        shell: bash
+        run: cd frontend && npm install && npm run lint && npm run test:unit


[iotdb-web-workbench] 02/34: feat(project)添加前端项目

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 1c5073905adb3cc50073b4c89dbb73aa51b782fd
Author: huangrui <hu...@163.com>
AuthorDate: Wed Sep 1 17:08:10 2021 +0800

    feat(project)添加前端项目
---
 frontend/.browserslistrc                           |     3 +
 frontend/.eslintignore                             |     1 +
 frontend/.eslintrc.js                              |    35 +
 frontend/.gitignore                                |    23 +
 frontend/.prettierrc.js                            |     5 +
 frontend/.stylelintrc.js                           |     4 +
 frontend/README.md                                 |    83 +
 frontend/babel.config.js                           |    15 +
 frontend/package-lock.json                         | 15843 +++++++++++++++++++
 frontend/package.json                              |    69 +
 frontend/public/iconfont.js                        |    57 +
 frontend/public/index.html                         |    18 +
 frontend/public/iotdb.ico                          |   Bin 0 -> 1150 bytes
 frontend/src/App.vue                               |    66 +
 frontend/src/assets/2d-code.png                    |   Bin 0 -> 22318 bytes
 frontend/src/assets/about-img.png                  |   Bin 0 -> 96789 bytes
 frontend/src/assets/empty.png                      |   Bin 0 -> 20406 bytes
 frontend/src/assets/login.png                      |   Bin 0 -> 73326 bytes
 frontend/src/assets/logo.png                       |   Bin 0 -> 7465 bytes
 frontend/src/components/Echarts.vue                |   173 +
 frontend/src/components/FormTable.vue              |    96 +
 frontend/src/components/HelloWorld.vue             |    20 +
 frontend/src/components/StandTable.vue             |   219 +
 frontend/src/directive/icon.js                     |    14 +
 frontend/src/directive/index.js                    |     5 +
 frontend/src/i18n/cn.js                            |   283 +
 frontend/src/i18n/de.js                            |   281 +
 frontend/src/i18n/en.js                            |   281 +
 frontend/src/i18n/index.js                         |    27 +
 frontend/src/main.js                               |    15 +
 frontend/src/router/index.js                       |    95 +
 frontend/src/shims-vue.d.ts                        |     1 +
 frontend/src/store/dataBaseM/index.js              |     7 +
 frontend/src/store/index.js                        |    42 +
 frontend/src/store/moduleA/index.js                |     7 +
 frontend/src/store/storage/index.js                |    15 +
 frontend/src/styles/element.scss                   |   108 +
 frontend/src/styles/reset.scss                     |    49 +
 frontend/src/styles/variables.scss                 |     1 +
 frontend/src/util/api_axios.js                     |     6 +
 frontend/src/util/axios.js                         |    64 +
 frontend/src/views/About/index.vue                 |   187 +
 .../views/DataBaseM/components/dataListTree.vue    |   384 +
 .../src/views/DataBaseM/components/iconTypes.vue   |    48 +
 .../src/views/DataBaseM/hooks/useElementResize.js  |    28 +
 frontend/src/views/DataBaseM/index.vue             |   308 +
 frontend/src/views/Device/api/index.js             |    18 +
 frontend/src/views/Device/index.vue                |   440 +
 frontend/src/views/DeviceMessage/api/index.js      |    18 +
 .../src/views/DeviceMessage/components/action.vue  |    89 +
 frontend/src/views/DeviceMessage/index.vue         |   379 +
 frontend/src/views/Home.vue                        |    38 +
 frontend/src/views/Login/index.vue                 |   243 +
 frontend/src/views/Root/hooks/useLangSwitch.js     |    24 +
 frontend/src/views/Root/index.vue                  |   168 +
 frontend/src/views/Source/components/empty.vue     |    81 +
 frontend/src/views/Source/components/newSource.vue |   293 +
 frontend/src/views/Source/index.vue                |  1366 ++
 frontend/src/views/SqlSerch/api/index.js           |    39 +
 .../src/views/SqlSerch/components/codemirror.vue   |   151 +
 .../src/views/SqlSerch/components/eltooltip.vue    |    20 +
 .../src/views/SqlSerch/components/formserch.vue    |    88 +
 .../views/SqlSerch/components/formserchData.vue    |   171 +
 .../src/views/SqlSerch/components/sqlDrawer.vue    |   104 +
 frontend/src/views/SqlSerch/hooks/codemirror.js    |    19 +
 frontend/src/views/SqlSerch/hooks/function.js      |    73 +
 frontend/src/views/SqlSerch/hooks/keywords.js      |   124 +
 frontend/src/views/SqlSerch/hooks/selectList.js    |    63 +
 .../src/views/SqlSerch/hooks/useElementResize.js   |    29 +
 frontend/src/views/SqlSerch/index.vue              |   493 +
 frontend/src/views/storage/index.vue               |   310 +
 frontend/src/views/storage/newStorage.vue          |   244 +
 frontend/tests/unit/example.spec.js                |    13 +
 frontend/vue.config.js                             |    25 +
 74 files changed, 24109 insertions(+)

diff --git a/frontend/.browserslistrc b/frontend/.browserslistrc
new file mode 100644
index 0000000..214388f
--- /dev/null
+++ b/frontend/.browserslistrc
@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead
diff --git a/frontend/.eslintignore b/frontend/.eslintignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/frontend/.eslintignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js
new file mode 100644
index 0000000..2bbdd2c
--- /dev/null
+++ b/frontend/.eslintrc.js
@@ -0,0 +1,35 @@
+module.exports = {
+    root: true,
+    env: {
+        browser: true,
+        node: true,
+    },
+    extends: [
+        "plugin:vue/vue3-essential",
+        "eslint:recommended",
+        "@vue/prettier",
+    ],
+    parserOptions: {
+        parser: "babel-eslint",
+        ecmaVersion: 7,
+        sourceType: "module",
+        ecmaFeatures: {
+            jsx: true,
+        },
+    },
+    rules: {
+        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
+        "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
+    },
+    overrides: [
+        {
+            files: [
+                "**/__tests__/*.{j,t}s?(x)",
+                "**/tests/unit/**/*.spec.{j,t}s?(x)",
+            ],
+            env: {
+                mocha: true,
+            },
+        },
+    ],
+};
diff --git a/frontend/.gitignore b/frontend/.gitignore
new file mode 100644
index 0000000..403adbc
--- /dev/null
+++ b/frontend/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/frontend/.prettierrc.js b/frontend/.prettierrc.js
new file mode 100644
index 0000000..ac684b0
--- /dev/null
+++ b/frontend/.prettierrc.js
@@ -0,0 +1,5 @@
+module.exports = {
+  tabWidth: 2,
+  singleQuote: true,
+  printWidth: 200,
+};
diff --git a/frontend/.stylelintrc.js b/frontend/.stylelintrc.js
new file mode 100644
index 0000000..fa6ec3d
--- /dev/null
+++ b/frontend/.stylelintrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+  extends: ["stylelint-config-standard-scss", "stylelint-config-prettier"],
+  rules: {},
+};
diff --git a/frontend/README.md b/frontend/README.md
new file mode 100644
index 0000000..b3c6978
--- /dev/null
+++ b/frontend/README.md
@@ -0,0 +1,83 @@
+# iotdb-fe
+
+## 开发环境
+
+目前支持的开发环境如下:
+
+- node 10.0.0 及以上
+- npm 6.0.0及以上
+- 推荐使用visual studio code
+
+## 安装依赖
+
+```
+cd frontend
+npm install
+```
+
+## 运行项目
+
+```
+npm run serve
+```
+
+## 运行单元测试
+
+```
+npm run test:unit
+```
+
+## 技术栈
+
+**Vue3.0** + **Scss**(css modules) + **Element Plus** + **Eslint,Stylelint,Prettier,Husky** 统一代码风格与规范。
+
+## 代码规范
+
+#### Javascript 规范
+
+根据 eslint 约定规范,详见.eslintrc。
+
+#### Css 规范
+
+根据 stylelint 约定规范,详见.stylelintrc。
+
+#### 代码格式风格规范
+
+请 IDE 下载 Eslint 和 Prettier 插件,配置保存文件时自动 fix。
+<br/>
+
+#### 项目目录规范
+
+```
+src 源码目录
+  |-- api 接口,统一管理
+  |-- assets 静态资源,统一管理
+  |-- components 公用业务组件,
+  |-- hooks 共用hooks文件
+  |-- i18n 国际化配置文件
+  |-- components 公用组件,全局文件
+  |-- util 全局工具
+  |-- icons 图标,全局资源
+  |-- lib  共用库
+  |-- mock 模拟接口,临时存放
+  |-- router 路由,统一管理
+  |-- store vuex, 统一管理
+  |-- styles 全局样式,scss全局变量等样式相关文件
+  | |-- element.scss 全局修改element plus组件库样式
+  | |-- reset.scss 重置浏览器样式
+  | |-- variables.scss scss全局变量
+  |-- views 视图目录
+  | |-- pageA 页面
+  | |-- |-- hooks 页面通用hooks
+  | |-- |-- api 需要就近维护的接口
+  | |-- |-- index.vue 页面入口页面
+  | |-- |-- components 页面通用组件
+```
+
+#### UI 规范
+
+原则上基于 Element Plus 组件库进行开发,统一开发样式。
+
+#### git commit 规范
+
+原则上基于 `<type>(<scope>): <subject>` 格式提交代码,详见https://zhuanlan.zhihu.com/p/182553920
\ No newline at end of file
diff --git a/frontend/babel.config.js b/frontend/babel.config.js
new file mode 100644
index 0000000..25d8020
--- /dev/null
+++ b/frontend/babel.config.js
@@ -0,0 +1,15 @@
+module.exports = {
+  presets: ['@vue/cli-plugin-babel/preset'],
+  plugins: [
+    [
+      'import',
+      {
+        libraryName: 'element-plus',
+        customStyleName: (name) => {
+          name = name.slice(3);
+          return `element-plus/packages/theme-chalk/src/${name}.scss`;
+        },
+      },
+    ],
+  ],
+};
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
new file mode 100644
index 0000000..c893cb6
--- /dev/null
+++ b/frontend/package-lock.json
@@ -0,0 +1,15843 @@
+{
+  "name": "iotdb",
+  "version": "0.1.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@babel/code-frame": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.12.13.tgz",
+      "integrity": "sha1-3PyCa+72XnXFDiHTg319lXmN1lg=",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.12.13"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/compat-data/download/@babel/compat-data-7.14.0.tgz?cache=0&sync_timestamp=1619727430608&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.14.0.tgz",
+      "integrity": "sha1-qQESi84q0CVl35Xm7L8ZXPlGWRk=",
+      "dev": true
+    },
+    "@babel/core": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/core/download/@babel/core-7.14.3.tgz",
+      "integrity": "sha1-U5XjBAXwd2Bn+9nPCITxW/t3Cjg=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.12.13",
+        "@babel/generator": "^7.14.3",
+        "@babel/helper-compilation-targets": "^7.13.16",
+        "@babel/helper-module-transforms": "^7.14.2",
+        "@babel/helpers": "^7.14.0",
+        "@babel/parser": "^7.14.3",
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.14.2",
+        "@babel/types": "^7.14.2",
+        "convert-source-map": "^1.7.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.1.2",
+        "semver": "^6.3.0",
+        "source-map": "^0.5.0"
+      }
+    },
+    "@babel/generator": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/generator/download/@babel/generator-7.14.3.tgz",
+      "integrity": "sha1-DCZS2R973at8zMa6gVfk9A3O25E=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.14.2",
+        "jsesc": "^2.5.1",
+        "source-map": "^0.5.0"
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/download/@babel/helper-annotate-as-pure-7.12.13.tgz?cache=0&sync_timestamp=1612314636125&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-annotate-as-pure%2Fdownload%2F%40babel%2Fhelper-annotate-as-pure-7.12.13.tgz",
+      "integrity": "sha1-D1jobfxLs7H819uAZXDhd9Q5tqs=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.12.13",
+      "resolved": "https://registry.nlark.com/@babel/helper-builder-binary-assignment-operator-visitor/download/@babel/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz",
+      "integrity": "sha1-a8IDYciLCnTQUTemXKyNPL9vYfw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.13.16",
+      "resolved": "https://registry.nlark.com/@babel/helper-compilation-targets/download/@babel/helper-compilation-targets-7.13.16.tgz",
+      "integrity": "sha1-bpHczxXj9D5VVt/+MthgEJiHVjw=",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.13.15",
+        "@babel/helper-validator-option": "^7.12.17",
+        "browserslist": "^4.14.5",
+        "semver": "^6.3.0"
+      }
+    },
+    "@babel/helper-create-class-features-plugin": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/helper-create-class-features-plugin/download/@babel/helper-create-class-features-plugin-7.14.3.tgz",
+      "integrity": "sha1-gyERvPT1fKV6TFsaAA/BJavGVUo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-function-name": "^7.14.2",
+        "@babel/helper-member-expression-to-functions": "^7.13.12",
+        "@babel/helper-optimise-call-expression": "^7.12.13",
+        "@babel/helper-replace-supers": "^7.14.3",
+        "@babel/helper-split-export-declaration": "^7.12.13"
+      }
+    },
+    "@babel/helper-create-regexp-features-plugin": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/helper-create-regexp-features-plugin/download/@babel/helper-create-regexp-features-plugin-7.14.3.tgz",
+      "integrity": "sha1-FJqm14wBbjGMQ+JAmgrpwTaoZog=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "regexpu-core": "^4.7.1"
+      }
+    },
+    "@babel/helper-define-polyfill-provider": {
+      "version": "0.2.3",
+      "resolved": "https://registry.nlark.com/@babel/helper-define-polyfill-provider/download/@babel/helper-define-polyfill-provider-0.2.3.tgz?cache=0&sync_timestamp=1622025470416&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-define-polyfill-provider%2Fdownload%2F%40babel%2Fhelper-define-polyfill-provider-0.2.3.tgz",
+      "integrity": "sha1-BSXt7FCUZTooJojTTYRuTHXpwLY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-compilation-targets": "^7.13.0",
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/traverse": "^7.13.0",
+        "debug": "^4.1.1",
+        "lodash.debounce": "^4.0.8",
+        "resolve": "^1.14.2",
+        "semver": "^6.1.2"
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-explode-assignable-expression/download/@babel/helper-explode-assignable-expression-7.13.0.tgz?cache=0&sync_timestamp=1614034723075&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-explode-assignable-expression%2Fdownload%2F%40babel%2Fhelper-explode-assignable-expression-7.13.0.tgz",
+      "integrity": "sha1-F7XFn/Rz2flW9A71cM86dsoSZX8=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.13.0"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/helper-function-name/download/@babel/helper-function-name-7.14.2.tgz?cache=0&sync_timestamp=1620839583330&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-function-name%2Fdownload%2F%40babel%2Fhelper-function-name-7.14.2.tgz",
+      "integrity": "sha1-OXaItZB2C273cltfCGDIJCfrqsI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.12.13",
+        "@babel/template": "^7.12.13",
+        "@babel/types": "^7.14.2"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-get-function-arity/download/@babel/helper-get-function-arity-7.12.13.tgz?cache=0&sync_timestamp=1612314636323&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-get-function-arity%2Fdownload%2F%40babel%2Fhelper-get-function-arity-7.12.13.tgz",
+      "integrity": "sha1-vGNFHUA6OzCCuX4diz/lvUCR5YM=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.13.16",
+      "resolved": "https://registry.nlark.com/@babel/helper-hoist-variables/download/@babel/helper-hoist-variables-7.13.16.tgz?cache=0&sync_timestamp=1618917701165&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-hoist-variables%2Fdownload%2F%40babel%2Fhelper-hoist-variables-7.13.16.tgz",
+      "integrity": "sha1-GxZRJJ6UtR+PDTNDmEPjPjl3WzA=",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "^7.13.15",
+        "@babel/types": "^7.13.16"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.13.12",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/download/@babel/helper-member-expression-to-functions-7.13.12.tgz?cache=0&sync_timestamp=1616428120148&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-member-expression-to-functions%2Fdownload%2F%40babel%2Fhelper-member-expression-to-functions-7.13.12.tgz",
+      "integrity": "sha1-3+No8m1CagcpnY1lE4IXaCFubXI=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.13.12"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.13.12",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-module-imports/download/@babel/helper-module-imports-7.13.12.tgz?cache=0&sync_timestamp=1616428110625&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-module-imports%2Fdownload%2F%40babel%2Fhelper-module-imports-7.13.12.tgz",
+      "integrity": "sha1-xqNppvNiHLJdoBQHhoTakZa2GXc=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.13.12"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/helper-module-transforms/download/@babel/helper-module-transforms-7.14.2.tgz?cache=0&sync_timestamp=1620839457149&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-module-transforms%2Fdownload%2F%40babel%2Fhelper-module-transforms-7.14.2.tgz",
+      "integrity": "sha1-rBzDDuR7lF4+DE2xL6DFOJUJ3+U=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.13.12",
+        "@babel/helper-replace-supers": "^7.13.12",
+        "@babel/helper-simple-access": "^7.13.12",
+        "@babel/helper-split-export-declaration": "^7.12.13",
+        "@babel/helper-validator-identifier": "^7.14.0",
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.14.2",
+        "@babel/types": "^7.14.2"
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/download/@babel/helper-optimise-call-expression-7.12.13.tgz?cache=0&sync_timestamp=1612314636446&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-optimise-call-expression%2Fdownload%2F%40babel%2Fhelper-optimise-call-expression-7.12.13.tgz",
+      "integrity": "sha1-XALRcbTIYVsecWP4iMHIHDCiquo=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-plugin-utils/download/@babel/helper-plugin-utils-7.13.0.tgz?cache=0&sync_timestamp=1614034721464&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-plugin-utils%2Fdownload%2F%40babel%2Fhelper-plugin-utils-7.13.0.tgz",
+      "integrity": "sha1-gGUmzhJa7QM3O8QWqCgyHjpqM68=",
+      "dev": true
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-remap-async-to-generator/download/@babel/helper-remap-async-to-generator-7.13.0.tgz?cache=0&sync_timestamp=1614034719757&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-remap-async-to-generator%2Fdownload%2F%40babel%2Fhelper-remap-async-to-generator-7.13.0.tgz",
+      "integrity": "sha1-N2p2DZ97SyB3qd0Fqpw5J8rbIgk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-wrap-function": "^7.13.0",
+        "@babel/types": "^7.13.0"
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/helper-replace-supers/download/@babel/helper-replace-supers-7.14.3.tgz",
+      "integrity": "sha1-yhezGLhZ0Qfw6bci1YzxLZRDZgA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-member-expression-to-functions": "^7.13.12",
+        "@babel/helper-optimise-call-expression": "^7.12.13",
+        "@babel/traverse": "^7.14.2",
+        "@babel/types": "^7.14.2"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.13.12",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-simple-access/download/@babel/helper-simple-access-7.13.12.tgz?cache=0&sync_timestamp=1616428121027&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-simple-access%2Fdownload%2F%40babel%2Fhelper-simple-access-7.13.12.tgz",
+      "integrity": "sha1-3WxTivthgZ0gWgEsMXkqOcel6vY=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.13.12"
+      }
+    },
+    "@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-skip-transparent-expression-wrappers/download/@babel/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
+      "integrity": "sha1-Ri3GOn5DWt6EaDhcY9K4TM5LPL8=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.1"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-split-export-declaration/download/@babel/helper-split-export-declaration-7.12.13.tgz?cache=0&sync_timestamp=1612314636310&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-split-export-declaration%2Fdownload%2F%40babel%2Fhelper-split-export-declaration-7.12.13.tgz",
+      "integrity": "sha1-6UML4AuvPoiw4T5vnU6vITY3KwU=",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/helper-validator-identifier": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.14.0.tgz?cache=0&sync_timestamp=1619727388937&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelper-validator-identifier%2Fdownload%2F%40babel%2Fhelper-validator-identifier-7.14.0.tgz",
+      "integrity": "sha1-0mytikfGUoaxXfFUcxml0Lzycog="
+    },
+    "@babel/helper-validator-option": {
+      "version": "7.12.17",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-validator-option/download/@babel/helper-validator-option-7.12.17.tgz?cache=0&sync_timestamp=1613661300791&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-validator-option%2Fdownload%2F%40babel%2Fhelper-validator-option-7.12.17.tgz",
+      "integrity": "sha1-0fvwEuGnm37rv9xtJwuq+NnrmDE=",
+      "dev": true
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.13.0.tgz?cache=0&sync_timestamp=1614034718032&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fhelper-wrap-function%2Fdownload%2F%40babel%2Fhelper-wrap-function-7.13.0.tgz",
+      "integrity": "sha1-vbXGb9qFJuwjWriUrVOhI1x5/MQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.13.0",
+        "@babel/types": "^7.13.0"
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/helpers/download/@babel/helpers-7.14.0.tgz?cache=0&sync_timestamp=1619727392870&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fhelpers%2Fdownload%2F%40babel%2Fhelpers-7.14.0.tgz",
+      "integrity": "sha1-6ptr6UeKE9b5Ydu182v3Xi87j2I=",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.12.13",
+        "@babel/traverse": "^7.14.0",
+        "@babel/types": "^7.14.0"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/highlight/download/@babel/highlight-7.14.0.tgz",
+      "integrity": "sha1-MZfjdXEe9r+DTmfQ2uyI5PRhE88=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.14.0",
+        "chalk": "^2.0.0",
+        "js-tokens": "^4.0.0"
+      }
+    },
+    "@babel/parser": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/parser/download/@babel/parser-7.14.3.tgz",
+      "integrity": "sha1-m1MO7LBx/QyTUZ3yXF/58UdZ8pg="
+    },
+    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+      "version": "7.13.12",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/download/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz?cache=0&sync_timestamp=1616428117548&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-bugfix-v8-spread-parameters-in-optional-chaining%2Fdownload%2F%40babel%2Fplugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz",
+      "integrity": "sha1-o0hNhNC1SfP8kWuZ7keD8m+rrSo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+        "@babel/plugin-proposal-optional-chaining": "^7.13.12"
+      }
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-async-generator-functions/download/@babel/plugin-proposal-async-generator-functions-7.14.2.tgz?cache=0&sync_timestamp=1620839583406&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-async-generator-functions%2Fdownload%2F%40babel%2Fplugin-proposal-async-generator-functions-7.14.2.tgz",
+      "integrity": "sha1-OiCFq79dX5YtSA28gTRzhe1i6x4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-remap-async-to-generator": "^7.13.0",
+        "@babel/plugin-syntax-async-generators": "^7.8.4"
+      }
+    },
+    "@babel/plugin-proposal-class-properties": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-class-properties/download/@babel/plugin-proposal-class-properties-7.13.0.tgz?cache=0&sync_timestamp=1614034719421&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-class-properties%2Fdownload%2F%40babel%2Fplugin-proposal-class-properties-7.13.0.tgz",
+      "integrity": "sha1-FGN2AAuU79AB5XpAqIpSWvqrnzc=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.13.0",
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-proposal-class-static-block": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-class-static-block/download/@babel/plugin-proposal-class-static-block-7.14.3.tgz",
+      "integrity": "sha1-WlJ+LK5KR1MRnDo+f2TsrozPE2A=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.14.3",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-class-static-block": "^7.12.13"
+      }
+    },
+    "@babel/plugin-proposal-decorators": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-decorators/download/@babel/plugin-proposal-decorators-7.14.2.tgz?cache=0&sync_timestamp=1620840028217&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-decorators%2Fdownload%2F%40babel%2Fplugin-proposal-decorators-7.14.2.tgz",
+      "integrity": "sha1-5ow8XkpqCINEVlaCVvw+cbk1kM8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.14.2",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-decorators": "^7.12.13"
+      }
+    },
+    "@babel/plugin-proposal-dynamic-import": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-dynamic-import/download/@babel/plugin-proposal-dynamic-import-7.14.2.tgz",
+      "integrity": "sha1-Aeur18OBz/Ix+kPjApOaneW+nZ8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-export-namespace-from": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-export-namespace-from/download/@babel/plugin-proposal-export-namespace-from-7.14.2.tgz?cache=0&sync_timestamp=1620839583318&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-export-namespace-from%2Fdownload%2F%40babel%2Fplugin-proposal-export-namespace-from-7.14.2.tgz",
+      "integrity": "sha1-YlQvlKqc6Pbbp57saYryIRIlN5E=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-json-strings": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-json-strings/download/@babel/plugin-proposal-json-strings-7.14.2.tgz",
+      "integrity": "sha1-gwtOJCanguiyh4+/4suoW3DL+Yw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-json-strings": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-logical-assignment-operators": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-logical-assignment-operators/download/@babel/plugin-proposal-logical-assignment-operators-7.14.2.tgz?cache=0&sync_timestamp=1620839583487&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-proposal-logical-assignment-operators-7.14.2.tgz",
+      "integrity": "sha1-IiNIwIChZ44OdOpj/nbydYgtH9c=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-nullish-coalescing-operator": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-nullish-coalescing-operator/download/@babel/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz",
+      "integrity": "sha1-QlsR3GL8JpOaKrQsu6aAvfVzRUY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-numeric-separator": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-numeric-separator/download/@babel/plugin-proposal-numeric-separator-7.14.2.tgz?cache=0&sync_timestamp=1620839583606&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-numeric-separator%2Fdownload%2F%40babel%2Fplugin-proposal-numeric-separator-7.14.2.tgz",
+      "integrity": "sha1-grTMBlcRQ/r1BiYQSzNd1xuqT54=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-object-rest-spread/download/@babel/plugin-proposal-object-rest-spread-7.14.2.tgz",
+      "integrity": "sha1-4X1Bj4HMED/t1M4DfhgcgFYiWrw=",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.14.0",
+        "@babel/helper-compilation-targets": "^7.13.16",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+        "@babel/plugin-transform-parameters": "^7.14.2"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-optional-catch-binding/download/@babel/plugin-proposal-optional-catch-binding-7.14.2.tgz",
+      "integrity": "sha1-FQ1OWOUlsWqaFDG9UybE7thw1xc=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-optional-chaining": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-optional-chaining/download/@babel/plugin-proposal-optional-chaining-7.14.2.tgz?cache=0&sync_timestamp=1620840046588&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-optional-chaining%2Fdownload%2F%40babel%2Fplugin-proposal-optional-chaining-7.14.2.tgz",
+      "integrity": "sha1-34FxqLnEPr9MHavmMRtDLYPhs04=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+      }
+    },
+    "@babel/plugin-proposal-private-methods": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-proposal-private-methods/download/@babel/plugin-proposal-private-methods-7.13.0.tgz?cache=0&sync_timestamp=1614034720852&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-proposal-private-methods%2Fdownload%2F%40babel%2Fplugin-proposal-private-methods-7.13.0.tgz",
+      "integrity": "sha1-BL1MbUD25rv6L1fi2AlLrZAO94c=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-class-features-plugin": "^7.13.0",
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-proposal-private-property-in-object": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-private-property-in-object/download/@babel/plugin-proposal-private-property-in-object-7.14.0.tgz?cache=0&sync_timestamp=1619727655656&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-proposal-private-property-in-object%2Fdownload%2F%40babel%2Fplugin-proposal-private-property-in-object-7.14.0.tgz",
+      "integrity": "sha1-saHyAwWGudNInMJhedLrWIMndjY=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-create-class-features-plugin": "^7.14.0",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/plugin-syntax-private-property-in-object": "^7.14.0"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.nlark.com/@babel/plugin-proposal-unicode-property-regex/download/@babel/plugin-proposal-unicode-property-regex-7.12.13.tgz",
+      "integrity": "sha1-vr3lEzm+gpwXqqrO0YZB3rYrObo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-async-generators": {
+      "version": "7.8.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-async-generators/download/@babel/plugin-syntax-async-generators-7.8.4.tgz",
+      "integrity": "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-class-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-class-properties/download/@babel/plugin-syntax-class-properties-7.12.13.tgz?cache=0&sync_timestamp=1612314770269&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-class-properties%2Fdownload%2F%40babel%2Fplugin-syntax-class-properties-7.12.13.tgz",
+      "integrity": "sha1-tcmHJ0xKOoK4lxR5aTGmtTVErhA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-class-static-block": {
+      "version": "7.12.13",
+      "resolved": "https://registry.nlark.com/@babel/plugin-syntax-class-static-block/download/@babel/plugin-syntax-class-static-block-7.12.13.tgz",
+      "integrity": "sha1-jj1nSwYT5nl1zqwndsl7YMr8XJw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-decorators": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-decorators/download/@babel/plugin-syntax-decorators-7.12.13.tgz",
+      "integrity": "sha1-+sgpvzx+9KG8kWJXtAPljGva9kg=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-dynamic-import/download/@babel/plugin-syntax-dynamic-import-7.8.3.tgz",
+      "integrity": "sha1-Yr+Ysto80h1iYVT8lu5bPLaOrLM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-export-namespace-from": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-export-namespace-from/download/@babel/plugin-syntax-export-namespace-from-7.8.3.tgz",
+      "integrity": "sha1-AolkqbqA28CUyRXEh618TnpmRlo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
+      }
+    },
+    "@babel/plugin-syntax-json-strings": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-json-strings/download/@babel/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-jsx": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/download/@babel/plugin-syntax-jsx-7.12.13.tgz",
+      "integrity": "sha1-BE+4HrrWaY/mLEeIdVdby7m3DxU=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-syntax-logical-assignment-operators": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-logical-assignment-operators/download/@babel/plugin-syntax-logical-assignment-operators-7.10.4.tgz?cache=0&sync_timestamp=1593522961558&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-logical-assignment-operators%2Fdownload%2F%40babel%2Fplugin-syntax-logical-assignment-operators-7.10.4.tgz",
+      "integrity": "sha1-ypHvRjA1MESLkGZSusLp/plB9pk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-nullish-coalescing-operator/download/@babel/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-numeric-separator": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-numeric-separator/download/@babel/plugin-syntax-numeric-separator-7.10.4.tgz?cache=0&sync_timestamp=1593521806492&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-numeric-separator%2Fdownload%2F%40babel%2Fplugin-syntax-numeric-separator-7.10.4.tgz",
+      "integrity": "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.10.4"
+      }
+    },
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-object-rest-spread/download/@babel/plugin-syntax-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-catch-binding/download/@babel/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-chaining": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-optional-chaining/download/@babel/plugin-syntax-optional-chaining-7.8.3.tgz",
+      "integrity": "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-private-property-in-object": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/plugin-syntax-private-property-in-object/download/@babel/plugin-syntax-private-property-in-object-7.14.0.tgz",
+      "integrity": "sha1-dipLq+xhF2/sbIhIDexANysUDAs=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-syntax-top-level-await": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-syntax-top-level-await/download/@babel/plugin-syntax-top-level-await-7.12.13.tgz?cache=0&sync_timestamp=1612314769908&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-syntax-top-level-await%2Fdownload%2F%40babel%2Fplugin-syntax-top-level-await-7.12.13.tgz",
+      "integrity": "sha1-xfD6biSfW3OXJ/kjVAz3qAYTAXg=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.13.0",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.13.0.tgz",
+      "integrity": "sha1-EKWb661S1jegJ6+mkujVzv9ePa4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-async-to-generator/download/@babel/plugin-transform-async-to-generator-7.13.0.tgz?cache=0&sync_timestamp=1614034721772&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-async-to-generator%2Fdownload%2F%40babel%2Fplugin-transform-async-to-generator-7.13.0.tgz",
+      "integrity": "sha1-jhEr9ncbgr8el05eJoBsXJmqUW8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-remap-async-to-generator": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoped-functions/download/@babel/plugin-transform-block-scoped-functions-7.12.13.tgz?cache=0&sync_timestamp=1612314818063&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoped-functions%2Fdownload%2F%40babel%2Fplugin-transform-block-scoped-functions-7.12.13.tgz",
+      "integrity": "sha1-qb8YNvKjm062zwmWdzneKepL9MQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.14.2.tgz?cache=0&sync_timestamp=1620839583504&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.14.2.tgz",
+      "integrity": "sha1-dhyxKrWojWQK1K9KqB+CDmtf31w=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-classes/download/@babel/plugin-transform-classes-7.14.2.tgz?cache=0&sync_timestamp=1620840027682&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-transform-classes%2Fdownload%2F%40babel%2Fplugin-transform-classes-7.14.2.tgz",
+      "integrity": "sha1-PxGWxXCfBkwlKtBWIH2Ht66y0D0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.12.13",
+        "@babel/helper-function-name": "^7.14.2",
+        "@babel/helper-optimise-call-expression": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-replace-supers": "^7.13.12",
+        "@babel/helper-split-export-declaration": "^7.12.13",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.13.0",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-computed-properties/download/@babel/plugin-transform-computed-properties-7.13.0.tgz",
+      "integrity": "sha1-hFxui5u1U3ax+guS7wvcjqBmRO0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.13.17",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-destructuring/download/@babel/plugin-transform-destructuring-7.13.17.tgz",
+      "integrity": "sha1-Z42WV2Y4wZ1bNrMyUE0/1uBt6ic=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-dotall-regex/download/@babel/plugin-transform-dotall-regex-7.12.13.tgz?cache=0&sync_timestamp=1612314730663&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-dotall-regex%2Fdownload%2F%40babel%2Fplugin-transform-dotall-regex-7.12.13.tgz",
+      "integrity": "sha1-PxYBzCmQW/y2f1ORDxl66v67Ja0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-duplicate-keys/download/@babel/plugin-transform-duplicate-keys-7.12.13.tgz?cache=0&sync_timestamp=1612314817333&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-duplicate-keys%2Fdownload%2F%40babel%2Fplugin-transform-duplicate-keys-7.12.13.tgz",
+      "integrity": "sha1-bwa4eouAP9ko5UuBwljwoAM5BN4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-exponentiation-operator/download/@babel/plugin-transform-exponentiation-operator-7.12.13.tgz?cache=0&sync_timestamp=1612314730682&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-exponentiation-operator%2Fdownload%2F%40babel%2Fplugin-transform-exponentiation-operator-7.12.13.tgz",
+      "integrity": "sha1-TVI5C5onPmUeSrpq7knvQOgM0KE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-for-of": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-for-of/download/@babel/plugin-transform-for-of-7.13.0.tgz?cache=0&sync_timestamp=1614034713485&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-for-of%2Fdownload%2F%40babel%2Fplugin-transform-for-of-7.13.0.tgz",
+      "integrity": "sha1-x5n4gagJGsJrVIZ6hFw+l9JpYGI=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-function-name/download/@babel/plugin-transform-function-name-7.12.13.tgz?cache=0&sync_timestamp=1612314730751&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-function-name%2Fdownload%2F%40babel%2Fplugin-transform-function-name-7.12.13.tgz",
+      "integrity": "sha1-uwJEUvmq7YYdN0yOeiQlLOOlAFE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-literals/download/@babel/plugin-transform-literals-7.12.13.tgz?cache=0&sync_timestamp=1612314767825&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-literals%2Fdownload%2F%40babel%2Fplugin-transform-literals-7.12.13.tgz",
+      "integrity": "sha1-LKRbr+SoIBl88xV5Sk0mVg/kvbk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-member-expression-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-member-expression-literals/download/@babel/plugin-transform-member-expression-literals-7.12.13.tgz",
+      "integrity": "sha1-X/pmzVm54ZExTJ8fgDuTjowIHkA=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-modules-amd/download/@babel/plugin-transform-modules-amd-7.14.2.tgz",
+      "integrity": "sha1-ZiKAb+GnwHoTiERCIu+VNfLKF7A=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.14.2",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-modules-commonjs/download/@babel/plugin-transform-modules-commonjs-7.14.0.tgz?cache=0&sync_timestamp=1619727039991&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-transform-modules-commonjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-commonjs-7.14.0.tgz",
+      "integrity": "sha1-UrwZnLWB4Jku26Dw+ANWRnWH8WE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.14.0",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-simple-access": "^7.13.12",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.13.8",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-modules-systemjs/download/@babel/plugin-transform-modules-systemjs-7.13.8.tgz?cache=0&sync_timestamp=1614383316294&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-modules-systemjs%2Fdownload%2F%40babel%2Fplugin-transform-modules-systemjs-7.13.8.tgz",
+      "integrity": "sha1-bQZu4r/zx7PWC/KN7Baa2ZODGuM=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.13.0",
+        "@babel/helper-module-transforms": "^7.13.0",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "babel-plugin-dynamic-import-node": "^2.3.3"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-modules-umd/download/@babel/plugin-transform-modules-umd-7.14.0.tgz?cache=0&sync_timestamp=1619727039991&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-transform-modules-umd%2Fdownload%2F%40babel%2Fplugin-transform-modules-umd-7.14.0.tgz",
+      "integrity": "sha1-L4F50bvJJjZlzkpl8wVSay6orDQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.14.0",
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.12.13.tgz?cache=0&sync_timestamp=1612314730683&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-named-capturing-groups-regex%2Fdownload%2F%40babel%2Fplugin-transform-named-capturing-groups-regex-7.12.13.tgz",
+      "integrity": "sha1-IhNyWl9bu+NktQw7pZmMlZnFydk=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-new-target/download/@babel/plugin-transform-new-target-7.12.13.tgz?cache=0&sync_timestamp=1612314827274&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-new-target%2Fdownload%2F%40babel%2Fplugin-transform-new-target-7.12.13.tgz",
+      "integrity": "sha1-4i2MOvJLFQ3VKMvW5oXnmb8cNRw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-object-super/download/@babel/plugin-transform-object-super-7.12.13.tgz",
+      "integrity": "sha1-tEFqLWO4974xTz00m9VanBtRcfc=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13",
+        "@babel/helper-replace-supers": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-parameters/download/@babel/plugin-transform-parameters-7.14.2.tgz?cache=0&sync_timestamp=1620839583383&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fplugin-transform-parameters%2Fdownload%2F%40babel%2Fplugin-transform-parameters-7.14.2.tgz",
+      "integrity": "sha1-5CkPcuDp6DEADQZkJ8RmcJjezDE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-property-literals": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-property-literals/download/@babel/plugin-transform-property-literals-7.12.13.tgz?cache=0&sync_timestamp=1612314768626&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-property-literals%2Fdownload%2F%40babel%2Fplugin-transform-property-literals-7.12.13.tgz",
+      "integrity": "sha1-TmqeN4ZNjxs7wOLc57+IV9uLGoE=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.13.15",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-regenerator/download/@babel/plugin-transform-regenerator-7.13.15.tgz?cache=0&sync_timestamp=1617897172824&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-regenerator%2Fdownload%2F%40babel%2Fplugin-transform-regenerator-7.13.15.tgz",
+      "integrity": "sha1-5esolFv4tlY+f4GJRflmqNKZfzk=",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.14.2"
+      }
+    },
+    "@babel/plugin-transform-reserved-words": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-reserved-words/download/@babel/plugin-transform-reserved-words-7.12.13.tgz",
+      "integrity": "sha1-fZmI1PBuD+aX6h2YAxiKoYtHJpU=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-runtime": {
+      "version": "7.14.3",
+      "resolved": "https://registry.nlark.com/@babel/plugin-transform-runtime/download/@babel/plugin-transform-runtime-7.14.3.tgz",
+      "integrity": "sha1-H9iFotDeHTwiN5Wk6b5ywttFFc8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.13.12",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "babel-plugin-polyfill-corejs2": "^0.2.0",
+        "babel-plugin-polyfill-corejs3": "^0.2.0",
+        "babel-plugin-polyfill-regenerator": "^0.2.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-shorthand-properties/download/@babel/plugin-transform-shorthand-properties-7.12.13.tgz",
+      "integrity": "sha1-23VXMrcMU51QTGOQ2c6Q/mSv960=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-spread/download/@babel/plugin-transform-spread-7.13.0.tgz?cache=0&sync_timestamp=1614034714029&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-spread%2Fdownload%2F%40babel%2Fplugin-transform-spread-7.13.0.tgz",
+      "integrity": "sha1-hIh3EOJzwYFaznrkWfb0Kl0x1f0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+      }
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-sticky-regex/download/@babel/plugin-transform-sticky-regex-7.12.13.tgz?cache=0&sync_timestamp=1612314787760&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-sticky-regex%2Fdownload%2F%40babel%2Fplugin-transform-sticky-regex-7.12.13.tgz",
+      "integrity": "sha1-dg/9k2+s5z+GCuZG+4bugvPQbR8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-template-literals/download/@babel/plugin-transform-template-literals-7.13.0.tgz?cache=0&sync_timestamp=1614034715504&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-template-literals%2Fdownload%2F%40babel%2Fplugin-transform-template-literals-7.13.0.tgz",
+      "integrity": "sha1-o2BJEnl3rZRDje50Q1mNHO/fQJ0=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.13.0"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-typeof-symbol/download/@babel/plugin-transform-typeof-symbol-7.12.13.tgz",
+      "integrity": "sha1-eF3Weh8upXnZwr5yLejITLhfWn8=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-unicode-escapes": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-escapes/download/@babel/plugin-transform-unicode-escapes-7.12.13.tgz",
+      "integrity": "sha1-hAztO4FtO1En3R0S3O3F3q0aXnQ=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-unicode-regex/download/@babel/plugin-transform-unicode-regex-7.12.13.tgz?cache=0&sync_timestamp=1612314730902&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-unicode-regex%2Fdownload%2F%40babel%2Fplugin-transform-unicode-regex-7.12.13.tgz",
+      "integrity": "sha1-tSUhaFgE4VWxIC6D/BiNNLtw9aw=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-create-regexp-features-plugin": "^7.12.13",
+        "@babel/helper-plugin-utils": "^7.12.13"
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/preset-env/download/@babel/preset-env-7.14.2.tgz?cache=0&sync_timestamp=1620839457830&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.14.2.tgz",
+      "integrity": "sha1-6AYSll2nNXnIStL5Y8I1nHFSTtU=",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.14.0",
+        "@babel/helper-compilation-targets": "^7.13.16",
+        "@babel/helper-plugin-utils": "^7.13.0",
+        "@babel/helper-validator-option": "^7.12.17",
+        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12",
+        "@babel/plugin-proposal-async-generator-functions": "^7.14.2",
+        "@babel/plugin-proposal-class-properties": "^7.13.0",
+        "@babel/plugin-proposal-class-static-block": "^7.13.11",
+        "@babel/plugin-proposal-dynamic-import": "^7.14.2",
+        "@babel/plugin-proposal-export-namespace-from": "^7.14.2",
+        "@babel/plugin-proposal-json-strings": "^7.14.2",
+        "@babel/plugin-proposal-logical-assignment-operators": "^7.14.2",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2",
+        "@babel/plugin-proposal-numeric-separator": "^7.14.2",
+        "@babel/plugin-proposal-object-rest-spread": "^7.14.2",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.14.2",
+        "@babel/plugin-proposal-optional-chaining": "^7.14.2",
+        "@babel/plugin-proposal-private-methods": "^7.13.0",
+        "@babel/plugin-proposal-private-property-in-object": "^7.14.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.12.13",
+        "@babel/plugin-syntax-async-generators": "^7.8.4",
+        "@babel/plugin-syntax-class-properties": "^7.12.13",
+        "@babel/plugin-syntax-class-static-block": "^7.12.13",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+        "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+        "@babel/plugin-syntax-json-strings": "^7.8.3",
+        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+        "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+        "@babel/plugin-syntax-private-property-in-object": "^7.14.0",
+        "@babel/plugin-syntax-top-level-await": "^7.12.13",
+        "@babel/plugin-transform-arrow-functions": "^7.13.0",
+        "@babel/plugin-transform-async-to-generator": "^7.13.0",
+        "@babel/plugin-transform-block-scoped-functions": "^7.12.13",
+        "@babel/plugin-transform-block-scoping": "^7.14.2",
+        "@babel/plugin-transform-classes": "^7.14.2",
+        "@babel/plugin-transform-computed-properties": "^7.13.0",
+        "@babel/plugin-transform-destructuring": "^7.13.17",
+        "@babel/plugin-transform-dotall-regex": "^7.12.13",
+        "@babel/plugin-transform-duplicate-keys": "^7.12.13",
+        "@babel/plugin-transform-exponentiation-operator": "^7.12.13",
+        "@babel/plugin-transform-for-of": "^7.13.0",
+        "@babel/plugin-transform-function-name": "^7.12.13",
+        "@babel/plugin-transform-literals": "^7.12.13",
+        "@babel/plugin-transform-member-expression-literals": "^7.12.13",
+        "@babel/plugin-transform-modules-amd": "^7.14.2",
+        "@babel/plugin-transform-modules-commonjs": "^7.14.0",
+        "@babel/plugin-transform-modules-systemjs": "^7.13.8",
+        "@babel/plugin-transform-modules-umd": "^7.14.0",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13",
+        "@babel/plugin-transform-new-target": "^7.12.13",
+        "@babel/plugin-transform-object-super": "^7.12.13",
+        "@babel/plugin-transform-parameters": "^7.14.2",
+        "@babel/plugin-transform-property-literals": "^7.12.13",
+        "@babel/plugin-transform-regenerator": "^7.13.15",
+        "@babel/plugin-transform-reserved-words": "^7.12.13",
+        "@babel/plugin-transform-shorthand-properties": "^7.12.13",
+        "@babel/plugin-transform-spread": "^7.13.0",
+        "@babel/plugin-transform-sticky-regex": "^7.12.13",
+        "@babel/plugin-transform-template-literals": "^7.13.0",
+        "@babel/plugin-transform-typeof-symbol": "^7.12.13",
+        "@babel/plugin-transform-unicode-escapes": "^7.12.13",
+        "@babel/plugin-transform-unicode-regex": "^7.12.13",
+        "@babel/preset-modules": "^0.1.4",
+        "@babel/types": "^7.14.2",
+        "babel-plugin-polyfill-corejs2": "^0.2.0",
+        "babel-plugin-polyfill-corejs3": "^0.2.0",
+        "babel-plugin-polyfill-regenerator": "^0.2.0",
+        "core-js-compat": "^3.9.0",
+        "semver": "^6.3.0"
+      }
+    },
+    "@babel/preset-modules": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npm.taobao.org/@babel/preset-modules/download/@babel/preset-modules-0.1.4.tgz?cache=0&sync_timestamp=1598549645892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-modules%2Fdownload%2F%40babel%2Fpreset-modules-0.1.4.tgz",
+      "integrity": "sha1-Ni8raMZihClw/bXiVP/I/BwuQV4=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+        "@babel/plugin-transform-dotall-regex": "^7.4.4",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      }
+    },
+    "@babel/runtime": {
+      "version": "7.14.0",
+      "resolved": "https://registry.nlark.com/@babel/runtime/download/@babel/runtime-7.14.0.tgz?cache=0&sync_timestamp=1619727389508&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fruntime%2Fdownload%2F%40babel%2Fruntime-7.14.0.tgz",
+      "integrity": "sha1-RnlLwgthLF915i3QceJN/ZXxy+Y=",
+      "dev": true,
+      "requires": {
+        "regenerator-runtime": "^0.13.4"
+      }
+    },
+    "@babel/runtime-corejs2": {
+      "version": "7.14.0",
+      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.14.0.tgz",
+      "integrity": "sha512-btR4E8JiGlmmDI5YgirlG9z3T91rBdxnVh2YuEStrHDcekffaaIeK+CE0S4IaYUyYhMa7rFDfF2GEO79XNbLEA==",
+      "dev": true,
+      "requires": {
+        "core-js": "^2.6.5",
+        "regenerator-runtime": "^0.13.4"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.12",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+          "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/template": {
+      "version": "7.12.13",
+      "resolved": "https://registry.npm.taobao.org/@babel/template/download/@babel/template-7.12.13.tgz?cache=0&sync_timestamp=1612314730561&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Ftemplate%2Fdownload%2F%40babel%2Ftemplate-7.12.13.tgz",
+      "integrity": "sha1-UwJlvooliduzdSOETFvLVZR/syc=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.12.13",
+        "@babel/parser": "^7.12.13",
+        "@babel/types": "^7.12.13"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/traverse/download/@babel/traverse-7.14.2.tgz?cache=0&sync_timestamp=1620839457171&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftraverse%2Fdownload%2F%40babel%2Ftraverse-7.14.2.tgz",
+      "integrity": "sha1-kgGo2RJyOoMcJnnH678v4UFtdls=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.12.13",
+        "@babel/generator": "^7.14.2",
+        "@babel/helper-function-name": "^7.14.2",
+        "@babel/helper-split-export-declaration": "^7.12.13",
+        "@babel/parser": "^7.14.2",
+        "@babel/types": "^7.14.2",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0"
+      }
+    },
+    "@babel/types": {
+      "version": "7.14.2",
+      "resolved": "https://registry.nlark.com/@babel/types/download/@babel/types-7.14.2.tgz?cache=0&sync_timestamp=1620839445517&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Ftypes%2Fdownload%2F%40babel%2Ftypes-7.14.2.tgz",
+      "integrity": "sha1-QgiuADEH74oFfqgzPlbrZNL2osM=",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.14.0",
+        "to-fast-properties": "^2.0.0"
+      }
+    },
+    "@element-plus/icons": {
+      "version": "0.0.11",
+      "resolved": "https://registry.npmjs.org/@element-plus/icons/-/icons-0.0.11.tgz",
+      "integrity": "sha512-iKQXSxXu131Ai+I9Ymtcof9WId7kaXvB1+WRfAfpQCW7UiAMYgdNDqb/u0hgTo2Yq3MwC4MWJnNuTBEpG8r7+A=="
+    },
+    "@hapi/address": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npm.taobao.org/@hapi/address/download/@hapi/address-2.1.4.tgz?cache=0&sync_timestamp=1603524710662&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Faddress%2Fdownload%2F%40hapi%2Faddress-2.1.4.tgz",
+      "integrity": "sha1-XWftQ/P9QaadS5/3tW58DR0KgeU=",
+      "dev": true
+    },
+    "@hapi/bourne": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npm.taobao.org/@hapi/bourne/download/@hapi/bourne-1.3.2.tgz?cache=0&sync_timestamp=1593915150444&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Fbourne%2Fdownload%2F%40hapi%2Fbourne-1.3.2.tgz",
+      "integrity": "sha1-CnCVreoGckPOMoPhtWuKj0U7JCo=",
+      "dev": true
+    },
+    "@hapi/hoek": {
+      "version": "8.5.1",
+      "resolved": "https://registry.nlark.com/@hapi/hoek/download/@hapi/hoek-8.5.1.tgz",
+      "integrity": "sha1-/elgZMpEbeyMVajC8TCVewcMbgY=",
+      "dev": true
+    },
+    "@hapi/joi": {
+      "version": "15.1.1",
+      "resolved": "https://registry.npm.taobao.org/@hapi/joi/download/@hapi/joi-15.1.1.tgz",
+      "integrity": "sha1-xnW4pxKW8Cgz+NbSQ7NMV7jOGdc=",
+      "dev": true,
+      "requires": {
+        "@hapi/address": "2.x.x",
+        "@hapi/bourne": "1.x.x",
+        "@hapi/hoek": "8.x.x",
+        "@hapi/topo": "3.x.x"
+      }
+    },
+    "@hapi/topo": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npm.taobao.org/@hapi/topo/download/@hapi/topo-3.1.6.tgz?cache=0&sync_timestamp=1593916080558&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Ftopo%2Fdownload%2F%40hapi%2Ftopo-3.1.6.tgz",
+      "integrity": "sha1-aNk1+j6uf91asNf5U/MgXYsr/Ck=",
+      "dev": true,
+      "requires": {
+        "@hapi/hoek": "^8.3.0"
+      }
+    },
+    "@intervolga/optimize-cssnano-plugin": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npm.taobao.org/@intervolga/optimize-cssnano-plugin/download/@intervolga/optimize-cssnano-plugin-1.0.6.tgz",
+      "integrity": "sha1-vnx4RhKLiPapsdEmGgrQbrXA/fg=",
+      "dev": true,
+      "requires": {
+        "cssnano": "^4.0.0",
+        "cssnano-preset-default": "^4.0.0",
+        "postcss": "^7.0.0"
+      }
+    },
+    "@intlify/core-base": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.1.7.tgz",
+      "integrity": "sha512-q1W2j81xbHyfKrNcca/CeJyf0Bcx4u9UDu05l7AaiJbqOseTme2o2I3wp1hDDCtmC7k7HgX0sAygyHNJH9swuQ==",
+      "requires": {
+        "@intlify/devtools-if": "9.1.7",
+        "@intlify/message-compiler": "9.1.7",
+        "@intlify/message-resolver": "9.1.7",
+        "@intlify/runtime": "9.1.7",
+        "@intlify/shared": "9.1.7",
+        "@intlify/vue-devtools": "9.1.7"
+      }
+    },
+    "@intlify/devtools-if": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.1.7.tgz",
+      "integrity": "sha512-/DcN5FUySSkQhDqx5y1RvxfuCXO3Ot/dUEIOs472qbM7Hyb2qif+eXCnwHBzlI4+wEfQVT6L0PiM1a7Er/ro9g==",
+      "requires": {
+        "@intlify/shared": "9.1.7"
+      }
+    },
+    "@intlify/message-compiler": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.1.7.tgz",
+      "integrity": "sha512-JZNkAhr3O7tnbdbRBcpYfqr/Ai26WTzX0K/lV8Y1KVdOIj/dGiamaffdWUdFiDXUnbJRNbPiOaKxy7Pwip3KxQ==",
+      "requires": {
+        "@intlify/message-resolver": "9.1.7",
+        "@intlify/shared": "9.1.7",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
+    "@intlify/message-resolver": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.1.7.tgz",
+      "integrity": "sha512-WTK+OaXJYjyquLGhuCyDvU2WHkG+kXzXeHagmVFHn+s118Jf2143zzkLLUrapP5CtZ/csuyjmYg7b3xQRQAmvw=="
+    },
+    "@intlify/runtime": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.1.7.tgz",
+      "integrity": "sha512-QURPSlzhOVnRwS2XMGpCDsDkP42kfVBh94aAORxh/gVGzdgJip2vagrIFij/J69aEqdB476WJkMhVjP8VSHmiA==",
+      "requires": {
+        "@intlify/message-compiler": "9.1.7",
+        "@intlify/message-resolver": "9.1.7",
+        "@intlify/shared": "9.1.7"
+      }
+    },
+    "@intlify/shared": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.1.7.tgz",
+      "integrity": "sha512-zt0zlUdalumvT9AjQNxPXA36UgOndUyvBMplh8uRZU0fhWHAwhnJTcf0NaG9Qvr8I1n3HPSs96+kLb/YdwTavQ=="
+    },
+    "@intlify/vue-devtools": {
+      "version": "9.1.7",
+      "resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.1.7.tgz",
+      "integrity": "sha512-DI5Wc0aOiohtBUGUkKAcryCWbbuaO4/PK4Pa/LaNCsFNxbtgR5qkIDmhBv9xVPYGTUhySXxaDDAMvOpBjhPJjw==",
+      "requires": {
+        "@intlify/message-resolver": "9.1.7",
+        "@intlify/runtime": "9.1.7",
+        "@intlify/shared": "9.1.7"
+      }
+    },
+    "@mrmlnc/readdir-enhanced": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npm.taobao.org/@mrmlnc/readdir-enhanced/download/@mrmlnc/readdir-enhanced-2.2.1.tgz",
+      "integrity": "sha1-UkryQNGjYFJ7cwR17PoTRKpUDd4=",
+      "dev": true,
+      "requires": {
+        "call-me-maybe": "^1.0.1",
+        "glob-to-regexp": "^0.3.0"
+      }
+    },
+    "@nodelib/fs.scandir": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
+      "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "2.0.4",
+        "run-parallel": "^1.1.9"
+      },
+      "dependencies": {
+        "@nodelib/fs.stat": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
+          "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
+          "dev": true
+        }
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npm.taobao.org/@nodelib/fs.stat/download/@nodelib/fs.stat-1.1.3.tgz?cache=0&sync_timestamp=1609074429033&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40nodelib%2Ffs.stat%2Fdownload%2F%40nodelib%2Ffs.stat-1.1.3.tgz",
+      "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
+      "dev": true
+    },
+    "@nodelib/fs.walk": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
+      "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.4",
+        "fastq": "^1.6.0"
+      }
+    },
+    "@popperjs/core": {
+      "version": "2.9.3",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.3.tgz",
+      "integrity": "sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ=="
+    },
+    "@soda/friendly-errors-webpack-plugin": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.8.0.tgz?cache=0&sync_timestamp=1607927364103&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40soda%2Ffriendly-errors-webpack-plugin%2Fdownload%2F%40soda%2Ffriendly-errors-webpack-plugin-1.8.0.tgz",
+      "integrity": "sha1-hHUdgqkwGdXJLAzw5FrFkIfNIkA=",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "error-stack-parser": "^2.0.2",
+        "string-width": "^2.0.0",
+        "strip-ansi": "^5"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-2.0.0.tgz?cache=0&sync_timestamp=1618552489864&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-fullwidth-code-point%2Fdownload%2Fis-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npm.taobao.org/string-width/download/string-width-2.1.1.tgz",
+          "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          },
+          "dependencies": {
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-4.0.0.tgz?cache=0&sync_timestamp=1618553299612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^3.0.0"
+              }
+            }
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1618553299612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz",
+          "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
+              "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "@soda/get-current-script": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/@soda/get-current-script/download/@soda/get-current-script-1.0.2.tgz?cache=0&sync_timestamp=1592273265306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40soda%2Fget-current-script%2Fdownload%2F%40soda%2Fget-current-script-1.0.2.tgz",
+      "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
+      "dev": true
+    },
+    "@stylelint/postcss-css-in-js": {
+      "version": "0.37.2",
+      "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz",
+      "integrity": "sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA==",
+      "dev": true,
+      "requires": {
+        "@babel/core": ">=7.9.0"
+      }
+    },
+    "@stylelint/postcss-markdown": {
+      "version": "0.36.2",
+      "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.2.tgz",
+      "integrity": "sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==",
+      "dev": true,
+      "requires": {
+        "remark": "^13.0.0",
+        "unist-util-find-all-after": "^3.0.2"
+      }
+    },
+    "@types/body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.nlark.com/@types/body-parser/download/@types/body-parser-1.19.0.tgz?cache=0&sync_timestamp=1621240672784&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fbody-parser%2Fdownload%2F%40types%2Fbody-parser-1.19.0.tgz",
+      "integrity": "sha1-BoWzxH6zAG/+0RfN1VFkth+AU48=",
+      "dev": true,
+      "requires": {
+        "@types/connect": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/codemirror": {
+      "version": "5.60.1",
+      "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.1.tgz",
+      "integrity": "sha512-yV14LQ5VvghnW0uSuCw2bEfZC6NvxHQEckl2w3dEk5l0yPGzQh14dCaWvG5KD/2l3cgFSifR+6nIUD7LDLdUTg==",
+      "dev": true,
+      "requires": {
+        "@types/tern": "*"
+      }
+    },
+    "@types/connect": {
+      "version": "3.4.34",
+      "resolved": "https://registry.nlark.com/@types/connect/download/@types/connect-3.4.34.tgz",
+      "integrity": "sha1-FwpAIjptZmAG2TyhKK8r6x2bGQE=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/connect-history-api-fallback": {
+      "version": "1.3.4",
+      "resolved": "https://registry.nlark.com/@types/connect-history-api-fallback/download/@types/connect-history-api-fallback-1.3.4.tgz?cache=0&sync_timestamp=1621240807633&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fconnect-history-api-fallback%2Fdownload%2F%40types%2Fconnect-history-api-fallback-1.3.4.tgz",
+      "integrity": "sha1-jA8Obl2CUraZ9aZi9Rvfgv2di7g=",
+      "dev": true,
+      "requires": {
+        "@types/express-serve-static-core": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/estree": {
+      "version": "0.0.48",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz",
+      "integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==",
+      "dev": true
+    },
+    "@types/express": {
+      "version": "4.17.12",
+      "resolved": "https://registry.nlark.com/@types/express/download/@types/express-4.17.12.tgz?cache=0&sync_timestamp=1621962565565&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fexpress%2Fdownload%2F%40types%2Fexpress-4.17.12.tgz",
+      "integrity": "sha1-S8G/PNDP5tP28oU2SLQNt9VN41A=",
+      "dev": true,
+      "requires": {
+        "@types/body-parser": "*",
+        "@types/express-serve-static-core": "^4.17.18",
+        "@types/qs": "*",
+        "@types/serve-static": "*"
+      }
+    },
+    "@types/express-serve-static-core": {
+      "version": "4.17.20",
+      "resolved": "https://registry.nlark.com/@types/express-serve-static-core/download/@types/express-serve-static-core-4.17.20.tgz?cache=0&sync_timestamp=1621962788076&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fexpress-serve-static-core%2Fdownload%2F%40types%2Fexpress-serve-static-core-4.17.20.tgz",
+      "integrity": "sha1-RMruAp8sJsRnEdpehFzcEhZ61y0=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*"
+      }
+    },
+    "@types/glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.nlark.com/@types/glob/download/@types/glob-7.1.3.tgz",
+      "integrity": "sha1-5rqA82t9qtLGhazZJmOC5omFwYM=",
+      "dev": true,
+      "requires": {
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/http-proxy": {
+      "version": "1.17.6",
+      "resolved": "https://registry.nlark.com/@types/http-proxy/download/@types/http-proxy-1.17.6.tgz?cache=0&sync_timestamp=1621034259660&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fhttp-proxy%2Fdownload%2F%40types%2Fhttp-proxy-1.17.6.tgz",
+      "integrity": "sha1-Ytw/reIn1qwoYsjxnuDanan9hhY=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/json-schema": {
+      "version": "7.0.7",
+      "resolved": "https://registry.nlark.com/@types/json-schema/download/@types/json-schema-7.0.7.tgz",
+      "integrity": "sha1-mKmTUWyFnrDVxMjwmDF6nqaNua0=",
+      "dev": true
+    },
+    "@types/mdast": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz",
+      "integrity": "sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw==",
+      "dev": true,
+      "requires": {
+        "@types/unist": "*"
+      }
+    },
+    "@types/mime": {
+      "version": "1.3.2",
+      "resolved": "https://registry.nlark.com/@types/mime/download/@types/mime-1.3.2.tgz?cache=0&sync_timestamp=1621241862733&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fmime%2Fdownload%2F%40types%2Fmime-1.3.2.tgz",
+      "integrity": "sha1-k+Jb+e51/g/YC1lLxP6w6GIRG1o=",
+      "dev": true
+    },
+    "@types/mini-css-extract-plugin": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz",
+      "integrity": "sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ==",
+      "dev": true,
+      "requires": {
+        "@types/webpack": "*"
+      }
+    },
+    "@types/minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.nlark.com/@types/minimatch/download/@types/minimatch-3.0.4.tgz?cache=0&sync_timestamp=1621241868071&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fminimatch%2Fdownload%2F%40types%2Fminimatch-3.0.4.tgz",
+      "integrity": "sha1-8Owl2/Lw5LGGRzE6wDETTKWySyE=",
+      "dev": true
+    },
+    "@types/minimist": {
+      "version": "1.2.1",
+      "resolved": "https://registry.nlark.com/@types/minimist/download/@types/minimist-1.2.1.tgz?cache=0&sync_timestamp=1621241867849&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fminimist%2Fdownload%2F%40types%2Fminimist-1.2.1.tgz",
+      "integrity": "sha1-KD9mn/dte4Jg34q3pCYsyD2YglY=",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "15.6.1",
+      "resolved": "https://registry.nlark.com/@types/node/download/@types/node-15.6.1.tgz",
+      "integrity": "sha1-MtQzkNXGLFtuxIapvJxZVE3jmgg=",
+      "dev": true
+    },
+    "@types/normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.nlark.com/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1621242104575&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz",
+      "integrity": "sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=",
+      "dev": true
+    },
+    "@types/parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+      "dev": true
+    },
+    "@types/q": {
+      "version": "1.5.4",
+      "resolved": "https://registry.nlark.com/@types/q/download/@types/q-1.5.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fq%2Fdownload%2F%40types%2Fq-1.5.4.tgz",
+      "integrity": "sha1-FZJUFOCtLNdlv+9YhC9+JqesyyQ=",
+      "dev": true
+    },
+    "@types/qs": {
+      "version": "6.9.6",
+      "resolved": "https://registry.nlark.com/@types/qs/download/@types/qs-6.9.6.tgz?cache=0&sync_timestamp=1621242292262&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fqs%2Fdownload%2F%40types%2Fqs-6.9.6.tgz",
+      "integrity": "sha1-35w8izGiR+wxXmmWVmvjFx30s7E=",
+      "dev": true
+    },
+    "@types/range-parser": {
+      "version": "1.2.3",
+      "resolved": "https://registry.nlark.com/@types/range-parser/download/@types/range-parser-1.2.3.tgz?cache=0&sync_timestamp=1621242291785&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Frange-parser%2Fdownload%2F%40types%2Frange-parser-1.2.3.tgz",
+      "integrity": "sha1-fuMwunyq+5gJC+zoal7kQRWQTCw=",
+      "dev": true
+    },
+    "@types/serve-static": {
+      "version": "1.13.9",
+      "resolved": "https://registry.nlark.com/@types/serve-static/download/@types/serve-static-1.13.9.tgz?cache=0&sync_timestamp=1621242704905&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fserve-static%2Fdownload%2F%40types%2Fserve-static-1.13.9.tgz",
+      "integrity": "sha1-qs8oqFoF7imhH7fD6tk1rFbzPk4=",
+      "dev": true,
+      "requires": {
+        "@types/mime": "^1",
+        "@types/node": "*"
+      }
+    },
+    "@types/source-list-map": {
+      "version": "0.1.2",
+      "resolved": "https://registry.nlark.com/@types/source-list-map/download/@types/source-list-map-0.1.2.tgz",
+      "integrity": "sha1-AHiDYGP/rxdBI0m7o2QIfgrALsk=",
+      "dev": true
+    },
+    "@types/tapable": {
+      "version": "1.0.7",
+      "resolved": "https://registry.nlark.com/@types/tapable/download/@types/tapable-1.0.7.tgz",
+      "integrity": "sha1-VFFYNC+Uno/Tv9gTIklx7N3D+sQ=",
+      "dev": true
+    },
+    "@types/tern": {
+      "version": "0.23.3",
+      "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.3.tgz",
+      "integrity": "sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w==",
+      "dev": true,
+      "requires": {
+        "@types/estree": "*"
+      }
+    },
+    "@types/uglify-js": {
+      "version": "3.13.0",
+      "resolved": "https://registry.nlark.com/@types/uglify-js/download/@types/uglify-js-3.13.0.tgz",
+      "integrity": "sha1-HK2N8fsLFDxaugjeVxLqnR/3ESQ=",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "@types/unist": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
+      "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
+      "dev": true
+    },
+    "@types/webpack": {
+      "version": "4.41.29",
+      "resolved": "https://registry.nlark.com/@types/webpack/download/@types/webpack-4.41.29.tgz?cache=0&sync_timestamp=1621533733988&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fwebpack%2Fdownload%2F%40types%2Fwebpack-4.41.29.tgz",
+      "integrity": "sha1-LmbB3oIjxEA2ZGlBXFCkfZdiV3M=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "@types/tapable": "^1",
+        "@types/uglify-js": "*",
+        "@types/webpack-sources": "*",
+        "anymatch": "^3.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "@types/webpack-dev-server": {
+      "version": "3.11.4",
+      "resolved": "https://registry.nlark.com/@types/webpack-dev-server/download/@types/webpack-dev-server-3.11.4.tgz",
+      "integrity": "sha1-kNR91mC2ltQJQxq4wen6NhUQOgc=",
+      "dev": true,
+      "requires": {
+        "@types/connect-history-api-fallback": "*",
+        "@types/express": "*",
+        "@types/serve-static": "*",
+        "@types/webpack": "^4",
+        "http-proxy-middleware": "^1.0.0"
+      }
+    },
+    "@types/webpack-sources": {
+      "version": "2.1.0",
+      "resolved": "https://registry.nlark.com/@types/webpack-sources/download/@types/webpack-sources-2.1.0.tgz?cache=0&sync_timestamp=1621243863278&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fwebpack-sources%2Fdownload%2F%40types%2Fwebpack-sources-2.1.0.tgz",
+      "integrity": "sha1-iIKwvWLR4M5i8YPQ0Bty5ugujBA=",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "@types/source-list-map": "*",
+        "source-map": "^0.7.3"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.7.3",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.7.3.tgz",
+          "integrity": "sha1-UwL4FpAxc1ImVECS5kmB91F1A4M=",
+          "dev": true
+        }
+      }
+    },
+    "@ungap/promise-all-settled": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
+      "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+      "dev": true
+    },
+    "@vue/babel-helper-vue-jsx-merge-props": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.2.1.tgz?cache=0&sync_timestamp=1602851135129&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-helper-vue-jsx-merge-props%2Fdownload%2F%40vue%2Fbabel-helper-vue-jsx-merge-props-1.2.1.tgz",
+      "integrity": "sha1-MWJKelBfsU2h1YAjclpMXycOaoE=",
+      "dev": true
+    },
+    "@vue/babel-helper-vue-transform-on": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-helper-vue-transform-on/download/@vue/babel-helper-vue-transform-on-1.0.2.tgz?cache=0&sync_timestamp=1610812663852&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-helper-vue-transform-on%2Fdownload%2F%40vue%2Fbabel-helper-vue-transform-on-1.0.2.tgz",
+      "integrity": "sha1-m5xpHNBvyFUiGiR1w8yDHXdLx9w=",
+      "dev": true
+    },
+    "@vue/babel-plugin-jsx": {
+      "version": "1.0.6",
+      "resolved": "https://registry.nlark.com/@vue/babel-plugin-jsx/download/@vue/babel-plugin-jsx-1.0.6.tgz?cache=0&sync_timestamp=1619929844730&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fbabel-plugin-jsx%2Fdownload%2F%40vue%2Fbabel-plugin-jsx-1.0.6.tgz",
+      "integrity": "sha1-GEvzVBq279vlB5q4sgwZ4q8QC/s=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/plugin-syntax-jsx": "^7.0.0",
+        "@babel/template": "^7.0.0",
+        "@babel/traverse": "^7.0.0",
+        "@babel/types": "^7.0.0",
+        "@vue/babel-helper-vue-transform-on": "^1.0.2",
+        "camelcase": "^6.0.0",
+        "html-tags": "^3.1.0",
+        "svg-tags": "^1.0.0"
+      }
+    },
+    "@vue/babel-plugin-transform-vue-jsx": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-plugin-transform-vue-jsx/download/@vue/babel-plugin-transform-vue-jsx-1.2.1.tgz?cache=0&sync_timestamp=1602851234609&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-plugin-transform-vue-jsx%2Fdownload%2F%40vue%2Fbabel-plugin-transform-vue-jsx-1.2.1.tgz",
+      "integrity": "sha1-ZGBGxlLC8CQnJ/NFGdkXsGQEHtc=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
+        "html-tags": "^2.0.0",
+        "lodash.kebabcase": "^4.1.1",
+        "svg-tags": "^1.0.0"
+      },
+      "dependencies": {
+        "html-tags": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/html-tags/download/html-tags-2.0.0.tgz",
+          "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
+          "dev": true
+        }
+      }
+    },
+    "@vue/babel-preset-app": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/babel-preset-app/download/@vue/babel-preset-app-4.5.13.tgz",
+      "integrity": "sha1-y0dTIeTHP38RDawppIwqnLgK/rY=",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.11.0",
+        "@babel/helper-compilation-targets": "^7.9.6",
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/plugin-proposal-class-properties": "^7.8.3",
+        "@babel/plugin-proposal-decorators": "^7.8.3",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+        "@babel/plugin-syntax-jsx": "^7.8.3",
+        "@babel/plugin-transform-runtime": "^7.11.0",
+        "@babel/preset-env": "^7.11.0",
+        "@babel/runtime": "^7.11.0",
+        "@vue/babel-plugin-jsx": "^1.0.3",
+        "@vue/babel-preset-jsx": "^1.2.4",
+        "babel-plugin-dynamic-import-node": "^2.3.3",
+        "core-js": "^3.6.5",
+        "core-js-compat": "^3.6.5",
+        "semver": "^6.1.0"
+      }
+    },
+    "@vue/babel-preset-jsx": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-preset-jsx/download/@vue/babel-preset-jsx-1.2.4.tgz?cache=0&sync_timestamp=1603806812399&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-preset-jsx%2Fdownload%2F%40vue%2Fbabel-preset-jsx-1.2.4.tgz",
+      "integrity": "sha1-kv6nnbbxOwHoDToAmeKSS9y+Toc=",
+      "dev": true,
+      "requires": {
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
+        "@vue/babel-sugar-composition-api-inject-h": "^1.2.1",
+        "@vue/babel-sugar-composition-api-render-instance": "^1.2.4",
+        "@vue/babel-sugar-functional-vue": "^1.2.2",
+        "@vue/babel-sugar-inject-h": "^1.2.2",
+        "@vue/babel-sugar-v-model": "^1.2.3",
+        "@vue/babel-sugar-v-on": "^1.2.3"
+      }
+    },
+    "@vue/babel-sugar-composition-api-inject-h": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-composition-api-inject-h/download/@vue/babel-sugar-composition-api-inject-h-1.2.1.tgz?cache=0&sync_timestamp=1602851126644&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-composition-api-inject-h%2Fdownload%2F%40vue%2Fbabel-sugar-composition-api-inject-h-1.2.1.tgz",
+      "integrity": "sha1-BdbgxDJxDjdYKyvppgSbaJtvA+s=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      }
+    },
+    "@vue/babel-sugar-composition-api-render-instance": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-composition-api-render-instance/download/@vue/babel-sugar-composition-api-render-instance-1.2.4.tgz",
+      "integrity": "sha1-5MvGmXw0T6wnF4WteikyXFHWjRk=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      }
+    },
+    "@vue/babel-sugar-functional-vue": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-functional-vue/download/@vue/babel-sugar-functional-vue-1.2.2.tgz?cache=0&sync_timestamp=1602929516892&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-functional-vue%2Fdownload%2F%40vue%2Fbabel-sugar-functional-vue-1.2.2.tgz",
+      "integrity": "sha1-JnqayNeHyW7b8Dzj85LEnam9Jlg=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      }
+    },
+    "@vue/babel-sugar-inject-h": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-inject-h/download/@vue/babel-sugar-inject-h-1.2.2.tgz?cache=0&sync_timestamp=1602929516704&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-inject-h%2Fdownload%2F%40vue%2Fbabel-sugar-inject-h-1.2.2.tgz",
+      "integrity": "sha1-1zjTyJM2fshJHcu2abAAkZKT46o=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      }
+    },
+    "@vue/babel-sugar-v-model": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-v-model/download/@vue/babel-sugar-v-model-1.2.3.tgz?cache=0&sync_timestamp=1603182448903&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-v-model%2Fdownload%2F%40vue%2Fbabel-sugar-v-model-1.2.3.tgz",
+      "integrity": "sha1-+h8pulHr8KoabDX6ZtU5vEWaGPI=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
+        "camelcase": "^5.0.0",
+        "html-tags": "^2.0.0",
+        "svg-tags": "^1.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz",
+          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
+          "dev": true
+        },
+        "html-tags": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/html-tags/download/html-tags-2.0.0.tgz",
+          "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
+          "dev": true
+        }
+      }
+    },
+    "@vue/babel-sugar-v-on": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npm.taobao.org/@vue/babel-sugar-v-on/download/@vue/babel-sugar-v-on-1.2.3.tgz?cache=0&sync_timestamp=1603181872947&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fbabel-sugar-v-on%2Fdownload%2F%40vue%2Fbabel-sugar-v-on-1.2.3.tgz",
+      "integrity": "sha1-NCNnF4WGpp85LwS/ujICHQKROto=",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
+        "camelcase": "^5.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz",
+          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
+          "dev": true
+        }
+      }
+    },
+    "@vue/cli-overlay": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-overlay/download/@vue/cli-overlay-4.5.13.tgz",
+      "integrity": "sha1-Tx/SFhvo9p1suoB58/DX3E3uR6c=",
+      "dev": true
+    },
+    "@vue/cli-plugin-babel": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-plugin-babel/download/@vue/cli-plugin-babel-4.5.13.tgz",
+      "integrity": "sha1-qJxILtzE6h0TVkXOxQKn9f1MMOc=",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.11.0",
+        "@vue/babel-preset-app": "^4.5.13",
+        "@vue/cli-shared-utils": "^4.5.13",
+        "babel-loader": "^8.1.0",
+        "cache-loader": "^4.1.0",
+        "thread-loader": "^2.1.3",
+        "webpack": "^4.0.0"
+      }
+    },
+    "@vue/cli-plugin-eslint": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-plugin-eslint/download/@vue/cli-plugin-eslint-4.5.13.tgz",
+      "integrity": "sha1-i68i0NltdnIMdQZka5b09iwFvfo=",
+      "dev": true,
+      "requires": {
+        "@vue/cli-shared-utils": "^4.5.13",
+        "eslint-loader": "^2.2.1",
+        "globby": "^9.2.0",
+        "inquirer": "^7.1.0",
+        "webpack": "^4.0.0",
+        "yorkie": "^2.0.0"
+      }
+    },
+    "@vue/cli-plugin-router": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-plugin-router/download/@vue/cli-plugin-router-4.5.13.tgz?cache=0&sync_timestamp=1620982327353&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fcli-plugin-router%2Fdownload%2F%40vue%2Fcli-plugin-router-4.5.13.tgz",
+      "integrity": "sha1-C2fIiYor8TKUGRmiouXzqsvZ/74=",
+      "dev": true,
+      "requires": {
+        "@vue/cli-shared-utils": "^4.5.13"
+      }
+    },
+    "@vue/cli-plugin-unit-mocha": {
+      "version": "4.5.13",
+      "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-mocha/-/cli-plugin-unit-mocha-4.5.13.tgz",
+      "integrity": "sha512-4o3QAK5sLsqBc5D6E7ya2ptaYMi/Guiq5i7By2++txAh+Os3UukqmCYoyN7TtmdUKyqpgEqBtirPQhbQo0r/Fw==",
+      "dev": true,
+      "requires": {
+        "@vue/cli-shared-utils": "^4.5.13",
+        "jsdom": "^15.2.1",
+        "jsdom-global": "^3.0.2",
+        "mocha": "^6.2.2",
+        "mochapack": "^1.1.15"
+      },
+      "dependencies": {
+        "ansi-colors": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+          "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+          "dev": true
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        },
+        "cliui": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+          "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+          "dev": true,
+          "requires": {
+            "string-width": "^3.1.0",
+            "strip-ansi": "^5.2.0",
+            "wrap-ansi": "^5.1.0"
+          }
+        },
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "diff": {
+          "version": "3.5.0",
+          "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+          "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "flat": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz",
+          "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==",
+          "dev": true,
+          "requires": {
+            "is-buffer": "~2.0.3"
+          }
+        },
+        "glob": {
+          "version": "7.1.3",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+          "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "is-buffer": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+          "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "js-yaml": {
+          "version": "3.13.1",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+          "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+          "dev": true,
+          "requires": {
+            "argparse": "^1.0.7",
+            "esprima": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
+          "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.5"
+          }
+        },
+        "mocha": {
+          "version": "6.2.3",
+          "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz",
+          "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==",
+          "dev": true,
+          "requires": {
+            "ansi-colors": "3.2.3",
+            "browser-stdout": "1.3.1",
+            "debug": "3.2.6",
+            "diff": "3.5.0",
+            "escape-string-regexp": "1.0.5",
+            "find-up": "3.0.0",
+            "glob": "7.1.3",
+            "growl": "1.10.5",
+            "he": "1.2.0",
+            "js-yaml": "3.13.1",
+            "log-symbols": "2.2.0",
+            "minimatch": "3.0.4",
+            "mkdirp": "0.5.4",
+            "ms": "2.1.1",
+            "node-environment-flags": "1.0.5",
+            "object.assign": "4.1.0",
+            "strip-json-comments": "2.0.1",
+            "supports-color": "6.0.0",
+            "which": "1.3.1",
+            "wide-align": "1.1.3",
+            "yargs": "13.3.2",
+            "yargs-parser": "13.1.2",
+            "yargs-unparser": "1.6.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "object.assign": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+          "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+          "dev": true,
+          "requires": {
+            "define-properties": "^1.1.2",
+            "function-bind": "^1.1.1",
+            "has-symbols": "^1.0.0",
+            "object-keys": "^1.0.11"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+          "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "wrap-ansi": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+          "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.0",
+            "string-width": "^3.0.0",
+            "strip-ansi": "^5.0.0"
+          }
+        },
+        "yargs": {
+          "version": "13.3.2",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+          "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+          "dev": true,
+          "requires": {
+            "cliui": "^5.0.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^2.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^2.0.0",
+            "set-blocking": "^2.0.0",
+            "string-width": "^3.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^4.0.0",
+            "yargs-parser": "^13.1.2"
+          }
+        },
+        "yargs-parser": {
+          "version": "13.1.2",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+          "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        },
+        "yargs-unparser": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+          "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+          "dev": true,
+          "requires": {
+            "flat": "^4.1.0",
+            "lodash": "^4.17.15",
+            "yargs": "^13.3.0"
+          }
+        }
+      }
+    },
+    "@vue/cli-plugin-vuex": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-plugin-vuex/download/@vue/cli-plugin-vuex-4.5.13.tgz?cache=0&sync_timestamp=1620982316986&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fcli-plugin-vuex%2Fdownload%2F%40vue%2Fcli-plugin-vuex-4.5.13.tgz",
+      "integrity": "sha1-mGRti8HmnPbGpsui/tPqzgNWw2A=",
+      "dev": true
+    },
+    "@vue/cli-service": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-service/download/@vue/cli-service-4.5.13.tgz",
+      "integrity": "sha1-oJ5oSoAWhLbiTlQUrTBlCXDuye0=",
+      "dev": true,
+      "requires": {
+        "@intervolga/optimize-cssnano-plugin": "^1.0.5",
+        "@soda/friendly-errors-webpack-plugin": "^1.7.1",
+        "@soda/get-current-script": "^1.0.0",
+        "@types/minimist": "^1.2.0",
+        "@types/webpack": "^4.0.0",
+        "@types/webpack-dev-server": "^3.11.0",
+        "@vue/cli-overlay": "^4.5.13",
+        "@vue/cli-plugin-router": "^4.5.13",
+        "@vue/cli-plugin-vuex": "^4.5.13",
+        "@vue/cli-shared-utils": "^4.5.13",
+        "@vue/component-compiler-utils": "^3.1.2",
+        "@vue/preload-webpack-plugin": "^1.1.0",
+        "@vue/web-component-wrapper": "^1.2.0",
+        "acorn": "^7.4.0",
+        "acorn-walk": "^7.1.1",
+        "address": "^1.1.2",
+        "autoprefixer": "^9.8.6",
+        "browserslist": "^4.12.0",
+        "cache-loader": "^4.1.0",
+        "case-sensitive-paths-webpack-plugin": "^2.3.0",
+        "cli-highlight": "^2.1.4",
+        "clipboardy": "^2.3.0",
+        "cliui": "^6.0.0",
+        "copy-webpack-plugin": "^5.1.1",
+        "css-loader": "^3.5.3",
+        "cssnano": "^4.1.10",
+        "debug": "^4.1.1",
+        "default-gateway": "^5.0.5",
+        "dotenv": "^8.2.0",
+        "dotenv-expand": "^5.1.0",
+        "file-loader": "^4.2.0",
+        "fs-extra": "^7.0.1",
+        "globby": "^9.2.0",
+        "hash-sum": "^2.0.0",
+        "html-webpack-plugin": "^3.2.0",
+        "launch-editor-middleware": "^2.2.1",
+        "lodash.defaultsdeep": "^4.6.1",
+        "lodash.mapvalues": "^4.6.0",
+        "lodash.transform": "^4.6.0",
+        "mini-css-extract-plugin": "^0.9.0",
+        "minimist": "^1.2.5",
+        "pnp-webpack-plugin": "^1.6.4",
+        "portfinder": "^1.0.26",
+        "postcss-loader": "^3.0.0",
+        "ssri": "^8.0.1",
+        "terser-webpack-plugin": "^1.4.4",
+        "thread-loader": "^2.1.3",
+        "url-loader": "^2.2.0",
+        "vue-loader": "^15.9.2",
+        "vue-loader-v16": "npm:vue-loader@^16.1.0",
+        "vue-style-loader": "^4.1.2",
+        "webpack": "^4.0.0",
+        "webpack-bundle-analyzer": "^3.8.0",
+        "webpack-chain": "^6.4.0",
+        "webpack-dev-server": "^3.11.0",
+        "webpack-merge": "^4.2.2"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.4.1",
+          "resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1620134156200&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz",
+          "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+          "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
+        "ssri": {
+          "version": "8.0.1",
+          "resolved": "https://registry.nlark.com/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1621364735533&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
+          "integrity": "sha1-Y45OQ54v+9LNKJd21cpFfE9Roq8=",
+          "dev": true,
+          "requires": {
+            "minipass": "^3.1.1"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "vue-loader-v16": {
+          "version": "npm:vue-loader@16.5.0",
+          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.5.0.tgz",
+          "integrity": "sha512-WXh+7AgFxGTgb5QAkQtFeUcHNIEq3PGVQ8WskY5ZiFbWBkOwcCPRs4w/2tVyTbh2q6TVRlO3xfvIukUtjsu62A==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chalk": "^4.1.0",
+            "hash-sum": "^2.0.0",
+            "loader-utils": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@vue/cli-shared-utils": {
+      "version": "4.5.13",
+      "resolved": "https://registry.nlark.com/@vue/cli-shared-utils/download/@vue/cli-shared-utils-4.5.13.tgz",
+      "integrity": "sha1-rNQPMbR5DxY0KSvapfypXcHg/1A=",
+      "dev": true,
+      "requires": {
+        "@hapi/joi": "^15.0.1",
+        "chalk": "^2.4.2",
+        "execa": "^1.0.0",
+        "launch-editor": "^2.2.1",
+        "lru-cache": "^5.1.1",
+        "node-ipc": "^9.1.1",
+        "open": "^6.3.0",
+        "ora": "^3.4.0",
+        "read-pkg": "^5.1.1",
+        "request": "^2.88.2",
+        "semver": "^6.1.0",
+        "strip-ansi": "^6.0.0"
+      }
+    },
+    "@vue/compiler-core": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.0.tgz",
+      "integrity": "sha512-+kfA4pisto26tcEh9Naf/qrizplYWnkBLHu3fX5Yu0c47RVBteVG3dHENFczl3Egwra+5NP5f3YuOgxK1ZMbNQ==",
+      "requires": {
+        "@babel/parser": "^7.12.0",
+        "@babel/types": "^7.12.0",
+        "@vue/shared": "3.2.0",
+        "estree-walker": "^2.0.1",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
+    "@vue/compiler-dom": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.0.tgz",
+      "integrity": "sha512-CqfATmX04+58LNBTTUPRBLyYGLP0bxtL+8b7B8pEvXja7fpmxiYcKBQsdaXfyqoRJsaTzA7eVXQt/t0dYhu/SQ==",
+      "requires": {
+        "@vue/compiler-core": "3.2.0",
+        "@vue/shared": "3.2.0"
+      }
+    },
+    "@vue/compiler-sfc": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.1.tgz",
+      "integrity": "sha512-lSgMsZaYHF+bAgryq5aUqpvyfhu52GJI2/4LoiJCE5uaxc6FCZfxfgqgw/d9ltiZghv+HiISFtmQVAVvlsk+/w==",
+      "dev": true,
+      "requires": {
+        "@babel/parser": "^7.13.9",
+        "@babel/types": "^7.13.0",
+        "@vue/compiler-core": "3.1.1",
+        "@vue/compiler-dom": "3.1.1",
+        "@vue/compiler-ssr": "3.1.1",
+        "@vue/shared": "3.1.1",
+        "consolidate": "^0.16.0",
+        "estree-walker": "^2.0.1",
+        "hash-sum": "^2.0.0",
+        "lru-cache": "^5.1.1",
+        "magic-string": "^0.25.7",
+        "merge-source-map": "^1.1.0",
+        "postcss": "^8.1.10",
+        "postcss-modules": "^4.0.0",
+        "postcss-selector-parser": "^6.0.4",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "@vue/compiler-core": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.1.tgz",
+          "integrity": "sha512-Z1RO3T6AEtAUFf2EqqovFm3ohAeTvFzRtB0qUENW2nEerJfdlk13/LS1a0EgsqlzxmYfR/S/S/gW9PLbFZZxkA==",
+          "dev": true,
+          "requires": {
+            "@babel/parser": "^7.12.0",
+            "@babel/types": "^7.12.0",
+            "@vue/shared": "3.1.1",
+            "estree-walker": "^2.0.1",
+            "source-map": "^0.6.1"
+          }
+        },
+        "@vue/compiler-dom": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.1.tgz",
+          "integrity": "sha512-nobRIo0t5ibzg+q8nC31m+aJhbq8FbWUoKvk6h3Vs1EqTDJaj6lBTcVTq5or8AYht7FbSpdAJ81isbJ1rWNX7A==",
+          "dev": true,
+          "requires": {
+            "@vue/compiler-core": "3.1.1",
+            "@vue/shared": "3.1.1"
+          }
+        },
+        "@vue/shared": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.1.tgz",
+          "integrity": "sha512-g+4pzAw7PYSjARtLBoDq6DmcblX8i9KJHSCnyM5VDDFFifUaUT9iHbFpOF/KOizQ9f7QAqU2JH3Y6aXjzUMhVA==",
+          "dev": true
+        },
+        "consolidate": {
+          "version": "0.16.0",
+          "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz",
+          "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==",
+          "dev": true,
+          "requires": {
+            "bluebird": "^3.7.2"
+          }
+        },
+        "postcss": {
+          "version": "8.3.0",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz",
+          "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==",
+          "dev": true,
+          "requires": {
+            "colorette": "^1.2.2",
+            "nanoid": "^3.1.23",
+            "source-map-js": "^0.6.2"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "@vue/compiler-ssr": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.1.tgz",
+      "integrity": "sha512-7H6krZtVt3h/YzfNp7eYK41hMDz8ZskiBy+Wby+EDRINX6BD9JQ5C8zyy2xAa7T6Iz2VrQzsaJ/Bb52lTPSS5A==",
+      "dev": true,
+      "requires": {
+        "@vue/compiler-dom": "3.1.1",
+        "@vue/shared": "3.1.1"
+      },
+      "dependencies": {
+        "@vue/compiler-core": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.1.tgz",
+          "integrity": "sha512-Z1RO3T6AEtAUFf2EqqovFm3ohAeTvFzRtB0qUENW2nEerJfdlk13/LS1a0EgsqlzxmYfR/S/S/gW9PLbFZZxkA==",
+          "dev": true,
+          "requires": {
+            "@babel/parser": "^7.12.0",
+            "@babel/types": "^7.12.0",
+            "@vue/shared": "3.1.1",
+            "estree-walker": "^2.0.1",
+            "source-map": "^0.6.1"
+          }
+        },
+        "@vue/compiler-dom": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.1.tgz",
+          "integrity": "sha512-nobRIo0t5ibzg+q8nC31m+aJhbq8FbWUoKvk6h3Vs1EqTDJaj6lBTcVTq5or8AYht7FbSpdAJ81isbJ1rWNX7A==",
+          "dev": true,
+          "requires": {
+            "@vue/compiler-core": "3.1.1",
+            "@vue/shared": "3.1.1"
+          }
+        },
+        "@vue/shared": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.1.tgz",
+          "integrity": "sha512-g+4pzAw7PYSjARtLBoDq6DmcblX8i9KJHSCnyM5VDDFFifUaUT9iHbFpOF/KOizQ9f7QAqU2JH3Y6aXjzUMhVA==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "@vue/component-compiler-utils": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npm.taobao.org/@vue/component-compiler-utils/download/@vue/component-compiler-utils-3.2.0.tgz",
+      "integrity": "sha1-j4UYLO7Sjps8dTE95mn4MWbRHl0=",
+      "dev": true,
+      "requires": {
+        "consolidate": "^0.15.1",
+        "hash-sum": "^1.0.2",
+        "lru-cache": "^4.1.2",
+        "merge-source-map": "^1.1.0",
+        "postcss": "^7.0.14",
+        "postcss-selector-parser": "^6.0.2",
+        "prettier": "^1.18.2",
+        "source-map": "~0.6.1",
+        "vue-template-es2015-compiler": "^1.9.0"
+      },
+      "dependencies": {
+        "hash-sum": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz?cache=0&sync_timestamp=1586263945599&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhash-sum%2Fdownload%2Fhash-sum-1.0.2.tgz",
+          "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+          "dev": true
+        },
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.5.tgz?cache=0&sync_timestamp=1594427602316&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-4.1.5.tgz",
+          "integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "prettier": {
+          "version": "1.19.1",
+          "resolved": "https://registry.nlark.com/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1620594183343&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz",
+          "integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=",
+          "dev": true,
+          "optional": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "@vue/devtools-api": {
+      "version": "6.0.0-beta.11",
+      "resolved": "https://registry.nlark.com/@vue/devtools-api/download/@vue/devtools-api-6.0.0-beta.11.tgz?cache=0&sync_timestamp=1621615833585&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fdevtools-api%2Fdownload%2F%40vue%2Fdevtools-api-6.0.0-beta.11.tgz",
+      "integrity": "sha1-T7QWHuQbp18/UZjUv9gOT/t/JGI="
+    },
+    "@vue/eslint-config-prettier": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/@vue/eslint-config-prettier/download/@vue/eslint-config-prettier-6.0.0.tgz",
+      "integrity": "sha1-rVkSswj0rkaEWOAqKwXbC50kZwA=",
+      "dev": true,
+      "requires": {
+        "eslint-config-prettier": "^6.0.0"
+      }
+    },
+    "@vue/preload-webpack-plugin": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.2.tgz?cache=0&sync_timestamp=1613215046917&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fpreload-webpack-plugin%2Fdownload%2F%40vue%2Fpreload-webpack-plugin-1.1.2.tgz",
+      "integrity": "sha1-zrkktOyzucQ4ccekKaAvhCPmIas=",
+      "dev": true
+    },
+    "@vue/reactivity": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.0.tgz",
+      "integrity": "sha512-39L3UJe8+jYeCTM/QrDglDM05O11UrmyhazUOHOOj7+a9pPVu95HGInh5CkKQf98mx2gq6t3PPN8bCN5wK8Wwg==",
+      "requires": {
+        "@vue/shared": "3.2.0"
+      }
+    },
+    "@vue/runtime-core": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.0.tgz",
+      "integrity": "sha512-mZlkYTcw3mVwClwFTpql4hkDfOweHE/w+9r3Yb3UPwRs75bSJXMBRUikw1GVx01bZQ8VQPjBYowCElcWNSlKig==",
+      "requires": {
+        "@vue/reactivity": "3.2.0",
+        "@vue/shared": "3.2.0"
+      }
+    },
+    "@vue/runtime-dom": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.0.tgz",
+      "integrity": "sha512-NCHMfrUwpJelCTINpMRLFhzWKJkl07slabmTbECZFJnkdDfFkptGCWll42q58bbvwGmpAPDzNI3yYch72pcKwg==",
+      "requires": {
+        "@vue/runtime-core": "3.2.0",
+        "@vue/shared": "3.2.0",
+        "csstype": "^2.6.8"
+      }
+    },
+    "@vue/shared": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.0.tgz",
+      "integrity": "sha512-MgdilC3YHYSCFuNlxZBgugh8B9/h/h+nQ6lkeaxqFWW+FnV/JzCwW4Bh5bYIYvBleG8QZjFwxdmdqSAWLXzgEA=="
+    },
+    "@vue/test-utils": {
+      "version": "2.0.0-rc.6",
+      "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-2.0.0-rc.6.tgz",
+      "integrity": "sha512-0cnQBVH589PwgqWpyv1fgCAz+9Ram/MsvN3ZEAEVXi1aPuhUa22EudGc0WezQ9PKwR+L40NrBmt3JBXE2tSRRQ==",
+      "dev": true
+    },
+    "@vue/web-component-wrapper": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npm.taobao.org/@vue/web-component-wrapper/download/@vue/web-component-wrapper-1.3.0.tgz",
+      "integrity": "sha1-trQKdiVCnSvXwigd26YB7QXcfxo=",
+      "dev": true
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ast/download/@webassemblyjs/ast-1.9.0.tgz?cache=0&sync_timestamp=1610041386122&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fast%2Fdownload%2F%40webassemblyjs%2Fast-1.9.0.tgz",
+      "integrity": "sha1-vYUGBLQEJFmlpBzX0zjL7Wle2WQ=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.nlark.com/@webassemblyjs/floating-point-hex-parser/download/@webassemblyjs/floating-point-hex-parser-1.9.0.tgz",
+      "integrity": "sha1-PD07Jxvd/ITesA9xNEQ4MR1S/7Q=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-api-error/download/@webassemblyjs/helper-api-error-1.9.0.tgz?cache=0&sync_timestamp=1610041385672&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-api-error%2Fdownload%2F%40webassemblyjs%2Fhelper-api-error-1.9.0.tgz",
+      "integrity": "sha1-ID9nbjM7lsnaLuqzzO8zxFkotqI=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-buffer/download/@webassemblyjs/helper-buffer-1.9.0.tgz?cache=0&sync_timestamp=1610041385156&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-buffer%2Fdownload%2F%40webassemblyjs%2Fhelper-buffer-1.9.0.tgz",
+      "integrity": "sha1-oUQtJpxf6yP8vJ73WdrDVH8p3gA=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-code-frame/download/@webassemblyjs/helper-code-frame-1.9.0.tgz?cache=0&sync_timestamp=1610041387135&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-code-frame%2Fdownload%2F%40webassemblyjs%2Fhelper-code-frame-1.9.0.tgz",
+      "integrity": "sha1-ZH+Iks0gQ6gqwMjF51w28dkVnyc=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-fsm/download/@webassemblyjs/helper-fsm-1.9.0.tgz?cache=0&sync_timestamp=1610041385398&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-fsm%2Fdownload%2F%40webassemblyjs%2Fhelper-fsm-1.9.0.tgz",
+      "integrity": "sha1-wFJWtxJEIUZx9LCOwQitY7cO3bg=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-module-context/download/@webassemblyjs/helper-module-context-1.9.0.tgz",
+      "integrity": "sha1-JdiIS3aDmHGgimxvgGw5ee9xLwc=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-bytecode/download/@webassemblyjs/helper-wasm-bytecode-1.9.0.tgz?cache=0&sync_timestamp=1610041385277&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-wasm-bytecode%2Fdownload%2F%40webassemblyjs%2Fhelper-wasm-bytecode-1.9.0.tgz",
+      "integrity": "sha1-T+2L6sm4wU+MWLcNEk1UndH+V5A=",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/helper-wasm-section/download/@webassemblyjs/helper-wasm-section-1.9.0.tgz?cache=0&sync_timestamp=1610041387398&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fhelper-wasm-section%2Fdownload%2F%40webassemblyjs%2Fhelper-wasm-section-1.9.0.tgz",
+      "integrity": "sha1-WkE41aYpK6GLBMWuSXF+QWeWU0Y=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/ieee754/download/@webassemblyjs/ieee754-1.9.0.tgz?cache=0&sync_timestamp=1610041385781&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fieee754%2Fdownload%2F%40webassemblyjs%2Fieee754-1.9.0.tgz",
+      "integrity": "sha1-Fceg+6roP7JhQ7us9tbfFwKtOeQ=",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/leb128/download/@webassemblyjs/leb128-1.9.0.tgz?cache=0&sync_timestamp=1610041385570&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fleb128%2Fdownload%2F%40webassemblyjs%2Fleb128-1.9.0.tgz",
+      "integrity": "sha1-8Zygt2ptxVYjoJz/p2noOPoeHJU=",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/utf8/download/@webassemblyjs/utf8-1.9.0.tgz?cache=0&sync_timestamp=1610041385889&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Futf8%2Fdownload%2F%40webassemblyjs%2Futf8-1.9.0.tgz",
+      "integrity": "sha1-BNM7Y2945qaBMifoJAL3Y3tiKas=",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-edit/download/@webassemblyjs/wasm-edit-1.9.0.tgz?cache=0&sync_timestamp=1610041387713&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-edit%2Fdownload%2F%40webassemblyjs%2Fwasm-edit-1.9.0.tgz",
+      "integrity": "sha1-P+bXnT8PkiGDqoYALELdJWz+6c8=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/helper-wasm-section": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-opt": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-gen/download/@webassemblyjs/wasm-gen-1.9.0.tgz?cache=0&sync_timestamp=1610041387011&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-gen%2Fdownload%2F%40webassemblyjs%2Fwasm-gen-1.9.0.tgz",
+      "integrity": "sha1-ULxw7Gje2OJ2OwGhQYv0NJGnpJw=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-opt/download/@webassemblyjs/wasm-opt-1.9.0.tgz?cache=0&sync_timestamp=1610041387249&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-opt%2Fdownload%2F%40webassemblyjs%2Fwasm-opt-1.9.0.tgz",
+      "integrity": "sha1-IhEYHlsxMmRDzIES658LkChyGmE=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wasm-parser/download/@webassemblyjs/wasm-parser-1.9.0.tgz?cache=0&sync_timestamp=1610041386641&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwasm-parser%2Fdownload%2F%40webassemblyjs%2Fwasm-parser-1.9.0.tgz",
+      "integrity": "sha1-nUjkSCbfSmWYKUqmyHRp1kL/9l4=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npm.taobao.org/@webassemblyjs/wast-parser/download/@webassemblyjs/wast-parser-1.9.0.tgz?cache=0&sync_timestamp=1610041213532&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40webassemblyjs%2Fwast-parser%2Fdownload%2F%40webassemblyjs%2Fwast-parser-1.9.0.tgz",
+      "integrity": "sha1-MDERXXmsW9JhVWzsw/qQo+9FGRQ=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-code-frame": "1.9.0",
+        "@webassemblyjs/helper-fsm": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.nlark.com/@webassemblyjs/wast-printer/download/@webassemblyjs/wast-printer-1.9.0.tgz",
+      "integrity": "sha1-STXVTIX+9jewDOn1I3dFHQDUeJk=",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/@xtuc/ieee754/download/@xtuc/ieee754-1.2.0.tgz",
+      "integrity": "sha1-7vAUoxRa5Hehy8AM0eVSM23Ot5A=",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npm.taobao.org/@xtuc/long/download/@xtuc/long-4.2.2.tgz",
+      "integrity": "sha1-0pHGpOl5ibXGHZrPOWrk/hM6cY0=",
+      "dev": true
+    },
+    "abab": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
+      "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
+      "dev": true,
+      "requires": {
+        "mime-types": "~2.1.24",
+        "negotiator": "0.6.2"
+      }
+    },
+    "acorn": {
+      "version": "6.4.2",
+      "resolved": "https://registry.nlark.com/acorn/download/acorn-6.4.2.tgz?cache=0&sync_timestamp=1620134156200&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-6.4.2.tgz",
+      "integrity": "sha1-NYZv1xBSjpLeEM8GAWSY5H454eY=",
+      "dev": true
+    },
+    "acorn-globals": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+      "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+      "dev": true,
+      "requires": {
+        "acorn": "^6.0.1",
+        "acorn-walk": "^6.0.1"
+      },
+      "dependencies": {
+        "acorn-walk": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+          "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+          "dev": true
+        }
+      }
+    },
+    "acorn-jsx": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.3.1.tgz?cache=0&sync_timestamp=1599499102891&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn-jsx%2Fdownload%2Facorn-jsx-5.3.1.tgz",
+      "integrity": "sha1-/IZh4Rt6wVOcR9v+oucrOvNNJns=",
+      "dev": true
+    },
+    "acorn-walk": {
+      "version": "7.2.0",
+      "resolved": "https://registry.nlark.com/acorn-walk/download/acorn-walk-7.2.0.tgz?cache=0&sync_timestamp=1619259236377&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn-walk%2Fdownload%2Facorn-walk-7.2.0.tgz",
+      "integrity": "sha1-DeiJpgEgOQmw++B7iTjcIdLpZ7w=",
+      "dev": true
+    },
+    "address": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/address/download/address-1.1.2.tgz",
+      "integrity": "sha1-vxEWycdYxRt6kz0pa3LCIe2UKLY=",
+      "dev": true
+    },
+    "aggregate-error": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      }
+    },
+    "ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.nlark.com/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1621517642931&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
+      "integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz?cache=0&sync_timestamp=1616886640262&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-errors%2Fdownload%2Fajv-errors-1.0.1.tgz",
+      "integrity": "sha1-81mGrOuRr63sQQL72FAUlQzvpk0=",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1616882441894&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz",
+      "integrity": "sha1-MfKdpatuANHC0yms97WSlhTVAU0=",
+      "dev": true
+    },
+    "alphanum-sort": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/alphanum-sort/download/alphanum-sort-1.0.2.tgz",
+      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+      "dev": true
+    },
+    "ansi-colors": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npm.taobao.org/ansi-colors/download/ansi-colors-3.2.4.tgz",
+      "integrity": "sha1-46PaS/uubIapwoViXeEkojQCb78=",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npm.taobao.org/ansi-escapes/download/ansi-escapes-4.3.2.tgz",
+      "integrity": "sha1-ayKR0dt9mLZSHV8e+kLQ86n+tl4=",
+      "dev": true,
+      "requires": {
+        "type-fest": "^0.21.3"
+      },
+      "dependencies": {
+        "type-fest": {
+          "version": "0.21.3",
+          "resolved": "https://registry.nlark.com/type-fest/download/type-fest-0.21.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftype-fest%2Fdownload%2Ftype-fest-0.21.3.tgz",
+          "integrity": "sha1-0mCiSwGYQ24TP6JqUkptZfo7Ljc=",
+          "dev": true
+        }
+      }
+    },
+    "ansi-html": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npm.taobao.org/ansi-html/download/ansi-html-0.0.7.tgz",
+      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz",
+      "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1618995625950&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz",
+      "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz",
+      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npm.taobao.org/anymatch/download/anymatch-3.1.2.tgz?cache=0&sync_timestamp=1617747806715&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fanymatch%2Fdownload%2Fanymatch-3.1.2.tgz",
+      "integrity": "sha1-wFV8CWrzLxBhmPT04qODU343hxY=",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz",
+      "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=",
+      "dev": true
+    },
+    "arch": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/arch/download/arch-2.2.0.tgz?cache=0&sync_timestamp=1603836324975&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farch%2Fdownload%2Farch-2.2.0.tgz",
+      "integrity": "sha1-G8R4GPMFdk8jqzMGsL/AhsWinRE=",
+      "dev": true
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npm.taobao.org/argparse/download/argparse-1.0.10.tgz",
+      "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/arr-diff/download/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/arr-flatten/download/arr-flatten-1.1.0.tgz",
+      "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/arr-union/download/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+      "dev": true
+    },
+    "array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.nlark.com/array-union/download/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "^1.0.1"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.nlark.com/array-uniq/download/array-uniq-1.0.3.tgz?cache=0&sync_timestamp=1620042121153&other_urls=https%3A%2F%2Fregistry.nlark.com%2Farray-uniq%2Fdownload%2Farray-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
+      "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npm.taobao.org/asn1.js/download/asn1.js-5.4.1.tgz",
+      "integrity": "sha1-EamAuE67kXgc41sP3C7ilON4Pwc=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "safer-buffer": "^2.1.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.12.0",
+          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.12.0.tgz",
+          "integrity": "sha1-d1s/J477uXGO7HNh9IP7Nvu/6og=",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npm.taobao.org/assert/download/assert-1.5.0.tgz?cache=0&sync_timestamp=1586265311434&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fassert%2Fdownload%2Fassert-1.5.0.tgz",
+      "integrity": "sha1-VcEJqvbgrv2z3EtxJAxwv1dLGOs=",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npm.taobao.org/util/download/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz",
+      "integrity": "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k=",
+      "dev": true
+    },
+    "async": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz",
+      "integrity": "sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8=",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.14"
+      }
+    },
+    "async-each": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/async-each/download/async-each-1.0.3.tgz",
+      "integrity": "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8=",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "async-validator": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz",
+      "integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ=="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npm.taobao.org/atob/download/atob-2.1.2.tgz",
+      "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "9.8.6",
+      "resolved": "https://registry.nlark.com/autoprefixer/download/autoprefixer-9.8.6.tgz",
+      "integrity": "sha1-O3NZTKG/kmYyDFrPFYjXTep0IQ8=",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.12.0",
+        "caniuse-lite": "^1.0.30001109",
+        "colorette": "^1.2.1",
+        "normalize-range": "^0.1.2",
+        "num2fraction": "^1.2.2",
+        "postcss": "^7.0.32",
+        "postcss-value-parser": "^4.1.0"
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.nlark.com/aws4/download/aws4-1.11.0.tgz",
+      "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+      "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+      "requires": {
+        "follow-redirects": "^1.10.0"
+      }
+    },
+    "babel-eslint": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz",
+      "integrity": "sha1-aWjlaKkQt4+zd5zdi2rC9HmUMjI=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.7.0",
+        "@babel/traverse": "^7.7.0",
+        "@babel/types": "^7.7.0",
+        "eslint-visitor-keys": "^1.0.0",
+        "resolve": "^1.12.0"
+      }
+    },
+    "babel-loader": {
+      "version": "8.2.2",
+      "resolved": "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.2.2.tgz?cache=0&sync_timestamp=1606424705083&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.2.2.tgz",
+      "integrity": "sha1-k2POhMEMmkDmx1N0jhRBtgyKC4E=",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^3.3.1",
+        "loader-utils": "^1.4.0",
+        "make-dir": "^3.1.0",
+        "schema-utils": "^2.6.5"
+      }
+    },
+    "babel-plugin-dynamic-import-node": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npm.taobao.org/babel-plugin-dynamic-import-node/download/babel-plugin-dynamic-import-node-2.3.3.tgz",
+      "integrity": "sha1-hP2hnJduxcbe/vV/lCez3vZuF6M=",
+      "dev": true,
+      "requires": {
+        "object.assign": "^4.1.0"
+      }
+    },
+    "babel-plugin-import": {
+      "version": "1.13.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-import/-/babel-plugin-import-1.13.3.tgz",
+      "integrity": "sha512-1qCWdljJOrDRH/ybaCZuDgySii4yYrtQ8OJQwrcDqdt0y67N30ng3X3nABg6j7gR7qUJgcMa9OMhc4AGViDwWw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "babel-plugin-polyfill-corejs2": {
+      "version": "0.2.2",
+      "resolved": "https://registry.nlark.com/babel-plugin-polyfill-corejs2/download/babel-plugin-polyfill-corejs2-0.2.2.tgz",
+      "integrity": "sha1-6RJHheb9lPlLYYp5VOVpMFO/Uyc=",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.13.11",
+        "@babel/helper-define-polyfill-provider": "^0.2.2",
+        "semver": "^6.1.1"
+      }
+    },
+    "babel-plugin-polyfill-corejs3": {
+      "version": "0.2.2",
+      "resolved": "https://registry.nlark.com/babel-plugin-polyfill-corejs3/download/babel-plugin-polyfill-corejs3-0.2.2.tgz",
+      "integrity": "sha1-dCShaC7kS67IFzJ3ELGwlOX49/U=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-define-polyfill-provider": "^0.2.2",
+        "core-js-compat": "^3.9.1"
+      }
+    },
+    "babel-plugin-polyfill-regenerator": {
+      "version": "0.2.2",
+      "resolved": "https://registry.nlark.com/babel-plugin-polyfill-regenerator/download/babel-plugin-polyfill-regenerator-0.2.2.tgz",
+      "integrity": "sha1-sxDI1kKsraNIwfo7Pmzg6FG+4Hc=",
+      "dev": true,
+      "requires": {
+        "@babel/helper-define-polyfill-provider": "^0.2.2"
+      }
+    },
+    "bail": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
+      "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbalanced-match%2Fdownload%2Fbalanced-match-1.0.2.tgz",
+      "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npm.taobao.org/base/download/base-0.11.2.tgz",
+      "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz",
+          "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npm.taobao.org/base64-js/download/base64-js-1.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbase64-js%2Fdownload%2Fbase64-js-1.5.1.tgz",
+      "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=",
+      "dev": true
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npm.taobao.org/batch/download/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/bcrypt-pbkdf/download/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "bfj": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npm.taobao.org/bfj/download/bfj-6.1.2.tgz",
+      "integrity": "sha1-MlyGGoIryzWKQceKM7jm4ght3n8=",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "check-types": "^8.0.3",
+        "hoopy": "^0.1.4",
+        "tryer": "^1.0.1"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.nlark.com/big.js/download/big.js-5.2.2.tgz",
+      "integrity": "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg=",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/binary-extensions/download/binary-extensions-2.2.0.tgz?cache=0&sync_timestamp=1610299285874&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbinary-extensions%2Fdownload%2Fbinary-extensions-2.2.0.tgz",
+      "integrity": "sha1-dfUC7q+f/eQvyYgpZFvk6na9ni0=",
+      "dev": true
+    },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz?cache=0&sync_timestamp=1586263933818&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbluebird%2Fdownload%2Fbluebird-3.7.2.tgz",
+      "integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-5.2.0.tgz",
+      "integrity": "sha1-NYhgZ0OWxpl3canQUfzBtX1K4AI=",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz",
+      "integrity": "sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433872491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz",
+          "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=",
+          "dev": true
+        }
+      }
+    },
+    "bonjour": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npm.taobao.org/bonjour/download/bonjour-3.5.0.tgz",
+      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+      "dev": true,
+      "requires": {
+        "array-flatten": "^2.1.0",
+        "deep-equal": "^1.0.1",
+        "dns-equal": "^1.0.0",
+        "dns-txt": "^2.0.2",
+        "multicast-dns": "^6.0.1",
+        "multicast-dns-service-types": "^1.1.0"
+      },
+      "dependencies": {
+        "array-flatten": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npm.taobao.org/array-flatten/download/array-flatten-2.1.2.tgz",
+          "integrity": "sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk=",
+          "dev": true
+        }
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/boolbase/download/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npm.taobao.org/brace-expansion/download/brace-expansion-1.1.11.tgz",
+      "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz",
+      "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/brorand/download/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-process-hrtime": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+      "dev": true
+    },
+    "browser-stdout": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+      "dev": true
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/browserify-aes/download/browserify-aes-1.2.0.tgz",
+      "integrity": "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/browserify-cipher/download/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/browserify-des/download/browserify-des-1.0.2.tgz",
+      "integrity": "sha1-OvTx9Zg5QDVy8cZiBDdfen9wPpw=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/browserify-rsa/download/browserify-rsa-4.1.0.tgz",
+      "integrity": "sha1-sv0Gtbda4pf3zi3GUfkY9b4VjI0=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.0.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npm.taobao.org/browserify-sign/download/browserify-sign-4.2.1.tgz",
+      "integrity": "sha1-6vSt1G3VS+O7OzbAzxWrvrp5VsM=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.3",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
+          "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.1.tgz",
+          "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=",
+          "dev": true
+        }
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npm.taobao.org/browserify-zlib/download/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.16.6",
+      "resolved": "https://registry.nlark.com/browserslist/download/browserslist-4.16.6.tgz?cache=0&sync_timestamp=1619789101558&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.16.6.tgz",
+      "integrity": "sha1-15ASd6WojlVO0wWxg+ybDAj2b6I=",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30001219",
+        "colorette": "^1.2.2",
+        "electron-to-chromium": "^1.3.723",
+        "escalade": "^3.1.1",
+        "node-releases": "^1.1.71"
+      }
+    },
+    "buffer": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&sync_timestamp=1606098066706&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz",
+      "integrity": "sha1-Iw6tNEACmIZEhBqwJEr4xEu+Pvg=",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/buffer-from/download/buffer-from-1.1.1.tgz",
+      "integrity": "sha1-MnE7wCj3XAL9txDXx7zsHyxgcO8=",
+      "dev": true
+    },
+    "buffer-indexof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/buffer-indexof/download/buffer-indexof-1.1.1.tgz",
+      "integrity": "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow=",
+      "dev": true
+    },
+    "buffer-json": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/buffer-json/download/buffer-json-2.0.0.tgz",
+      "integrity": "sha1-9z4TseQvGW/i/WfQAcfXEH7dfCM=",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/buffer-xor/download/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.1.0.tgz",
+      "integrity": "sha1-9s95M6Ng4FiPqf3oVlHNx/gF0fY=",
+      "dev": true
+    },
+    "cacache": {
+      "version": "12.0.4",
+      "resolved": "https://registry.nlark.com/cacache/download/cacache-12.0.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcacache%2Fdownload%2Fcacache-12.0.4.tgz",
+      "integrity": "sha1-ZovL0QWutfHZL+JVcOyVJcj6pAw=",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.1.15",
+        "infer-owner": "^1.0.3",
+        "lru-cache": "^5.1.1",
+        "mississippi": "^3.0.0",
+        "mkdirp": "^0.5.1",
+        "move-concurrently": "^1.0.1",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^2.6.3",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
+        "y18n": "^4.0.0"
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/cache-base/download/cache-base-1.0.1.tgz",
+      "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=",
+      "dev": true,
+      "requires": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      }
+    },
+    "cache-loader": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/cache-loader/download/cache-loader-4.1.0.tgz",
+      "integrity": "sha1-mUjK41OuwKH8ser9ojAIFuyFOH4=",
+      "dev": true,
+      "requires": {
+        "buffer-json": "^2.0.0",
+        "find-cache-dir": "^3.0.0",
+        "loader-utils": "^1.2.3",
+        "mkdirp": "^0.5.1",
+        "neo-async": "^2.6.1",
+        "schema-utils": "^2.0.0"
+      }
+    },
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/call-bind/download/call-bind-1.0.2.tgz?cache=0&sync_timestamp=1610403232833&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcall-bind%2Fdownload%2Fcall-bind-1.0.2.tgz",
+      "integrity": "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "call-me-maybe": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/call-me-maybe/download/call-me-maybe-1.0.1.tgz",
+      "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+      "dev": true
+    },
+    "caller-callsite": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/caller-callsite/download/caller-callsite-2.0.0.tgz",
+      "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+      "dev": true,
+      "requires": {
+        "callsites": "^2.0.0"
+      }
+    },
+    "caller-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/caller-path/download/caller-path-2.0.0.tgz?cache=0&sync_timestamp=1618738174589&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaller-path%2Fdownload%2Fcaller-path-2.0.0.tgz",
+      "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+      "dev": true,
+      "requires": {
+        "caller-callsite": "^2.0.0"
+      }
+    },
+    "callsites": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/callsites/download/callsites-2.0.0.tgz",
+      "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+      "dev": true
+    },
+    "camel-case": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/camel-case/download/camel-case-3.0.0.tgz?cache=0&sync_timestamp=1606869170809&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcamel-case%2Fdownload%2Fcamel-case-3.0.0.tgz",
+      "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
+      "dev": true,
+      "requires": {
+        "no-case": "^2.2.0",
+        "upper-case": "^1.1.1"
+      }
+    },
+    "camelcase": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-6.2.0.tgz",
+      "integrity": "sha1-kkr4gcnVJaydh/QNlk5c6pgqGAk=",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
+      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "map-obj": "^4.0.0",
+        "quick-lru": "^4.0.1"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        }
+      }
+    },
+    "caniuse-api": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/caniuse-api/download/caniuse-api-3.0.0.tgz",
+      "integrity": "sha1-Xk2Q4idJYdRikZl99Znj7QCO5MA=",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-lite": "^1.0.0",
+        "lodash.memoize": "^4.1.2",
+        "lodash.uniq": "^4.5.0"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30001230",
+      "resolved": "https://registry.nlark.com/caniuse-lite/download/caniuse-lite-1.0.30001230.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001230.tgz",
+      "integrity": "sha1-gTXFdFmFSyJAtXpKZ4YES9xan3E=",
+      "dev": true
+    },
+    "case-sensitive-paths-webpack-plugin": {
+      "version": "2.4.0",
+      "resolved": "https://registry.nlark.com/case-sensitive-paths-webpack-plugin/download/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
+      "integrity": "sha1-22QGbGQi7tLgjMFLmGykN5bbxtQ=",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "chai": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
+      "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
+      "dev": true,
+      "requires": {
+        "assertion-error": "^1.1.0",
+        "check-error": "^1.0.2",
+        "deep-eql": "^3.0.1",
+        "get-func-name": "^2.0.0",
+        "pathval": "^1.1.1",
+        "type-detect": "^4.0.5"
+      }
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.nlark.com/chalk/download/chalk-2.4.2.tgz?cache=0&sync_timestamp=1618995297666&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-2.4.2.tgz",
+      "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      }
+    },
+    "character-entities": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+      "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+      "dev": true
+    },
+    "character-entities-legacy": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+      "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+      "dev": true
+    },
+    "character-reference-invalid": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+      "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+      "dev": true
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz?cache=0&sync_timestamp=1601032519509&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchardet%2Fdownload%2Fchardet-0.7.0.tgz",
+      "integrity": "sha1-kAlISfCTfy7twkJdDSip5fDLrZ4=",
+      "dev": true
+    },
+    "check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true
+    },
+    "check-types": {
+      "version": "8.0.3",
+      "resolved": "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz",
+      "integrity": "sha1-M1bMoZyIlUTy16le1JzlCKDs9VI=",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-3.5.1.tgz?cache=0&sync_timestamp=1610719499558&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.5.1.tgz",
+      "integrity": "sha1-7pznu+vSt59J8wR5nVRo4x4U5oo=",
+      "dev": true,
+      "requires": {
+        "anymatch": "~3.1.1",
+        "braces": "~3.0.2",
+        "fsevents": "~2.3.1",
+        "glob-parent": "~5.1.0",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.5.0"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
+          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
+          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
+          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+          "dev": true
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
+          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npm.taobao.org/chownr/download/chownr-1.1.4.tgz",
+      "integrity": "sha1-b8nXtC0ypYNZYzdmbn0ICE2izGs=",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/chrome-trace-event/download/chrome-trace-event-1.0.3.tgz?cache=0&sync_timestamp=1617905826919&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchrome-trace-event%2Fdownload%2Fchrome-trace-event-1.0.3.tgz",
+      "integrity": "sha1-EBXs7UdB4V0GZkqVfbv1DQQeJqw=",
+      "dev": true
+    },
+    "ci-info": {
+      "version": "1.6.0",
+      "resolved": "https://registry.nlark.com/ci-info/download/ci-info-1.6.0.tgz?cache=0&sync_timestamp=1622040049099&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fci-info%2Fdownload%2Fci-info-1.6.0.tgz",
+      "integrity": "sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=",
+      "dev": true
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/cipher-base/download/cipher-base-1.0.4.tgz",
+      "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npm.taobao.org/class-utils/download/class-utils-0.3.6.tgz",
+      "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "clean-css": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npm.taobao.org/clean-css/download/clean-css-4.2.3.tgz",
+      "integrity": "sha1-UHtd59l7SO5T2ErbAWD/YhY4D3g=",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/cli-cursor/download/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^2.0.0"
+      }
+    },
+    "cli-highlight": {
+      "version": "2.1.11",
+      "resolved": "https://registry.npm.taobao.org/cli-highlight/download/cli-highlight-2.1.11.tgz?cache=0&sync_timestamp=1616955426054&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcli-highlight%2Fdownload%2Fcli-highlight-2.1.11.tgz",
+      "integrity": "sha1-SXNvpFLwqvT65YDjCssmgo0twb8=",
+      "dev": true,
+      "requires": {
+        "chalk": "^4.0.0",
+        "highlight.js": "^10.7.1",
+        "mz": "^2.4.0",
+        "parse5": "^5.1.1",
+        "parse5-htmlparser2-tree-adapter": "^6.0.0",
+        "yargs": "^16.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995625950&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.1",
+          "resolved": "https://registry.nlark.com/chalk/download/chalk-4.1.1.tgz?cache=0&sync_timestamp=1618995297666&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.1.tgz",
+          "integrity": "sha1-yAs/qyi/Y3HmhjMl7uZ+YYt35q0=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.nlark.com/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1618847145907&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "cli-spinners": {
+      "version": "2.6.0",
+      "resolved": "https://registry.nlark.com/cli-spinners/download/cli-spinners-2.6.0.tgz",
+      "integrity": "sha1-NsfcmPtqmna9YjjsP3fiQlYn6Tk=",
+      "dev": true
+    },
+    "cli-truncate": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+      "dev": true,
+      "requires": {
+        "slice-ansi": "^3.0.0",
+        "string-width": "^4.2.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "astral-regex": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+          "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+          "dev": true
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "slice-ansi": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+          "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "astral-regex": "^2.0.0",
+            "is-fullwidth-code-point": "^3.0.0"
+          }
+        }
+      }
+    },
+    "cli-width": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/cli-width/download/cli-width-3.0.0.tgz",
+      "integrity": "sha1-ovSEN6LKqaIkNueUvwceyeYc7fY=",
+      "dev": true
+    },
+    "clipboardy": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npm.taobao.org/clipboardy/download/clipboardy-2.3.0.tgz",
+      "integrity": "sha1-PCkDZQxo5GqRs4iYW8J3QofbopA=",
+      "dev": true,
+      "requires": {
+        "arch": "^2.1.1",
+        "execa": "^1.0.0",
+        "is-wsl": "^2.1.1"
+      },
+      "dependencies": {
+        "is-wsl": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npm.taobao.org/is-wsl/download/is-wsl-2.2.0.tgz",
+          "integrity": "sha1-dKTHbnfKn9P5MvKQwX6jJs0VcnE=",
+          "dev": true,
+          "requires": {
+            "is-docker": "^2.0.0"
+          }
+        }
+      }
+    },
+    "cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/cliui/download/cliui-6.0.0.tgz",
+      "integrity": "sha1-UR1wLAxOQcoVbX0OlgIfI+EyJbE=",
+      "dev": true,
+      "requires": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995625950&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-6.2.0.tgz?cache=0&sync_timestamp=1618558913931&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwrap-ansi%2Fdownload%2Fwrap-ansi-6.2.0.tgz",
+          "integrity": "sha1-6Tk7oHEC5skaOyIUePAlfNKFblM=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0"
+          }
+        }
+      }
+    },
+    "clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/clone/download/clone-1.0.4.tgz",
+      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+      "dev": true
+    },
+    "clone-deep": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/clone-deep/download/clone-deep-4.0.1.tgz",
+      "integrity": "sha1-wZ/Zvbv4WUK0/ZechNz31fB8I4c=",
+      "dev": true,
+      "requires": {
+        "is-plain-object": "^2.0.4",
+        "kind-of": "^6.0.2",
+        "shallow-clone": "^3.0.0"
+      }
+    },
+    "clone-regexp": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
+      "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
+      "dev": true,
+      "requires": {
+        "is-regexp": "^2.0.0"
+      }
+    },
+    "coa": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/coa/download/coa-2.0.2.tgz",
+      "integrity": "sha1-Q/bCEVG07yv1cYfbDXPeIp4+fsM=",
+      "dev": true,
+      "requires": {
+        "@types/q": "^1.5.1",
+        "chalk": "^2.4.1",
+        "q": "^1.1.2"
+      }
+    },
+    "codemirror": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.0.tgz",
+      "integrity": "sha512-Xnl3304iCc8nyVZuRkzDVVwc794uc9QNX0UcPGeNic1fbzkSrO4l4GVXho9tRNKBgPYZXgocUqXyfIv3BILhCQ=="
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/collection-visit/download/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npm.taobao.org/color/download/color-3.1.3.tgz",
+      "integrity": "sha1-ymf7TnuX1hHc3jns7tQiBn2RWW4=",
+      "dev": true,
+      "requires": {
+        "color-convert": "^1.9.1",
+        "color-string": "^1.5.4"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-1.9.3.tgz",
+      "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "color-string": {
+      "version": "1.5.5",
+      "resolved": "https://registry.nlark.com/color-string/download/color-string-1.5.5.tgz",
+      "integrity": "sha1-ZUdKjw50OWJfPSemoZ2J/EUiMBQ=",
+      "dev": true,
+      "requires": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
+    "colorette": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npm.taobao.org/colorette/download/colorette-1.2.2.tgz?cache=0&sync_timestamp=1614259647923&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcolorette%2Fdownload%2Fcolorette-1.2.2.tgz",
+      "integrity": "sha1-y8x51emcrqLb8Q6zom/Ys+as+pQ=",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz",
+      "integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.nlark.com/commander/download/commander-2.20.3.tgz?cache=0&sync_timestamp=1621726578455&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz",
+      "integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz",
+      "integrity": "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=",
+      "dev": true
+    },
+    "compressible": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npm.taobao.org/compressible/download/compressible-2.0.18.tgz",
+      "integrity": "sha1-r1PMprBw1MPAdQ+9dyhqbXzEb7o=",
+      "dev": true,
+      "requires": {
+        "mime-db": ">= 1.43.0 < 2"
+      }
+    },
+    "compression": {
+      "version": "1.7.4",
+      "resolved": "https://registry.npm.taobao.org/compression/download/compression-1.7.4.tgz",
+      "integrity": "sha1-lVI+/xcMpXwpoMpB5v4TH0Hlu48=",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.5",
+        "bytes": "3.0.0",
+        "compressible": "~2.0.16",
+        "debug": "2.6.9",
+        "on-headers": "~1.0.2",
+        "safe-buffer": "5.1.2",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz",
+          "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+          "dev": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433872491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npm.taobao.org/concat-stream/download/concat-stream-1.6.2.tgz",
+      "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "connect-history-api-fallback": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npm.taobao.org/connect-history-api-fallback/download/connect-history-api-fallback-1.6.0.tgz",
+      "integrity": "sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w=",
+      "dev": true
+    },
+    "console-browserify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/console-browserify/download/console-browserify-1.2.0.tgz",
+      "integrity": "sha1-ZwY871fOts9Jk6KrOlWECujEkzY=",
+      "dev": true
+    },
+    "consolidate": {
+      "version": "0.15.1",
+      "resolved": "https://registry.nlark.com/consolidate/download/consolidate-0.15.1.tgz",
+      "integrity": "sha1-IasEMjXHGgfUXZqtmFk7DbpWurc=",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.1.1"
+      }
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/constants-browserify/download/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz",
+      "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz",
+      "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npm.taobao.org/convert-source-map/download/convert-source-map-1.7.0.tgz",
+      "integrity": "sha1-F6LLiC1/d9NJBYXizmxSRCSjpEI=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz?cache=0&sync_timestamp=1587525998658&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookie%2Fdownload%2Fcookie-0.4.0.tgz",
+      "integrity": "sha1-vrQ35wIrO21JAZ0IhmUwPr6cFLo=",
+      "dev": true
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npm.taobao.org/cookie-signature/download/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha1-kilzmMrjSTf8r9bsgTnBgFHwteA=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "fs-write-stream-atomic": "^1.0.8",
+        "iferr": "^0.1.5",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.0"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npm.taobao.org/copy-descriptor/download/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "copy-webpack-plugin": {
+      "version": "5.1.2",
+      "resolved": "https://registry.nlark.com/copy-webpack-plugin/download/copy-webpack-plugin-5.1.2.tgz?cache=0&sync_timestamp=1621607433850&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcopy-webpack-plugin%2Fdownload%2Fcopy-webpack-plugin-5.1.2.tgz",
+      "integrity": "sha1-ioieHcr6bJHGzUvhrRWPHTgjuuI=",
+      "dev": true,
+      "requires": {
+        "cacache": "^12.0.3",
+        "find-cache-dir": "^2.1.0",
+        "glob-parent": "^3.1.0",
+        "globby": "^7.1.1",
+        "is-glob": "^4.0.1",
+        "loader-utils": "^1.2.3",
+        "minimatch": "^3.0.4",
+        "normalize-path": "^3.0.0",
+        "p-limit": "^2.2.1",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^4.0.0",
+        "webpack-log": "^2.0.0"
+      },
+      "dependencies": {
+        "find-cache-dir": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-2.1.0.tgz",
+          "integrity": "sha1-jQ+UzRP+Q8bHwmGg2GEVypGMBfc=",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^2.0.0",
+            "pkg-dir": "^3.0.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz",
+          "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.nlark.com/glob-parent/download/glob-parent-3.1.0.tgz?cache=0&sync_timestamp=1620073321855&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fglob-parent%2Fdownload%2Fglob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        },
+        "globby": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npm.taobao.org/globby/download/globby-7.1.1.tgz",
+          "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "dir-glob": "^2.0.0",
+            "glob": "^7.1.2",
+            "ignore": "^3.3.5",
+            "pify": "^3.0.0",
+            "slash": "^1.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
+              "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+              "dev": true
+            }
+          }
+        },
+        "ignore": {
+          "version": "3.3.10",
+          "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz",
+          "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz",
+          "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "make-dir": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz",
+          "integrity": "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU=",
+          "dev": true,
+          "requires": {
+            "pify": "^4.0.1",
+            "semver": "^5.6.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz",
+          "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-3.0.0.tgz?cache=0&sync_timestamp=1602858985920&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-3.0.0.tgz",
+          "integrity": "sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM=",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-1.0.0.tgz?cache=0&sync_timestamp=1601922425223&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-1.0.0.tgz",
+          "integrity": "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A=",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1616463641178&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        },
+        "slash": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/slash/download/slash-1.0.0.tgz",
+          "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+          "dev": true
+        }
+      }
+    },
+    "core-js": {
+      "version": "3.13.0",
+      "resolved": "https://registry.nlark.com/core-js/download/core-js-3.13.0.tgz",
+      "integrity": "sha1-WMpDa/AdaQOu49NkCJho0Nif5Y0="
+    },
+    "core-js-compat": {
+      "version": "3.13.0",
+      "resolved": "https://registry.nlark.com/core-js-compat/download/core-js-compat-3.13.0.tgz",
+      "integrity": "sha1-qI9fqB2OmxXX+Yq8REek38oqNY8=",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.16.6",
+        "semver": "7.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-7.0.0.tgz?cache=0&sync_timestamp=1616463641178&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.0.0.tgz",
+          "integrity": "sha1-XzyjV2HkfgWyBsba/yz4FPAxa44=",
+          "dev": true
+        }
+      }
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cosmiconfig": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-5.2.1.tgz?cache=0&sync_timestamp=1596312863119&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-5.2.1.tgz",
+      "integrity": "sha1-BA9yaAnFked6F8CjYmykW08Wixo=",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^2.0.0",
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.13.1",
+        "parse-json": "^4.0.0"
+      },
+      "dependencies": {
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/parse-json/download/parse-json-4.0.0.tgz?cache=0&sync_timestamp=1610966642419&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        }
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.4.tgz?cache=0&sync_timestamp=1596557456448&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcreate-ecdh%2Fdownload%2Fcreate-ecdh-4.0.4.tgz",
+      "integrity": "sha1-1uf0v/pmc2CFoHYv06YyaE2rzE4=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.12.0",
+          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.12.0.tgz",
+          "integrity": "sha1-d1s/J477uXGO7HNh9IP7Nvu/6og=",
+          "dev": true
+        }
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/create-hash/download/create-hash-1.2.0.tgz",
+      "integrity": "sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npm.taobao.org/create-hmac/download/create-hmac-1.1.7.tgz",
+      "integrity": "sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-6.0.5.tgz?cache=0&sync_timestamp=1590421014780&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcross-spawn%2Fdownload%2Fcross-spawn-6.0.5.tgz",
+      "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=",
+      "dev": true,
+      "requires": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1616463641178&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz",
+          "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=",
+          "dev": true
+        }
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha1-OWz58xN/A+S45TLFj2mCVOAPgOw=",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "css-color-names": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npm.taobao.org/css-color-names/download/css-color-names-0.0.4.tgz",
+      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+      "dev": true
+    },
+    "css-declaration-sorter": {
+      "version": "4.0.1",
+      "resolved": "https://registry.nlark.com/css-declaration-sorter/download/css-declaration-sorter-4.0.1.tgz?cache=0&sync_timestamp=1620754845858&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcss-declaration-sorter%2Fdownload%2Fcss-declaration-sorter-4.0.1.tgz",
+      "integrity": "sha1-wZiUD2OnbX42wecQGLABchBUyyI=",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.1",
+        "timsort": "^0.3.0"
+      }
+    },
+    "css-loader": {
+      "version": "3.6.0",
+      "resolved": "https://registry.nlark.com/css-loader/download/css-loader-3.6.0.tgz?cache=0&sync_timestamp=1621865043272&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcss-loader%2Fdownload%2Fcss-loader-3.6.0.tgz",
+      "integrity": "sha1-Lkssfm4tJ/jI8o9hv/zS5ske9kU=",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "cssesc": "^3.0.0",
+        "icss-utils": "^4.1.1",
+        "loader-utils": "^1.2.3",
+        "normalize-path": "^3.0.0",
+        "postcss": "^7.0.32",
+        "postcss-modules-extract-imports": "^2.0.0",
+        "postcss-modules-local-by-default": "^3.0.2",
+        "postcss-modules-scope": "^2.2.0",
+        "postcss-modules-values": "^3.0.0",
+        "postcss-value-parser": "^4.1.0",
+        "schema-utils": "^2.7.0",
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz",
+          "integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
+          "dev": true
+        }
+      }
+    },
+    "css-select": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/css-select/download/css-select-2.1.0.tgz",
+      "integrity": "sha1-ajRlM1ZjWTSoG6ymjQJVQyEF2+8=",
+      "dev": true,
+      "requires": {
+        "boolbase": "^1.0.0",
+        "css-what": "^3.2.1",
+        "domutils": "^1.7.0",
+        "nth-check": "^1.0.2"
+      }
+    },
+    "css-select-base-adapter": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npm.taobao.org/css-select-base-adapter/download/css-select-base-adapter-0.1.1.tgz",
+      "integrity": "sha1-Oy/0lyzDYquIVhUHqVQIoUMhNdc=",
+      "dev": true
+    },
+    "css-tree": {
+      "version": "1.0.0-alpha.37",
+      "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.0-alpha.37.tgz?cache=0&sync_timestamp=1617191603409&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.0.0-alpha.37.tgz",
+      "integrity": "sha1-mL69YsTB2flg7DQM+fdSLjBwmiI=",
+      "dev": true,
+      "requires": {
+        "mdn-data": "2.0.4",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "css-what": {
+      "version": "3.4.2",
+      "resolved": "https://registry.npm.taobao.org/css-what/download/css-what-3.4.2.tgz",
+      "integrity": "sha1-6nAm/LAXd+295SEk4h8yfnrpUOQ=",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/cssesc/download/cssesc-3.0.0.tgz",
+      "integrity": "sha1-N3QZGZA7hoVl4cCep0dEXNGJg+4=",
+      "dev": true
+    },
+    "cssnano": {
+      "version": "4.1.11",
+      "resolved": "https://registry.nlark.com/cssnano/download/cssnano-4.1.11.tgz?cache=0&sync_timestamp=1621619432261&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcssnano%2Fdownload%2Fcssnano-4.1.11.tgz",
+      "integrity": "sha1-x7X1uB2iacsf2YLLlgwSAJEMmpk=",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^5.0.0",
+        "cssnano-preset-default": "^4.0.8",
+        "is-resolvable": "^1.0.0",
+        "postcss": "^7.0.0"
+      }
+    },
+    "cssnano-preset-default": {
+      "version": "4.0.8",
+      "resolved": "https://registry.nlark.com/cssnano-preset-default/download/cssnano-preset-default-4.0.8.tgz?cache=0&sync_timestamp=1621619431842&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcssnano-preset-default%2Fdownload%2Fcssnano-preset-default-4.0.8.tgz",
+      "integrity": "sha1-kgYisfwelaNOiDggPxOXpQTy0/8=",
+      "dev": true,
+      "requires": {
+        "css-declaration-sorter": "^4.0.1",
+        "cssnano-util-raw-cache": "^4.0.1",
+        "postcss": "^7.0.0",
+        "postcss-calc": "^7.0.1",
+        "postcss-colormin": "^4.0.3",
+        "postcss-convert-values": "^4.0.1",
+        "postcss-discard-comments": "^4.0.2",
+        "postcss-discard-duplicates": "^4.0.2",
+        "postcss-discard-empty": "^4.0.1",
+        "postcss-discard-overridden": "^4.0.1",
+        "postcss-merge-longhand": "^4.0.11",
+        "postcss-merge-rules": "^4.0.3",
+        "postcss-minify-font-values": "^4.0.2",
+        "postcss-minify-gradients": "^4.0.2",
+        "postcss-minify-params": "^4.0.2",
+        "postcss-minify-selectors": "^4.0.2",
+        "postcss-normalize-charset": "^4.0.1",
+        "postcss-normalize-display-values": "^4.0.2",
+        "postcss-normalize-positions": "^4.0.2",
+        "postcss-normalize-repeat-style": "^4.0.2",
+        "postcss-normalize-string": "^4.0.2",
+        "postcss-normalize-timing-functions": "^4.0.2",
+        "postcss-normalize-unicode": "^4.0.1",
+        "postcss-normalize-url": "^4.0.1",
+        "postcss-normalize-whitespace": "^4.0.2",
+        "postcss-ordered-values": "^4.1.2",
+        "postcss-reduce-initial": "^4.0.3",
+        "postcss-reduce-transforms": "^4.0.2",
+        "postcss-svgo": "^4.0.3",
+        "postcss-unique-selectors": "^4.0.1"
+      }
+    },
+    "cssnano-util-get-arguments": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/cssnano-util-get-arguments/download/cssnano-util-get-arguments-4.0.0.tgz",
+      "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
+      "dev": true
+    },
+    "cssnano-util-get-match": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/cssnano-util-get-match/download/cssnano-util-get-match-4.0.0.tgz",
+      "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
+      "dev": true
+    },
+    "cssnano-util-raw-cache": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/cssnano-util-raw-cache/download/cssnano-util-raw-cache-4.0.1.tgz",
+      "integrity": "sha1-sm1f1fcqEd/np4RvtMZyYPlr8oI=",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.0"
+      }
+    },
+    "cssnano-util-same-parent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/cssnano-util-same-parent/download/cssnano-util-same-parent-4.0.1.tgz",
+      "integrity": "sha1-V0CC+yhZ0ttDOFWDXZqEVuoYu/M=",
+      "dev": true
+    },
+    "csso": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npm.taobao.org/csso/download/csso-4.2.0.tgz?cache=0&sync_timestamp=1606408849393&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcsso%2Fdownload%2Fcsso-4.2.0.tgz",
+      "integrity": "sha1-6jpWE0bo3J9UbW/r7dUBh884lSk=",
+      "dev": true,
+      "requires": {
+        "css-tree": "^1.1.2"
+      },
+      "dependencies": {
+        "css-tree": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.1.3.tgz?cache=0&sync_timestamp=1617191603409&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.1.3.tgz",
+          "integrity": "sha1-60hw+2/XcHMn7JXC/yqwm16NuR0=",
+          "dev": true,
+          "requires": {
+            "mdn-data": "2.0.14",
+            "source-map": "^0.6.1"
+          }
+        },
+        "mdn-data": {
+          "version": "2.0.14",
+          "resolved": "https://registry.nlark.com/mdn-data/download/mdn-data-2.0.14.tgz?cache=0&sync_timestamp=1619049642547&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.14.tgz",
+          "integrity": "sha1-cRP8QoGRfWPOKbQ0RvcB5owlulA=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "cssom": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+      "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+      "dev": true,
+      "requires": {
+        "cssom": "~0.3.6"
+      },
+      "dependencies": {
+        "cssom": {
+          "version": "0.3.8",
+          "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+          "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+          "dev": true
+        }
+      }
+    },
+    "csstype": {
+      "version": "2.6.17",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz",
+      "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A=="
+    },
+    "cyclist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/cyclist/download/cyclist-1.0.1.tgz",
+      "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz?cache=0&sync_timestamp=1601073714105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdashdash%2Fdownload%2Fdashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "data-urls": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "whatwg-mimetype": "^2.2.0",
+        "whatwg-url": "^7.0.0"
+      }
+    },
+    "dayjs": {
+      "version": "1.10.6",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
+      "integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
+    },
+    "debug": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.3.1.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.3.1.tgz",
+      "integrity": "sha1-8NIpxQXgxtjEmsVT0bE9wYP2su4=",
+      "dev": true,
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/decamelize/download/decamelize-1.2.0.tgz?cache=0&sync_timestamp=1610348666353&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdecamelize%2Fdownload%2Fdecamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decamelize-keys": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
+      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+      "dev": true,
+      "requires": {
+        "decamelize": "^1.1.0",
+        "map-obj": "^1.0.0"
+      },
+      "dependencies": {
+        "map-obj": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+          "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+          "dev": true
+        }
+      }
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npm.taobao.org/decode-uri-component/download/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "dedent": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+      "dev": true
+    },
+    "deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "requires": {
+        "type-detect": "^4.0.0"
+      }
+    },
+    "deep-equal": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.1.1.tgz",
+      "integrity": "sha1-tcmMlCzv+vfLBR4k4UNKJaLmB2o=",
+      "dev": true,
+      "requires": {
+        "is-arguments": "^1.0.4",
+        "is-date-object": "^1.0.1",
+        "is-regex": "^1.0.4",
+        "object-is": "^1.0.1",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.2.0"
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npm.taobao.org/deep-is/download/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "deepmerge": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz?cache=0&sync_timestamp=1593463429320&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-1.5.2.tgz",
+      "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M=",
+      "dev": true
+    },
+    "default-gateway": {
+      "version": "5.0.5",
+      "resolved": "https://registry.nlark.com/default-gateway/download/default-gateway-5.0.5.tgz",
+      "integrity": "sha1-T9a9XShV05s0zFpZUFSG6ar8mxA=",
+      "dev": true,
+      "requires": {
+        "execa": "^3.3.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npm.taobao.org/cross-spawn/download/cross-spawn-7.0.3.tgz?cache=0&sync_timestamp=1590421014780&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcross-spawn%2Fdownload%2Fcross-spawn-7.0.3.tgz",
+          "integrity": "sha1-9zqFudXUHQRVUcF34ogtSshXKKY=",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "execa": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npm.taobao.org/execa/download/execa-3.4.0.tgz",
+          "integrity": "sha1-wI7UVQ72XYWPrCaf/IVyRG8364k=",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "human-signals": "^1.1.1",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.0",
+            "onetime": "^5.1.0",
+            "p-finally": "^2.0.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-5.2.0.tgz?cache=0&sync_timestamp=1618462652134&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-5.2.0.tgz",
+          "integrity": "sha1-SWaheV7lrOZecGxLe+txJX1uItM=",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-stream/download/is-stream-2.0.0.tgz",
+          "integrity": "sha1-venDJoDW+uBBKdasnZIc54FfeOM=",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-2.1.0.tgz?cache=0&sync_timestamp=1617823674050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmimic-fn%2Fdownload%2Fmimic-fn-2.1.0.tgz",
+          "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npm.taobao.org/npm-run-path/download/npm-run-path-4.0.1.tgz",
+          "integrity": "sha1-t+zR5e1T2o43pV4cImnguX7XSOo=",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "onetime": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz",
+          "integrity": "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "p-finally": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/p-finally/download/p-finally-2.0.1.tgz?cache=0&sync_timestamp=1617947676340&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-finally%2Fdownload%2Fp-finally-2.0.1.tgz",
+          "integrity": "sha1-vW/KqcVZoJa2gIBvTWV7Pw8kBWE=",
+          "dev": true
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npm.taobao.org/path-key/download/path-key-3.1.1.tgz?cache=0&sync_timestamp=1617971675964&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-key%2Fdownload%2Fpath-key-3.1.1.tgz",
+          "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/shebang-command/download/shebang-command-2.0.0.tgz",
+          "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/shebang-regex/download/shebang-regex-3.0.0.tgz",
+          "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npm.taobao.org/which/download/which-2.0.2.tgz?cache=0&sync_timestamp=1574116898193&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-2.0.2.tgz",
+          "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "defaults": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/defaults/download/defaults-1.0.3.tgz",
+      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+      "dev": true,
+      "requires": {
+        "clone": "^1.0.2"
+      }
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npm.taobao.org/define-properties/download/define-properties-1.1.3.tgz",
+      "integrity": "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE=",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-2.0.2.tgz",
+      "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz",
+          "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "del": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npm.taobao.org/del/download/del-4.1.1.tgz",
+      "integrity": "sha1-no8RciLqRKMf86FWwEm5kFKp8LQ=",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "globby": "^6.1.0",
+        "is-path-cwd": "^2.0.0",
+        "is-path-in-cwd": "^2.0.0",
+        "p-map": "^2.0.0",
+        "pify": "^4.0.1",
+        "rimraf": "^2.6.3"
+      },
+      "dependencies": {
+        "globby": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npm.taobao.org/globby/download/globby-6.1.0.tgz",
+          "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "glob": "^7.0.3",
+            "object-assign": "^4.0.1",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "2.3.0",
+              "resolved": "https://registry.npm.taobao.org/pify/download/pify-2.3.0.tgz",
+              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/des.js/download/des.js-1.0.1.tgz",
+      "integrity": "sha1-U4IULhvcU/hdhtU+X0qn3rkeCEM=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "detect-node": {
+      "version": "2.1.0",
+      "resolved": "https://registry.nlark.com/detect-node/download/detect-node-2.1.0.tgz?cache=0&sync_timestamp=1621146954463&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdetect-node%2Fdownload%2Fdetect-node-2.1.0.tgz",
+      "integrity": "sha1-yccHdaScPQO8LAbZpzvlUPl4+LE=",
+      "dev": true
+    },
+    "diff": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+      "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npm.taobao.org/diffie-hellman/download/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha1-QOjumPVaIUlgcUaSHGPhrl89KHU=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.12.0",
+          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.12.0.tgz",
+          "integrity": "sha1-d1s/J477uXGO7HNh9IP7Nvu/6og=",
+          "dev": true
+        }
+      }
+    },
+    "dir-glob": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npm.taobao.org/dir-glob/download/dir-glob-2.2.2.tgz",
+      "integrity": "sha1-+gnwaUFTyJGLGLoN6vrpR2n8UMQ=",
+      "dev": true,
+      "requires": {
+        "path-type": "^3.0.0"
+      }
+    },
+    "dns-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/dns-equal/download/dns-equal-1.0.0.tgz",
+      "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+      "dev": true
+    },
+    "dns-packet": {
+      "version": "1.3.4",
+      "resolved": "https://registry.nlark.com/dns-packet/download/dns-packet-1.3.4.tgz?cache=0&sync_timestamp=1622021450532&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdns-packet%2Fdownload%2Fdns-packet-1.3.4.tgz",
+      "integrity": "sha1-40VQZYJKJQe6iGxVqJljuxB97G8=",
+      "dev": true,
+      "requires": {
+        "ip": "^1.1.0",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "dns-txt": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/dns-txt/download/dns-txt-2.0.2.tgz",
+      "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+      "dev": true,
+      "requires": {
+        "buffer-indexof": "^1.0.0"
+      }
+    },
+    "doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/doctrine/download/doctrine-3.0.0.tgz",
+      "integrity": "sha1-rd6+rXKmV023g2OdyHoSF3OXOWE=",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "dom-converter": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+      "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+      "dev": true,
+      "requires": {
+        "utila": "~0.4"
+      }
+    },
+    "dom-serializer": {
+      "version": "0.2.2",
+      "resolved": "https://registry.nlark.com/dom-serializer/download/dom-serializer-0.2.2.tgz?cache=0&sync_timestamp=1621256819522&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdom-serializer%2Fdownload%2Fdom-serializer-0.2.2.tgz",
+      "integrity": "sha1-GvuB9TNxcXXUeGVd68XjMtn5u1E=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^2.0.1",
+        "entities": "^2.0.0"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-2.2.0.tgz",
+          "integrity": "sha1-mgtsJ4LtahxzI9QiZxg9+b2LHVc=",
+          "dev": true
+        }
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/domain-browser/download/domain-browser-1.2.0.tgz",
+      "integrity": "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npm.taobao.org/domelementtype/download/domelementtype-1.3.1.tgz",
+      "integrity": "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8=",
+      "dev": true
+    },
+    "domexception": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+      "dev": true,
+      "requires": {
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "domhandler": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npm.taobao.org/domhandler/download/domhandler-2.4.2.tgz?cache=0&sync_timestamp=1618563983578&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomhandler%2Fdownload%2Fdomhandler-2.4.2.tgz",
+      "integrity": "sha1-iAUJfpM9ZehVRvcm1g9euItE+AM=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1"
+      }
+    },
+    "domutils": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npm.taobao.org/domutils/download/domutils-1.7.0.tgz?cache=0&sync_timestamp=1618565562449&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdomutils%2Fdownload%2Fdomutils-1.7.0.tgz",
+      "integrity": "sha1-Vuo0HoNOBuZ0ivehyyXaZ+qfjCo=",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "0",
+        "domelementtype": "1"
+      }
+    },
+    "dot-prop": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npm.taobao.org/dot-prop/download/dot-prop-5.3.0.tgz?cache=0&sync_timestamp=1605778171073&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdot-prop%2Fdownload%2Fdot-prop-5.3.0.tgz",
+      "integrity": "sha1-kMzOcIzZzYLMTcjD3dmr3VWyDog=",
+      "dev": true,
+      "requires": {
+        "is-obj": "^2.0.0"
+      }
+    },
+    "dotenv": {
+      "version": "8.6.0",
+      "resolved": "https://registry.nlark.com/dotenv/download/dotenv-8.6.0.tgz?cache=0&sync_timestamp=1621629308355&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdotenv%2Fdownload%2Fdotenv-8.6.0.tgz",
+      "integrity": "sha1-Bhr2ZNGff02PxuT/m1hM4jety4s=",
+      "dev": true
+    },
+    "dotenv-expand": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npm.taobao.org/dotenv-expand/download/dotenv-expand-5.1.0.tgz",
+      "integrity": "sha1-P7rwIL/XlIhAcuomsel5HUWmKfA=",
+      "dev": true
+    },
+    "duplexer": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.2.tgz?cache=0&sync_timestamp=1597220926027&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fduplexer%2Fdownload%2Fduplexer-0.1.2.tgz",
+      "integrity": "sha1-Or5DrvODX4rgd9E23c4PJ2sEAOY=",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npm.taobao.org/duplexify/download/duplexify-3.7.1.tgz",
+      "integrity": "sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk=",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "easy-stack": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/easy-stack/download/easy-stack-1.0.1.tgz",
+      "integrity": "sha1-iv5CZGJpiMq7EfPHBMzQyDVBEGY=",
+      "dev": true
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "echarts": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.1.2.tgz",
+      "integrity": "sha512-okUhO4sw22vwZp+rTPNjd/bvTdpug4K4sHNHyrV8NdAncIX9/AarlolFqtJCAYKGFYhUBNjIWu1EznFrSWTFxg==",
+      "requires": {
+        "tslib": "2.0.3",
+        "zrender": "5.1.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
+        }
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "ejs": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npm.taobao.org/ejs/download/ejs-2.7.4.tgz",
+      "integrity": "sha1-SGYSh1c9zFPjZsehrlLDoSDuybo=",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.741",
+      "resolved": "https://registry.nlark.com/electron-to-chromium/download/electron-to-chromium-1.3.741.tgz?cache=0&sync_timestamp=1622168446893&other_urls=https%3A%2F%2Fregistry.nlark.com%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.741.tgz",
+      "integrity": "sha1-3BAksZsx4n+yyMCh8SDLBfxsppU=",
+      "dev": true
+    },
+    "element-plus": {
+      "version": "1.0.2-beta.70",
+      "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-1.0.2-beta.70.tgz",
+      "integrity": "sha512-q9nqxELedLTFMCff5M5CsFbjWQYa6FvcLr1p7QZI64stZ7oEx1EcFnLEeP7dTg0g6iZf1fnaL5df1fVKWY0Dcg==",
+      "requires": {
+        "@element-plus/icons": "^0.0.11",
+        "@popperjs/core": "^2.4.4",
+        "async-validator": "^3.4.0",
+        "dayjs": "1.x",
+        "lodash": "^4.17.20",
+        "mitt": "^2.1.0",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.1"
+      }
+    },
+    "elliptic": {
+      "version": "6.5.4",
+      "resolved": "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.4.tgz",
+      "integrity": "sha1-2jfOvTHnmhNn6UG1ku0fvr1Yq7s=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.11.9",
+        "brorand": "^1.1.0",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.1",
+        "inherits": "^2.0.4",
+        "minimalistic-assert": "^1.0.1",
+        "minimalistic-crypto-utils": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.12.0",
+          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.12.0.tgz",
+          "integrity": "sha1-d1s/J477uXGO7HNh9IP7Nvu/6og=",
+          "dev": true
+        }
+      }
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npm.taobao.org/emoji-regex/download/emoji-regex-8.0.0.tgz?cache=0&sync_timestamp=1614682725186&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Femoji-regex%2Fdownload%2Femoji-regex-8.0.0.tgz",
+      "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=",
+      "dev": true
+    },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-3.0.0.tgz",
+      "integrity": "sha1-VXBmIEatKeLpFucariYKvf9Pang=",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npm.taobao.org/end-of-stream/download/end-of-stream-1.4.4.tgz",
+      "integrity": "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA=",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.5.0",
+      "resolved": "https://registry.nlark.com/enhanced-resolve/download/enhanced-resolve-4.5.0.tgz?cache=0&sync_timestamp=1620663202047&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.5.0.tgz",
+      "integrity": "sha1-Lzz9hNvjtIfxjy2y7x4GSlccpew=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.5.0",
+        "tapable": "^1.0.0"
+      },
+      "dependencies": {
+        "memory-fs": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.5.0.tgz",
+          "integrity": "sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw=",
+          "dev": true,
+          "requires": {
+            "errno": "^0.1.3",
+            "readable-stream": "^2.0.1"
+          }
+        }
+      }
+    },
+    "enquirer": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^4.1.1"
+      },
+      "dependencies": {
+        "ansi-colors": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+          "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+          "dev": true
+        }
+      }
+    },
+    "entities": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/entities/download/entities-2.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fentities%2Fdownload%2Fentities-2.2.0.tgz",
+      "integrity": "sha1-CY3JDruD2N/6CJ1VJWs1HTTE2lU=",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npm.taobao.org/errno/download/errno-0.1.8.tgz",
+      "integrity": "sha1-i7Ppx9Rjvkl2/4iPdrSAnrwugR8=",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npm.taobao.org/error-ex/download/error-ex-1.3.2.tgz",
+      "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "error-stack-parser": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npm.taobao.org/error-stack-parser/download/error-stack-parser-2.0.6.tgz",
+      "integrity": "sha1-WpmnB716TFinl5AtSNgoA+3mqtg=",
+      "dev": true,
+      "requires": {
+        "stackframe": "^1.1.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.18.3",
+      "resolved": "https://registry.nlark.com/es-abstract/download/es-abstract-1.18.3.tgz",
+      "integrity": "sha1-JcTDOAonqiA8RLK2hbupTaMbY+A=",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.2",
+        "is-callable": "^1.2.3",
+        "is-negative-zero": "^2.0.1",
+        "is-regex": "^1.1.3",
+        "is-string": "^1.0.6",
+        "object-inspect": "^1.10.3",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.2",
+        "string.prototype.trimend": "^1.0.4",
+        "string.prototype.trimstart": "^1.0.4",
+        "unbox-primitive": "^1.0.1"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/es-to-primitive/download/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha1-5VzUyc3BiLzvsDs2bHNjI/xciYo=",
+      "dev": true,
+      "requires": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npm.taobao.org/escalade/download/escalade-3.1.1.tgz",
+      "integrity": "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA=",
+      "dev": true
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "escodegen": {
+      "version": "1.14.3",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
+      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+      "dev": true,
+      "requires": {
+        "esprima": "^4.0.1",
+        "estraverse": "^4.2.0",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "eslint": {
+      "version": "6.8.0",
+      "resolved": "https://registry.nlark.com/eslint/download/eslint-6.8.0.tgz",
+      "integrity": "sha1-YiYtZylzn5J1cjgkMC+yJ8jJP/s=",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.10.0",
+        "chalk": "^2.1.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^1.4.3",
+        "eslint-visitor-keys": "^1.1.0",
+        "espree": "^6.1.2",
+        "esquery": "^1.0.1",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^5.0.1",
+        "functional-red-black-tree": "^1.0.1",
+        "glob-parent": "^5.0.0",
+        "globals": "^12.1.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "inquirer": "^7.0.0",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.3.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.8.3",
+        "progress": "^2.0.0",
+        "regexpp": "^2.0.1",
+        "semver": "^6.1.2",
+        "strip-ansi": "^5.2.0",
+        "strip-json-comments": "^3.0.1",
+        "table": "^5.2.3",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
+      },
+      "dependencies": {
+        "eslint-scope": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-5.1.1.tgz",
+          "integrity": "sha1-54blmmbLkrP2wfsNUIqrF0hI9Iw=",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.3.0",
+            "estraverse": "^4.1.1"
+          }
+        },
+        "globals": {
+          "version": "12.4.0",
+          "resolved": "https://registry.nlark.com/globals/download/globals-12.4.0.tgz",
+          "integrity": "sha1-oYgTV2pBsAokqX5/gVkYwuGZJfg=",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "import-fresh": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.3.0.tgz",
+          "integrity": "sha1-NxYsJfy566oublPVtNiM4X2eDCs=",
+          "dev": true,
+          "requires": {
+            "parent-module": "^1.0.0",
+            "resolve-from": "^4.0.0"
+          }
+        },
+        "resolve-from": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/resolve-from/download/resolve-from-4.0.0.tgz",
+          "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-5.2.0.tgz?cache=0&sync_timestamp=1618553299612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-ansi%2Fdownload%2Fstrip-ansi-5.2.0.tgz",
+          "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.nlark.com/type-fest/download/type-fest-0.8.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ftype-fest%2Fdownload%2Ftype-fest-0.8.1.tgz",
+          "integrity": "sha1-CeJJ696FHTseSNJ8EFREZn8XuD0=",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-prettier": {
+      "version": "6.15.0",
+      "resolved": "https://registry.nlark.com/eslint-config-prettier/download/eslint-config-prettier-6.15.0.tgz?cache=0&sync_timestamp=1619270465166&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.15.0.tgz",
+      "integrity": "sha1-f5P2y31FqS8VN6cOzAY2bhrG/tk=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^6.0.0"
+      }
+    },
+    "eslint-loader": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npm.taobao.org/eslint-loader/download/eslint-loader-2.2.1.tgz",
+      "integrity": "sha1-KLnBLaVAV68IReKmEScBova/gzc=",
+      "dev": true,
+      "requires": {
+        "loader-fs-cache": "^1.0.0",
+        "loader-utils": "^1.0.2",
+        "object-assign": "^4.0.1",
+        "object-hash": "^1.1.4",
+        "rimraf": "^2.6.1"
+      }
+    },
+    "eslint-plugin-prettier": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npm.taobao.org/eslint-plugin-prettier/download/eslint-plugin-prettier-3.4.0.tgz",
+      "integrity": "sha1-zbrTvx29Kxd+mCVzf+Y7R2oI8Mc=",
+      "dev": true,
+      "requires": {
+        "prettier-linter-helpers": "^1.0.0"
+      }
+    },
+    "eslint-plugin-vue": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npm.taobao.org/eslint-plugin-vue/download/eslint-plugin-vue-7.9.0.tgz?cache=0&sync_timestamp=1618213434663&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-vue%2Fdownload%2Feslint-plugin-vue-7.9.0.tgz",
+      "integrity": "sha1-+Og6KpCPTEP8gwT1QB1P9nHz1WA=",
+      "dev": true,
+      "requires": {
+        "eslint-utils": "^2.1.0",
+        "natural-compare": "^1.4.0",
+        "semver": "^7.3.2",
+        "vue-eslint-parser": "^7.6.0"
+      },
+      "dependencies": {
+        "eslint-utils": {
+          "version": "2.1.0",
+          "resolved": "https://registry.nlark.com/eslint-utils/download/eslint-utils-2.1.0.tgz",
+          "integrity": "sha1-0t5eA0JOcH3BDHQGjd7a5wh0Gyc=",
+          "dev": true,
+          "requires": {
+            "eslint-visitor-keys": "^1.1.0"
+          }
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-6.0.0.tgz?cache=0&sync_timestamp=1594427602316&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-6.0.0.tgz",
+          "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "semver": {
+          "version": "7.3.5",
+          "resolved": "https://registry.npm.taobao.org/semver/download/semver-7.3.5.tgz?cache=0&sync_timestamp=1616463641178&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.3.5.tgz",
+          "integrity": "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz",
+          "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=",
+          "dev": true
+        }
+      }
+    },
+    "eslint-scope": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-4.0.3.tgz",
+      "integrity": "sha1-ygODMxD2iJoyZHgaqC5j65z+eEg=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "1.4.3",
+      "resolved": "https://registry.nlark.com/eslint-utils/download/eslint-utils-1.4.3.tgz",
+      "integrity": "sha1-dP7HxU0Hdrb2fgJRBAtYBlZOmB8=",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.3.0",
+      "resolved": "https://registry.nlark.com/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz",
+      "integrity": "sha1-MOvR73wv3/AcOk8VEESvJfqwUj4=",
+      "dev": true
+    },
+    "espree": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npm.taobao.org/espree/download/espree-6.2.1.tgz?cache=0&sync_timestamp=1607144023810&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fespree%2Fdownload%2Fespree-6.2.1.tgz",
+      "integrity": "sha1-d/xy4f10SiBSwg84pbV1gy6Cc0o=",
+      "dev": true,
+      "requires": {
+        "acorn": "^7.1.1",
+        "acorn-jsx": "^5.2.0",
+        "eslint-visitor-keys": "^1.1.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.4.1",
+          "resolved": "https://registry.nlark.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1620134156200&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz",
+          "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
+          "dev": true
+        }
+      }
+    },
+    "esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/esprima/download/esprima-4.0.1.tgz?cache=0&sync_timestamp=1569398383140&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fesprima%2Fdownload%2Fesprima-4.0.1.tgz",
+      "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npm.taobao.org/esquery/download/esquery-1.4.0.tgz",
+      "integrity": "sha1-IUj/w4uC6McFff7UhCWz5h8PJKU=",
+      "dev": true,
+      "requires": {
+        "estraverse": "^5.1.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-5.2.0.tgz?cache=0&sync_timestamp=1596641353460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-5.2.0.tgz",
+          "integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=",
+          "dev": true
+        }
+      }
+    },
+    "esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/esrecurse/download/esrecurse-4.3.0.tgz",
+      "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=",
+      "dev": true,
+      "requires": {
+        "estraverse": "^5.2.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-5.2.0.tgz?cache=0&sync_timestamp=1596641353460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-5.2.0.tgz",
+          "integrity": "sha1-MH30JUfmzHMk088DwVXVzbjFOIA=",
+          "dev": true
+        }
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/estraverse/download/estraverse-4.3.0.tgz?cache=0&sync_timestamp=1596641353460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Festraverse%2Fdownload%2Festraverse-4.3.0.tgz",
+      "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=",
+      "dev": true
+    },
+    "estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.nlark.com/estree-walker/download/estree-walker-2.0.2.tgz",
+      "integrity": "sha1-UvAQF4wqTBF6d1fP6UKtt9LaTKw="
+    },
+    "esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npm.taobao.org/esutils/download/esutils-2.0.3.tgz",
+      "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=",
+      "dev": true
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "event-pubsub": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/event-pubsub/download/event-pubsub-4.3.0.tgz?cache=0&sync_timestamp=1606361549058&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fevent-pubsub%2Fdownload%2Fevent-pubsub-4.3.0.tgz",
+      "integrity": "sha1-9o2Ba8KfHsAsU53FjI3UDOcss24=",
+      "dev": true
+    },
+    "eventemitter3": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.7.tgz?cache=0&sync_timestamp=1598517820291&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventemitter3%2Fdownload%2Feventemitter3-4.0.7.tgz",
+      "integrity": "sha1-Lem2j2Uo1WRO9cWVJqG0oHMGFp8=",
+      "dev": true
+    },
+    "events": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npm.taobao.org/events/download/events-3.3.0.tgz",
+      "integrity": "sha1-Mala0Kkk4tLEGagTrrLE6HjqdAA=",
+      "dev": true
+    },
+    "eventsource": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/eventsource/download/eventsource-1.1.0.tgz?cache=0&sync_timestamp=1616041700200&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feventsource%2Fdownload%2Feventsource-1.1.0.tgz",
+      "integrity": "sha1-AOjKfJIQnpSw3fMtrGd9hBAoz68=",
+      "dev": true,
+      "requires": {
+        "original": "^1.0.0"
+      }
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/evp_bytestokey/download/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "execa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/execa/download/execa-1.0.0.tgz",
+      "integrity": "sha1-xiNqW7TfbW8V6I5/AXeYIWdJ3dg=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      }
+    },
+    "execall": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
+      "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
+      "dev": true,
+      "requires": {
+        "clone-regexp": "^2.1.0"
+      }
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433872491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz?cache=0&sync_timestamp=1591256237931&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexpress%2Fdownload%2Fexpress-4.17.1.tgz",
+      "integrity": "sha1-RJH8OGBc9R+GKdOcK10Cb5ikwTQ=",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433872491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz",
+          "integrity": "sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
+      "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz",
+          "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/external-editor/download/external-editor-3.1.0.tgz",
+      "integrity": "sha1-ywP3QL764D6k0oPK7SdBqD8zVJU=",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npm.taobao.org/extglob/download/extglob-2.0.4.tgz",
+      "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/define-property/download/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-1.0.2.tgz",
+          "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-3.1.3.tgz?cache=0&sync_timestamp=1591599604098&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-deep-equal%2Fdownload%2Ffast-deep-equal-3.1.3.tgz",
+      "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=",
+      "dev": true
+    },
+    "fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/fast-diff/download/fast-diff-1.2.0.tgz",
+      "integrity": "sha1-c+4RmC2Gyq95WYKNUZz+kn+sXwM=",
+      "dev": true
+    },
+    "fast-glob": {
+      "version": "2.2.7",
+      "resolved": "https://registry.npm.taobao.org/fast-glob/download/fast-glob-2.2.7.tgz?cache=0&sync_timestamp=1610876590762&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-glob%2Fdownload%2Ffast-glob-2.2.7.tgz",
+      "integrity": "sha1-aVOFfDr6R1//ku5gFdUtpwpM050=",
+      "dev": true,
+      "requires": {
+        "@mrmlnc/readdir-enhanced": "^2.2.1",
+        "@nodelib/fs.stat": "^1.1.2",
+        "glob-parent": "^3.1.0",
+        "is-glob": "^4.0.0",
+        "merge2": "^1.2.3",
+        "micromatch": "^3.1.10"
+      },
+      "dependencies": {
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.nlark.com/glob-parent/download/glob-parent-3.1.0.tgz?cache=0&sync_timestamp=1620073321855&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fglob-parent%2Fdownload%2Fglob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        }
+      }
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npm.taobao.org/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz?cache=0&sync_timestamp=1595428045324&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-levenshtein%2Fdownload%2Ffast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fastest-levenshtein": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
+      "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
+      "dev": true
+    },
+    "fastq": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
+      "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
+      "dev": true,
+      "requires": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "faye-websocket": {
+      "version": "0.11.4",
+      "resolved": "https://registry.nlark.com/faye-websocket/download/faye-websocket-0.11.4.tgz",
+      "integrity": "sha1-fw2Sdc/dhqHJY9yLZfzEUe3Lsdo=",
+      "dev": true,
+      "requires": {
+        "websocket-driver": ">=0.5.1"
+      }
+    },
+    "figgy-pudding": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npm.taobao.org/figgy-pudding/download/figgy-pudding-3.5.2.tgz",
+      "integrity": "sha1-tO7oFIq7Adzx0aw0Nn1Z4S+mHW4=",
+      "dev": true
+    },
+    "figures": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npm.taobao.org/figures/download/figures-3.2.0.tgz",
+      "integrity": "sha1-YlwYvSk8YE3EqN2y/r8MiDQXRq8=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npm.taobao.org/file-entry-cache/download/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha1-yg9u+m3T1WEzP7FFFQZcL6/fQ5w=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^2.0.1"
+      }
+    },
+    "file-loader": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz",
+      "integrity": "sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8=",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.2.3",
+        "schema-utils": "^2.5.0"
+      }
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://repo.huaweicloud.com/repository/npm/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
+    "filesize": {
+      "version": "3.6.1",
+      "resolved": "https://registry.nlark.com/filesize/download/filesize-3.6.1.tgz",
+      "integrity": "sha1-CQuz7gG2+AGoqL6Z0xcQs0Irsxc=",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/finalhandler/download/finalhandler-1.1.2.tgz",
+      "integrity": "sha1-t+fQAP/RGTjQ/bBTUG9uur6fWH0=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npm.taobao.org/debug/download/debug-2.6.9.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz?cache=0&sync_timestamp=1607433872491&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.3.1.tgz",
+      "integrity": "sha1-ibM/rUpGcNqpT4Vff74x1thP6IA=",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^3.0.2",
+        "pkg-dir": "^4.1.0"
+      }
+    },
+    "find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-4.1.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-4.1.0.tgz",
+      "integrity": "sha1-l6/n1s3AvFkoWEt8jXsW6KmqXRk=",
+      "dev": true,
+      "requires": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      }
+    },
+    "flat": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+      "dev": true
+    },
+    "flat-cache": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz",
+      "integrity": "sha1-XSltbwS9pEpGMKMBQTvbwuwIXsA=",
+      "dev": true,
+      "requires": {
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
+      },
+      "dependencies": {
+        "rimraf": {
+          "version": "2.6.3",
+          "resolved": "https://registry.npm.taobao.org/rimraf/download/rimraf-2.6.3.tgz?cache=0&sync_timestamp=1581229865753&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frimraf%2Fdownload%2Frimraf-2.6.3.tgz",
+          "integrity": "sha1-stEE/g2Psnz54KHNqCYt04M8bKs=",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
+      }
+    },
+    "flatted": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/flatted/download/flatted-2.0.2.tgz?cache=0&sync_timestamp=1611061356171&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fflatted%2Fdownload%2Fflatted-2.0.2.tgz",
+      "integrity": "sha1-RXWyHivO50NKqb5mL0t7X5wrUTg=",
+      "dev": true
+    },
+    "flush-write-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/flush-write-stream/download/flush-write-stream-1.1.1.tgz",
+      "integrity": "sha1-jdfYc6G6vCB9lOrQwuDkQnbr8ug=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.14.1",
+      "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.1.tgz?cache=0&sync_timestamp=1620555300559&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.1.tgz",
+      "integrity": "sha1-2RFN7Qoc/dM04WTmZirQK/2R/0M="
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz?cache=0&sync_timestamp=1613410812604&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fform-data%2Fdownload%2Fform-data-2.3.3.tgz",
+      "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npm.taobao.org/fragment-cache/download/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npm.taobao.org/from2/download/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "fs-extra": {
+      "version": "7.0.1",
+      "resolved": "https://registry.nlark.com/fs-extra/download/fs-extra-7.0.1.tgz",
+      "integrity": "sha1-TxicRKoSO4lfcigE9V6iPq3DSOk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npm.taobao.org/fs-write-stream-atomic/download/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "optional": true
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz",
+      "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=",
+      "dev": true
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "generic-names": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz",
+      "integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0"
+      }
+    },
+    "gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npm.taobao.org/gensync/download/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha1-MqbudsPX9S1GsrGuXZP+qFgKJeA=",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-2.0.5.tgz",
+      "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=",
+      "dev": true
+    },
+    "get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true
+    },
+    "get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://registry.nlark.com/get-intrinsic/download/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "get-own-enumerable-property-symbols": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+      "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npm.taobao.org/get-stdin/download/get-stdin-6.0.0.tgz?cache=0&sync_timestamp=1618557641950&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stdin%2Fdownload%2Fget-stdin-6.0.0.tgz",
+      "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npm.taobao.org/get-stream/download/get-stream-4.1.0.tgz?cache=0&sync_timestamp=1618462652134&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fget-stream%2Fdownload%2Fget-stream-4.1.0.tgz",
+      "integrity": "sha1-wbJVV189wh1Zv8ec09K0axw6VLU=",
+      "dev": true,
+      "requires": {
+        "pump": "^3.0.0"
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npm.taobao.org/get-value/download/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.7",
+      "resolved": "https://registry.nlark.com/glob/download/glob-7.1.7.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fglob%2Fdownload%2Fglob-7.1.7.tgz",
+      "integrity": "sha1-Oxk+kjPwHULQs/eClLvutBj5SpA=",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.nlark.com/glob-parent/download/glob-parent-5.1.2.tgz?cache=0&sync_timestamp=1620073321855&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fglob-parent%2Fdownload%2Fglob-parent-5.1.2.tgz",
+      "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=",
+      "dev": true,
+      "requires": {
+        "is-glob": "^4.0.1"
+      }
+    },
+    "glob-to-regexp": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npm.taobao.org/glob-to-regexp/download/glob-to-regexp-0.3.0.tgz",
+      "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+      "dev": true
+    },
+    "global-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+      "dev": true,
+      "requires": {
+        "global-prefix": "^3.0.0"
+      }
+    },
+    "global-prefix": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+      "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+      "dev": true,
+      "requires": {
+        "ini": "^1.3.5",
+        "kind-of": "^6.0.2",
+        "which": "^1.3.1"
+      }
+    },
+    "globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.nlark.com/globals/download/globals-11.12.0.tgz",
+      "integrity": "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4=",
+      "dev": true
+    },
+    "globby": {
+      "version": "9.2.0",
+      "resolved": "https://registry.npm.taobao.org/globby/download/globby-9.2.0.tgz",
+      "integrity": "sha1-/QKacGxwPSm90XD0tts6P3p8tj0=",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "array-union": "^1.0.2",
+        "dir-glob": "^2.2.2",
+        "fast-glob": "^2.2.6",
+        "glob": "^7.1.3",
+        "ignore": "^4.0.3",
+        "pify": "^4.0.1",
+        "slash": "^2.0.0"
+      }
+    },
+    "globjoin": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+      "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=",
+      "dev": true
+    },
+    "gonzales-pe": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz",
+      "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.6.tgz",
+      "integrity": "sha1-/wQLKwhTsjw9MQJ1I3BvGIXXa+4=",
+      "dev": true
+    },
+    "growl": {
+      "version": "1.10.5",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+      "dev": true
+    },
+    "gzip-size": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npm.taobao.org/gzip-size/download/gzip-size-5.1.1.tgz?cache=0&sync_timestamp=1605523125680&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fgzip-size%2Fdownload%2Fgzip-size-5.1.1.tgz",
+      "integrity": "sha1-y5vuaS+HwGErIyhAqHOQTkwTUnQ=",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.1",
+        "pify": "^4.0.1"
+      }
+    },
+    "handle-thing": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npm.taobao.org/handle-thing/download/handle-thing-2.0.1.tgz",
+      "integrity": "sha1-hX95zjWVgMNA1DCBzGSJcNC7I04=",
+      "dev": true
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npm.taobao.org/har-validator/download/har-validator-5.1.5.tgz?cache=0&sync_timestamp=1596082605533&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhar-validator%2Fdownload%2Fhar-validator-5.1.5.tgz",
+      "integrity": "sha1-HwgDufjLIMD6E4It8ezds2veHv0=",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "hard-rejection": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
+      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
+      "dev": true
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz",
+      "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-bigints": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/has-bigints/download/has-bigints-1.0.1.tgz?cache=0&sync_timestamp=1615461293395&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-bigints%2Fdownload%2Fhas-bigints-1.0.1.tgz",
+      "integrity": "sha1-ZP5qywIGc+O3jbA1pa9pqp0HsRM=",
+      "dev": true
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-symbols": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/has-symbols/download/has-symbols-1.0.2.tgz",
+      "integrity": "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/has-value/download/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/has-values/download/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/hash-base/download/hash-base-3.1.0.tgz",
+      "integrity": "sha1-VcOB2eBuHSmXqIO0o/3f5/DTrzM=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
+          "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.1.tgz",
+          "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=",
+          "dev": true
+        }
+      }
+    },
+    "hash-sum": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-2.0.0.tgz?cache=0&sync_timestamp=1586263945599&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhash-sum%2Fdownload%2Fhash-sum-2.0.0.tgz",
+      "integrity": "sha1-gdAbtd6OpKIUrV1urRtSNGCwtFo=",
+      "dev": true
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npm.taobao.org/hash.js/download/hash.js-1.1.7.tgz",
+      "integrity": "sha1-C6vKU46NTuSg+JiNaIZlN6ADz0I=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz",
+      "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=",
+      "dev": true
+    },
+    "hex-color-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz",
+      "integrity": "sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4=",
+      "dev": true
+    },
+    "highlight.js": {
+      "version": "10.7.2",
+      "resolved": "https://registry.nlark.com/highlight.js/download/highlight.js-10.7.2.tgz",
+      "integrity": "sha1-iTGbhh7cZsSIVO0ebaIeqJ+Ec2A=",
+      "dev": true
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "hoopy": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npm.taobao.org/hoopy/download/hoopy-0.1.4.tgz",
+      "integrity": "sha1-YJIH1mEQADOpqUAq096mdzgcGx0=",
+      "dev": true
+    },
+    "hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.nlark.com/hosted-git-info/download/hosted-git-info-2.8.9.tgz?cache=0&sync_timestamp=1621254855802&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.9.tgz",
+      "integrity": "sha1-3/wL+aIcAiCQkPKqaUKeFBTa8/k=",
+      "dev": true
+    },
+    "hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npm.taobao.org/hpack.js/download/hpack.js-2.1.6.tgz",
+      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      }
+    },
+    "hsl-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/hsl-regex/download/hsl-regex-1.0.0.tgz",
+      "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
+      "dev": true
+    },
+    "hsla-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/hsla-regex/download/hsla-regex-1.0.0.tgz",
+      "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
+      "dev": true
+    },
+    "html-encoding-sniffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+      "dev": true,
+      "requires": {
+        "whatwg-encoding": "^1.0.1"
+      }
+    },
+    "html-entities": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npm.taobao.org/html-entities/download/html-entities-1.4.0.tgz?cache=0&sync_timestamp=1617031494718&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtml-entities%2Fdownload%2Fhtml-entities-1.4.0.tgz",
+      "integrity": "sha1-z70bAdKvr5rcobEK59/6uYxx0tw=",
+      "dev": true
+    },
+    "html-minifier": {
+      "version": "3.5.21",
+      "resolved": "https://registry.npm.taobao.org/html-minifier/download/html-minifier-3.5.21.tgz",
+      "integrity": "sha1-0AQOBUcw41TbAIRjWTGUAVIS0gw=",
+      "dev": true,
+      "requires": {
+        "camel-case": "3.0.x",
+        "clean-css": "4.2.x",
+        "commander": "2.17.x",
+        "he": "1.2.x",
+        "param-case": "2.1.x",
+        "relateurl": "0.2.x",
+        "uglify-js": "3.4.x"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.17.1",
+          "resolved": "https://registry.nlark.com/commander/download/commander-2.17.1.tgz?cache=0&sync_timestamp=1621726578455&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcommander%2Fdownload%2Fcommander-2.17.1.tgz",
+          "integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78=",
+          "dev": true
+        }
+      }
+    },
+    "html-tags": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/html-tags/download/html-tags-3.1.0.tgz",
+      "integrity": "sha1-e15vfmZen7QfMAB+2eDUHpf7IUA=",
+      "dev": true
+    },
+    "html-webpack-plugin": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz",
+      "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
+      "dev": true,
+      "requires": {
+        "html-minifier": "^3.2.3",
+        "loader-utils": "^0.2.16",
+        "lodash": "^4.17.3",
+        "pretty-error": "^2.0.2",
+        "tapable": "^1.0.0",
+        "toposort": "^1.0.0",
+        "util.promisify": "1.0.0"
+      },
+      "dependencies": {
+        "big.js": {
+          "version": "3.2.0",
+          "resolved": "https://registry.nlark.com/big.js/download/big.js-3.2.0.tgz",
+          "integrity": "sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4=",
+          "dev": true
+        },
+        "emojis-list": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-2.1.0.tgz",
+          "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+          "dev": true
+        },
+        "json5": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npm.taobao.org/json5/download/json5-0.5.1.tgz?cache=0&sync_timestamp=1612146875530&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-0.5.1.tgz",
+          "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+          "dev": true
+        },
+        "loader-utils": {
+          "version": "0.2.17",
+          "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-0.2.17.tgz",
+          "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
+          "dev": true,
+          "requires": {
+            "big.js": "^3.1.3",
+            "emojis-list": "^2.0.0",
+            "json5": "^0.5.0",
+            "object-assign": "^4.0.1"
+          }
+        },
+        "util.promisify": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/util.promisify/download/util.promisify-1.0.0.tgz?cache=0&sync_timestamp=1610159866228&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Futil.promisify%2Fdownload%2Futil.promisify-1.0.0.tgz",
+          "integrity": "sha1-RA9xZaRZyaFtwUXrjnLzVocJcDA=",
+          "dev": true,
+          "requires": {
+            "define-properties": "^1.1.2",
+            "object.getownpropertydescriptors": "^2.0.3"
+          }
+        }
+      }
+    },
+    "htmlparser2": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz?cache=0&sync_timestamp=1617915295732&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-3.10.1.tgz",
+      "integrity": "sha1-vWedw/WYl7ajS7EHSchVu1OpOS8=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "^1.3.1",
+        "domhandler": "^2.3.0",
+        "domutils": "^1.5.1",
+        "entities": "^1.1.1",
+        "inherits": "^2.0.1",
+        "readable-stream": "^3.1.1"
+      },
+      "dependencies": {
+        "entities": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npm.taobao.org/entities/download/entities-1.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fentities%2Fdownload%2Fentities-1.1.2.tgz",
+          "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz",
+          "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npm.taobao.org/http-deceiver/download/http-deceiver-1.2.7.tgz",
+      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+      "dev": true
+    },
+    "http-errors": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.2.tgz?cache=0&sync_timestamp=1593407738381&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.2.tgz",
+      "integrity": "sha1-T1ApzxMjnzEDblsuVSkrz7zIXI8=",
+      "dev": true,
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.1",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "http-parser-js": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npm.taobao.org/http-parser-js/download/http-parser-js-0.5.3.tgz?cache=0&sync_timestamp=1609542336109&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-parser-js%2Fdownload%2Fhttp-parser-js-0.5.3.tgz",
+      "integrity": "sha1-AdJwnHnUFpi7AdTezF6dpOSgM9k=",
+      "dev": true
+    },
+    "http-proxy": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npm.taobao.org/http-proxy/download/http-proxy-1.18.1.tgz",
+      "integrity": "sha1-QBVB8FNIhLv5UmAzTnL4juOXZUk=",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "^4.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "http-proxy-middleware": {
+      "version": "1.3.1",
+      "resolved": "https://registry.nlark.com/http-proxy-middleware/download/http-proxy-middleware-1.3.1.tgz",
+      "integrity": "sha1-Q3ANbZ7st0Gb8IahKND3IF2etmU=",
+      "dev": true,
+      "requires": {
+        "@types/http-proxy": "^1.17.5",
+        "http-proxy": "^1.18.1",
+        "is-glob": "^4.0.1",
+        "is-plain-obj": "^3.0.0",
+        "micromatch": "^4.0.2"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npm.taobao.org/braces/download/braces-3.0.2.tgz",
+          "integrity": "sha1-NFThpGLujVmeI23zNs2epPiv4Qc=",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-7.0.1.tgz",
+          "integrity": "sha1-GRmmp8df44ssfHflGYU12prN2kA=",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-7.0.0.tgz",
+          "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-4.0.4.tgz?cache=0&sync_timestamp=1618054740956&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmicromatch%2Fdownload%2Fmicromatch-4.0.4.tgz",
+          "integrity": "sha1-iW1Rnf6dsl/OlM63pQCRm/iB6/k=",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.2.3"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npm.taobao.org/to-regex-range/download/to-regex-range-5.0.1.tgz",
+          "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/http-signature/download/http-signature-1.2.0.tgz?cache=0&sync_timestamp=1600868441269&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-signature%2Fdownload%2Fhttp-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/https-browserify/download/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "human-signals": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz",
+      "integrity": "sha1-xbHNFPUK6uCatsWf5jujOV/k36M=",
+      "dev": true
+    },
+    "husky": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz",
+      "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==",
+      "dev": true
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.nlark.com/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1621826271136&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz",
+      "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "icss-replace-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/icss-replace-symbols/download/icss-replace-symbols-1.1.0.tgz",
+      "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
+      "dev": true
+    },
+    "icss-utils": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npm.taobao.org/icss-utils/download/icss-utils-4.1.1.tgz?cache=0&sync_timestamp=1605801375650&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficss-utils%2Fdownload%2Ficss-utils-4.1.1.tgz",
+      "integrity": "sha1-IRcLU3ie4nRHwvR91oMIFAP5pGc=",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.14"
+      }
+    },
+    "ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/ieee754/download/ieee754-1.2.1.tgz?cache=0&sync_timestamp=1603838235461&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fieee754%2Fdownload%2Fieee754-1.2.1.tgz",
+      "integrity": "sha1-jrehCmP/8l0VpXsAFYbRd9Gw01I=",
+      "dev": true
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npm.taobao.org/iferr/download/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz",
+      "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=",
+      "dev": true
+    },
+    "import-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz",
+      "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+      "dev": true,
+      "requires": {
+        "import-from": "^2.1.0"
+      }
+    },
+    "import-fresh": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/import-fresh/download/import-fresh-2.0.0.tgz",
+      "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+      "dev": true,
+      "requires": {
+        "caller-path": "^2.0.0",
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "import-from": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/import-from/download/import-from-2.1.0.tgz",
+      "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "import-lazy": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+      "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+      "dev": true
+    },
+    "import-local": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/import-local/download/import-local-2.0.0.tgz",
+      "integrity": "sha1-VQcL44pZk88Y72236WH1vuXFoJ0=",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^3.0.0",
+        "resolve-cwd": "^2.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-3.0.0.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz",
+          "integrity": "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M=",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-3.0.0.tgz",
+          "integrity": "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4=",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/p-locate/download/p-locate-3.0.0.tgz?cache=0&sync_timestamp=1597081508945&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz",
+          "integrity": "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ=",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-3.0.0.tgz?cache=0&sync_timestamp=1602858985920&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-3.0.0.tgz",
+          "integrity": "sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM=",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        }
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npm.taobao.org/imurmurhash/download/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+      "dev": true
+    },
+    "indexes-of": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/indexes-of/download/indexes-of-1.0.1.tgz",
+      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+      "dev": true
+    },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npm.taobao.org/infer-owner/download/infer-owner-1.0.4.tgz",
+      "integrity": "sha1-xM78qo5RBRwqQLos6KPScpWvlGc=",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz",
+      "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "7.3.3",
+      "resolved": "https://registry.nlark.com/inquirer/download/inquirer-7.3.3.tgz?cache=0&sync_timestamp=1621629105005&other_urls=https%3A%2F%2Fregistry.nlark.com%2Finquirer%2Fdownload%2Finquirer-7.3.3.tgz",
+      "integrity": "sha1-BNF2sq8Er8FXqD/XwQDpjuCq0AM=",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^4.1.0",
+        "cli-cursor": "^3.1.0",
+        "cli-width": "^3.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.19",
+        "mute-stream": "0.0.8",
+        "run-async": "^2.4.0",
+        "rxjs": "^6.6.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995625950&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
+          "integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.1",
+          "resolved": "https://registry.nlark.com/chalk/download/chalk-4.1.1.tgz?cache=0&sync_timestamp=1618995297666&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.1.tgz",
+          "integrity": "sha1-yAs/qyi/Y3HmhjMl7uZ+YYt35q0=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "cli-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/cli-cursor/download/cli-cursor-3.1.0.tgz",
+          "integrity": "sha1-JkMFp65JDR0Dvwybp8kl0XU68wc=",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "^3.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
+          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
+          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz",
+          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-2.1.0.tgz?cache=0&sync_timestamp=1617823674050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmimic-fn%2Fdownload%2Fmimic-fn-2.1.0.tgz",
+          "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz",
+          "integrity": "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4=",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "restore-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npm.taobao.org/restore-cursor/download/restore-cursor-3.1.0.tgz",
+          "integrity": "sha1-OfZ8VLOnpYzqUjbZXPADQjljH34=",
+          "dev": true,
+          "requires": {
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.nlark.com/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1618847145907&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
+          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "internal-ip": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/internal-ip/download/internal-ip-4.3.0.tgz?cache=0&sync_timestamp=1605885556992&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finternal-ip%2Fdownload%2Finternal-ip-4.3.0.tgz",
+      "integrity": "sha1-hFRSuq2dLKO2nGNaE3rLmg2tCQc=",
+      "dev": true,
+      "requires": {
+        "default-gateway": "^4.2.0",
+        "ipaddr.js": "^1.9.0"
+      },
+      "dependencies": {
+        "default-gateway": {
+          "version": "4.2.0",
+          "resolved": "https://registry.nlark.com/default-gateway/download/default-gateway-4.2.0.tgz",
+          "integrity": "sha1-FnEEx1AMIRX23WmwpTa7jtcgVSs=",
+          "dev": true,
+          "requires": {
+            "execa": "^1.0.0",
+            "ip-regex": "^2.1.0"
+          }
+        }
+      }
+    },
+    "interpret": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+      "dev": true
+    },
+    "ip": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npm.taobao.org/ip/download/ip-1.1.5.tgz",
+      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+      "dev": true
+    },
+    "ip-regex": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/ip-regex/download/ip-regex-2.1.0.tgz",
+      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+      "dev": true
+    },
+    "ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npm.taobao.org/ipaddr.js/download/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha1-v/OFQ+64mEglB5/zoqjmy9RngbM=",
+      "dev": true
+    },
+    "is-absolute-url": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-absolute-url/download/is-absolute-url-2.1.0.tgz",
+      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npm.taobao.org/is-accessor-descriptor/download/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-alphabetical": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+      "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+      "dev": true
+    },
+    "is-alphanumerical": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+      "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+      "dev": true,
+      "requires": {
+        "is-alphabetical": "^1.0.0",
+        "is-decimal": "^1.0.0"
+      }
+    },
+    "is-arguments": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.1.0.tgz",
+      "integrity": "sha1-YjUwMd++4HzrNGVqa95Z7+yujdk=",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0"
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npm.taobao.org/is-arrayish/download/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-bigint": {
+      "version": "1.0.2",
+      "resolved": "https://registry.nlark.com/is-bigint/download/is-bigint-1.0.2.tgz?cache=0&sync_timestamp=1620161578872&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fis-bigint%2Fdownload%2Fis-bigint-1.0.2.tgz",
+      "integrity": "sha1-/7OBRCUDI1rSReqJ5Fs9v/BA7lo=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-binary-path/download/is-binary-path-2.1.0.tgz",
+      "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^2.0.0"
+      }
+    },
+    "is-boolean-object": {
+      "version": "1.1.1",
+      "resolved": "https://registry.nlark.com/is-boolean-object/download/is-boolean-object-1.1.1.tgz",
+      "integrity": "sha1-PAh48DXLghIo01DS4eNnGXFqPeg=",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz?cache=0&sync_timestamp=1604432378894&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-1.1.6.tgz",
+      "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
+      "dev": true
+    },
+    "is-callable": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npm.taobao.org/is-callable/download/is-callable-1.2.3.tgz?cache=0&sync_timestamp=1612133035765&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-callable%2Fdownload%2Fis-callable-1.2.3.tgz",
+      "integrity": "sha1-ix4FALc6HXbHBIdjbzaOUZ3o244=",
+      "dev": true
+    },
+    "is-ci": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npm.taobao.org/is-ci/download/is-ci-1.2.1.tgz?cache=0&sync_timestamp=1613631987391&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-ci%2Fdownload%2Fis-ci-1.2.1.tgz",
+      "integrity": "sha1-43ecjuF/zPQoSI9uKBGH8uYyhBw=",
+      "dev": true,
+      "requires": {
+        "ci-info": "^1.5.0"
+      }
+    },
+    "is-color-stop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-color-stop/download/is-color-stop-1.1.0.tgz",
+      "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
+      "dev": true,
+      "requires": {
+        "css-color-names": "^0.0.4",
+        "hex-color-regex": "^1.1.0",
+        "hsl-regex": "^1.0.0",
+        "hsla-regex": "^1.0.0",
+        "rgb-regex": "^1.0.1",
+        "rgba-regex": "^1.0.0"
+      }
+    },
+    "is-core-module": {
+      "version": "2.4.0",
+      "resolved": "https://registry.nlark.com/is-core-module/download/is-core-module-2.4.0.tgz",
+      "integrity": "sha1-jp/I4VAnsBFBgCbpjw5vTYYwXME=",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npm.taobao.org/is-data-descriptor/download/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.4",
+      "resolved": "https://registry.nlark.com/is-date-object/download/is-date-object-1.0.4.tgz",
+      "integrity": "sha1-VQz8wDr62gXuo90wmBx7CVUfc+U=",
+      "dev": true
+    },
+    "is-decimal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+      "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+      "dev": true
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npm.taobao.org/is-descriptor/download/is-descriptor-0.1.6.tgz",
+      "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-5.1.0.tgz",
+          "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=",
+          "dev": true
+        }
+      }
+    },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npm.taobao.org/is-directory/download/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
+    "is-docker": {
+      "version": "2.2.1",
+      "resolved": "https://registry.nlark.com/is-docker/download/is-docker-2.2.1.tgz",
+      "integrity": "sha1-M+6r4jz+hvFL3kQIoCwM+4U6zao=",
+      "dev": true
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npm.taobao.org/is-extendable/download/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-fullwidth-code-point/download/is-fullwidth-code-point-3.0.0.tgz?cache=0&sync_timestamp=1618552489864&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-fullwidth-code-point%2Fdownload%2Fis-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/is-glob/download/is-glob-4.0.1.tgz",
+      "integrity": "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-hexadecimal": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+      "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+      "dev": true
+    },
+    "is-negative-zero": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npm.taobao.org/is-negative-zero/download/is-negative-zero-2.0.1.tgz?cache=0&sync_timestamp=1607123159909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-negative-zero%2Fdownload%2Fis-negative-zero-2.0.1.tgz",
+      "integrity": "sha1-PedGwY3aIxkkGlNnWQjY92bxHCQ=",
+      "dev": true
+    },
+    "is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-number/download/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-number-object": {
+      "version": "1.0.5",
+      "resolved": "https://registry.nlark.com/is-number-object/download/is-number-object-1.0.5.tgz",
+      "integrity": "sha1-bt+u7XlQz/Ga/tzp+/yp7m3Sies=",
+      "dev": true
+    },
+    "is-obj": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-obj/download/is-obj-2.0.0.tgz",
+      "integrity": "sha1-Rz+wXZc3BeP9liBUUBjKjiLvSYI=",
+      "dev": true
+    },
+    "is-path-cwd": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/is-path-cwd/download/is-path-cwd-2.2.0.tgz",
+      "integrity": "sha1-Z9Q7gmZKe1GR/ZEZEn6zAASKn9s=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.nlark.com/is-path-in-cwd/download/is-path-in-cwd-2.1.0.tgz?cache=0&sync_timestamp=1620047156679&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fis-path-in-cwd%2Fdownload%2Fis-path-in-cwd-2.1.0.tgz",
+      "integrity": "sha1-v+Lcomxp85cmWkAJljYCk1oFOss=",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "^2.1.0"
+      }
+    },
+    "is-path-inside": {
+      "version": "2.1.0",
+      "resolved": "https://registry.nlark.com/is-path-inside/download/is-path-inside-2.1.0.tgz?cache=0&sync_timestamp=1620046845369&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fis-path-inside%2Fdownload%2Fis-path-inside-2.1.0.tgz",
+      "integrity": "sha1-fJgQWH1lmkDSe8201WFuqwWUlLI=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "^1.0.2"
+      }
+    },
+    "is-plain-obj": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-plain-obj/download/is-plain-obj-3.0.0.tgz?cache=0&sync_timestamp=1618600554597&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-plain-obj%2Fdownload%2Fis-plain-obj-3.0.0.tgz",
+      "integrity": "sha1-r28uoUrFpkYYOlu9tbqrvBVq2dc=",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npm.taobao.org/is-plain-object/download/is-plain-object-2.0.4.tgz?cache=0&sync_timestamp=1599667316315&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-plain-object%2Fdownload%2Fis-plain-object-2.0.4.tgz",
+      "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-regex": {
+      "version": "1.1.3",
+      "resolved": "https://registry.nlark.com/is-regex/download/is-regex-1.1.3.tgz",
+      "integrity": "sha1-0Cn5r/ZEi5Prvj8z2scVEf3L758=",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "has-symbols": "^1.0.2"
+      }
+    },
+    "is-regexp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
+      "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
+      "dev": true
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-resolvable/download/is-resolvable-1.1.0.tgz",
+      "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=",
+      "dev": true
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-stream/download/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
+    },
+    "is-string": {
+      "version": "1.0.6",
+      "resolved": "https://registry.nlark.com/is-string/download/is-string-1.0.6.tgz",
+      "integrity": "sha1-P+XVmS+w2TQE8yWE1LAXmnG1Sl8=",
+      "dev": true
+    },
+    "is-symbol": {
+      "version": "1.0.4",
+      "resolved": "https://registry.nlark.com/is-symbol/download/is-symbol-1.0.4.tgz?cache=0&sync_timestamp=1620501174327&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fis-symbol%2Fdownload%2Fis-symbol-1.0.4.tgz",
+      "integrity": "sha1-ptrJO2NbBjymhyI23oiRClevE5w=",
+      "dev": true,
+      "requires": {
+        "has-symbols": "^1.0.2"
+      }
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-unicode-supported": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/is-windows/download/is-windows-1.0.2.tgz",
+      "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/is-wsl/download/is-wsl-1.1.0.tgz",
+      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npm.taobao.org/isobject/download/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "javascript-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npm.taobao.org/javascript-stringify/download/javascript-stringify-2.1.0.tgz",
+      "integrity": "sha1-J8dlOb4U2L0Sghmi1zGwkzeQTnk=",
+      "dev": true
+    },
+    "js-message": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npm.taobao.org/js-message/download/js-message-1.0.7.tgz",
+      "integrity": "sha1-+93QU8ekcCGHG7iyyVOXzBfCDkc=",
+      "dev": true
+    },
+    "js-queue": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npm.taobao.org/js-queue/download/js-queue-2.0.2.tgz",
+      "integrity": "sha1-C+WQM4+QOzbHPTPDGIOoIUEs1II=",
+      "dev": true,
+      "requires": {
+        "easy-stack": "^1.0.1"
+      }
+    },
+    "js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.nlark.com/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1619345098261&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz",
+      "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.14.1",
+      "resolved": "https://registry.npm.taobao.org/js-yaml/download/js-yaml-3.14.1.tgz?cache=0&sync_timestamp=1618435028703&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjs-yaml%2Fdownload%2Fjs-yaml-3.14.1.tgz",
+      "integrity": "sha1-2ugS/bOCX6MGYJqHFzg8UMNqBTc=",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "jsdom": {
+      "version": "15.2.1",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
+      "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "acorn": "^7.1.0",
+        "acorn-globals": "^4.3.2",
+        "array-equal": "^1.0.0",
+        "cssom": "^0.4.1",
+        "cssstyle": "^2.0.0",
+        "data-urls": "^1.1.0",
+        "domexception": "^1.0.1",
+        "escodegen": "^1.11.1",
+        "html-encoding-sniffer": "^1.0.2",
+        "nwsapi": "^2.2.0",
+        "parse5": "5.1.0",
+        "pn": "^1.1.0",
+        "request": "^2.88.0",
+        "request-promise-native": "^1.0.7",
+        "saxes": "^3.1.9",
+        "symbol-tree": "^3.2.2",
+        "tough-cookie": "^3.0.1",
+        "w3c-hr-time": "^1.0.1",
+        "w3c-xmlserializer": "^1.1.2",
+        "webidl-conversions": "^4.0.2",
+        "whatwg-encoding": "^1.0.5",
+        "whatwg-mimetype": "^2.3.0",
+        "whatwg-url": "^7.0.0",
+        "ws": "^7.0.0",
+        "xml-name-validator": "^3.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.4.1",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+          "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+          "dev": true
+        },
+        "parse5": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+          "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+          "dev": true
+        },
+        "tough-cookie": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+          "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+          "dev": true,
+          "requires": {
+            "ip-regex": "^2.1.0",
+            "psl": "^1.1.28",
+            "punycode": "^2.1.1"
+          }
+        },
+        "ws": {
+          "version": "7.4.6",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+          "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+          "dev": true
+        }
+      }
+    },
+    "jsdom-global": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/jsdom-global/-/jsdom-global-3.0.2.tgz",
+      "integrity": "sha1-a9KZwTsMRiay2iwDk81DhdYGrLk=",
+      "dev": true
+    },
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npm.taobao.org/jsesc/download/jsesc-2.5.2.tgz",
+      "integrity": "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q=",
+      "dev": true
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npm.taobao.org/json-parse-better-errors/download/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha1-u4Z8+zRQ5pEHwTHRxRS6s9yLyqk=",
+      "dev": true
+    },
+    "json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npm.taobao.org/json-parse-even-better-errors/download/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha1-fEeAWpQxmSjgV3dAXcEuH3pO4C0=",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.nlark.com/json-schema/download/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=",
+      "dev": true
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/json-stable-stringify-without-jsonify/download/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json3": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npm.taobao.org/json3/download/json3-3.3.3.tgz",
+      "integrity": "sha1-f8EON1/FrkLEcFpcwKpvYr4wW4E=",
+      "dev": true
+    },
+    "json5": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/json5/download/json5-2.2.0.tgz?cache=0&sync_timestamp=1612146875530&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-2.2.0.tgz",
+      "integrity": "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM=",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz?cache=0&sync_timestamp=1604161844511&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonfile%2Fdownload%2Fjsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "killable": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz",
+      "integrity": "sha1-TIzkQRh6Bhx0dPuHygjipjgZSJI=",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.3.tgz",
+      "integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=",
+      "dev": true
+    },
+    "known-css-properties": {
+      "version": "0.21.0",
+      "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.21.0.tgz",
+      "integrity": "sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==",
+      "dev": true
+    },
+    "launch-editor": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npm.taobao.org/launch-editor/download/launch-editor-2.2.1.tgz",
+      "integrity": "sha1-hxtaPuOdZoD8wm03kwtu7aidsMo=",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.3.0",
+        "shell-quote": "^1.6.1"
+      }
+    },
+    "launch-editor-middleware": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npm.taobao.org/launch-editor-middleware/download/launch-editor-middleware-2.2.1.tgz",
+      "integrity": "sha1-4UsH5scVSwpLhqD9NFeE5FgEwVc=",
+      "dev": true,
+      "requires": {
+        "launch-editor": "^2.2.1"
+      }
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flevn%2Fdownload%2Flevn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      }
+    },
+    "lines-and-columns": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npm.taobao.org/lines-and-columns/download/lines-and-columns-1.1.6.tgz",
+      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "dev": true
+    },
+    "lint-staged": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.0.0.tgz",
+      "integrity": "sha512-3rsRIoyaE8IphSUtO1RVTFl1e0SLBtxxUOPBtHxQgBHS5/i6nqvjcUfNioMa4BU9yGnPzbO+xkfLtXtxBpCzjw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^4.1.1",
+        "cli-truncate": "^2.1.0",
+        "commander": "^7.2.0",
+        "cosmiconfig": "^7.0.0",
+        "debug": "^4.3.1",
+        "dedent": "^0.7.0",
+        "enquirer": "^2.3.6",
+        "execa": "^5.0.0",
+        "listr2": "^3.8.2",
+        "log-symbols": "^4.1.0",
+        "micromatch": "^4.0.4",
+        "normalize-path": "^3.0.0",
+        "please-upgrade-node": "^3.2.0",
+        "string-argv": "0.3.1",
+        "stringify-object": "^3.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+          "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "commander": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+          "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+          "dev": true
+        },
+        "cosmiconfig": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+          "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
+          "dev": true,
+          "requires": {
+            "@types/parse-json": "^4.0.0",
+            "import-fresh": "^3.2.1",
+            "parse-json": "^5.0.0",
+            "path-type": "^4.0.0",
+            "yaml": "^1.10.0"
+          }
+        },
+        "cross-spawn": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "execa": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.0.tgz",
+          "integrity": "sha512-CkdUB7s2y6S+d4y+OM/+ZtQcJCiKUCth4cNImGMqrt2zEVtW2rfHGspQBE1GDo6LjeNIQmTPKXqTCKjqFKyu3A==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.3",
+            "get-stream": "^6.0.0",
+            "human-signals": "^2.1.0",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^4.0.1",
+            "onetime": "^5.1.2",
+            "signal-exit": "^3.0.3",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "get-stream": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+          "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "human-signals": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+          "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+          "dev": true
+        },
+        "import-fresh": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+          "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+          "dev": true,
+          "requires": {
+            "parent-module": "^1.0.0",
+            "resolve-from": "^4.0.0"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "log-symbols": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+          "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^4.1.0",
+            "is-unicode-supported": "^0.1.0"
+          }
+        },
+        "micromatch": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+          "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.2.3"
+          }
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+          "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "onetime": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+          "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+          "dev": true
+        },
+        "resolve-from": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "listr2": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.9.0.tgz",
+      "integrity": "sha512-+JxQt7Vi4WEWgJsxmOEX9lDbCumrb3mrEYIeE1VI7I4lf2rXE4v9pq3RMVNp+a9s6mCgc/IsF0ppHsLrx2BEAw==",
+      "dev": true,
+      "requires": {
+        "cli-truncate": "^2.1.0",
+        "colorette": "^1.2.2",
+        "log-update": "^4.0.0",
+        "p-map": "^4.0.0",
+        "rxjs": "^6.6.7",
+        "through": "^2.3.8",
+        "wrap-ansi": "^7.0.0"
+      },
+      "dependencies": {
+        "p-map": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+          "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+          "dev": true,
+          "requires": {
+            "aggregate-error": "^3.0.0"
+          }
+        }
+      }
+    },
+    "loader-fs-cache": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npm.taobao.org/loader-fs-cache/download/loader-fs-cache-1.0.3.tgz",
+      "integrity": "sha1-8IZXZG1gcHi+LwoDL4vWndbyd9k=",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^0.1.1",
+        "mkdirp": "^0.5.1"
+      },
+      "dependencies": {
+        "find-cache-dir": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-0.1.1.tgz",
+          "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "mkdirp": "^0.5.1",
+            "pkg-dir": "^1.0.0"
+          }
+        },
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npm.taobao.org/find-up/download/find-up-1.1.2.tgz?cache=0&sync_timestamp=1597169862146&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npm.taobao.org/path-exists/download/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "pkg-dir": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-1.0.0.tgz?cache=0&sync_timestamp=1602858985920&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-1.0.0.tgz",
+          "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+          "dev": true,
+          "requires": {
+            "find-up": "^1.0.0"
+          }
+        }
+      }
+    },
+    "loader-runner": {
+      "version": "2.4.0",
+      "resolved": "https://registry.nlark.com/loader-runner/download/loader-runner-2.4.0.tgz",
+      "integrity": "sha1-7UcGa/5TTX6ExMe5mYwqdWB9k1c=",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-1.4.0.tgz",
+      "integrity": "sha1-xXm140yzSxp07cbB+za/o3HVphM=",
+      "dev": true,
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npm.taobao.org/json5/download/json5-1.0.1.tgz?cache=0&sync_timestamp=1612146875530&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz",
+          "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        }
+      }
+    },
+    "locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz",
+      "integrity": "sha1-Gvujlq/WdqbUJQTQpno6frn2KqA=",
+      "dev": true,
+      "requires": {
+        "p-locate": "^4.1.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.21.tgz?cache=0&sync_timestamp=1613835817439&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.21.tgz",
+      "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw="
+    },
+    "lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npm.taobao.org/lodash.camelcase/download/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+      "dev": true
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+      "dev": true
+    },
+    "lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npm.taobao.org/lodash.debounce/download/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+      "dev": true
+    },
+    "lodash.defaultsdeep": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npm.taobao.org/lodash.defaultsdeep/download/lodash.defaultsdeep-4.6.1.tgz",
+      "integrity": "sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY=",
+      "dev": true
+    },
+    "lodash.kebabcase": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npm.taobao.org/lodash.kebabcase/download/lodash.kebabcase-4.1.1.tgz",
+      "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+      "dev": true
+    },
+    "lodash.mapvalues": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npm.taobao.org/lodash.mapvalues/download/lodash.mapvalues-4.6.0.tgz",
+      "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=",
+      "dev": true
+    },
+    "lodash.memoize": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz",
+      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+      "dev": true
+    },
+    "lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+      "dev": true
+    },
+    "lodash.transform": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz",
+      "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=",
+      "dev": true
+    },
+    "lodash.truncate": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+      "dev": true
+    },
+    "lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+      "dev": true
+    },
+    "log-symbols": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npm.taobao.org/log-symbols/download/log-symbols-2.2.0.tgz?cache=0&sync_timestamp=1618723146520&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flog-symbols%2Fdownload%2Flog-symbols-2.2.0.tgz",
+      "integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.1"
+      }
+    },
+    "log-update": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+      "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^4.3.0",
+        "cli-cursor": "^3.1.0",
+        "slice-ansi": "^4.0.0",
+        "wrap-ansi": "^6.2.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "astral-regex": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+          "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+          "dev": true
+        },
+        "cli-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "^3.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+          "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "restore-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+          "dev": true,
+          "requires": {
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2"
+          }
+        },
+        "slice-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+          "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "astral-regex": "^2.0.0",
+            "is-fullwidth-code-point": "^3.0.0"
+          }
+        },
+        "wrap-ansi": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0"
+          }
+        }
+      }
+    },
+    "loglevel": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npm.taobao.org/loglevel/download/loglevel-1.7.1.tgz?cache=0&sync_timestamp=1606314029553&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floglevel%2Fdownload%2Floglevel-1.7.1.tgz",
+      "integrity": "sha1-AF/eL15uRwaPk1/yhXPhJe9y8Zc=",
+      "dev": true
+    },
+    "longest-streak": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz",
+      "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==",
+      "dev": true
+    },
+    "lower-case": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npm.taobao.org/lower-case/download/lower-case-1.1.4.tgz?cache=0&sync_timestamp=1606867317282&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flower-case%2Fdownload%2Flower-case-1.1.4.tgz",
+      "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-5.1.1.tgz?cache=0&sync_timestamp=1594427602316&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-5.1.1.tgz",
+      "integrity": "sha1-HaJ+ZxAnGUdpXa9oSOhH8B2EuSA=",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "magic-string": {
+      "version": "0.25.7",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
+      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+      "dev": true,
+      "requires": {
+        "sourcemap-codec": "^1.4.4"
+      }
+    },
+    "make-dir": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npm.taobao.org/make-dir/download/make-dir-3.1.0.tgz",
+      "integrity": "sha1-QV6WcEazp/HRhSd9hKpYIDcmoT8=",
+      "dev": true,
+      "requires": {
+        "semver": "^6.0.0"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npm.taobao.org/map-cache/download/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz",
+      "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npm.taobao.org/map-visit/download/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "mathml-tag-names": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
+      "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
+      "dev": true
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz",
+      "integrity": "sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8=",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "mdast-util-from-markdown": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz",
+      "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==",
+      "dev": true,
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-string": "^2.0.0",
+        "micromark": "~2.11.0",
+        "parse-entities": "^2.0.0",
+        "unist-util-stringify-position": "^2.0.0"
+      }
+    },
+    "mdast-util-to-markdown": {
+      "version": "0.6.5",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz",
+      "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==",
+      "dev": true,
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "longest-streak": "^2.0.0",
+        "mdast-util-to-string": "^2.0.0",
+        "parse-entities": "^2.0.0",
+        "repeat-string": "^1.0.0",
+        "zwitch": "^1.0.0"
+      }
+    },
+    "mdast-util-to-string": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz",
+      "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==",
+      "dev": true
+    },
+    "mdn-data": {
+      "version": "2.0.4",
+      "resolved": "https://registry.nlark.com/mdn-data/download/mdn-data-2.0.4.tgz?cache=0&sync_timestamp=1619049642547&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fmdn-data%2Fdownload%2Fmdn-data-2.0.4.tgz",
+      "integrity": "sha1-aZs8OKxvHXKAkaZGULZdOIUC/Vs=",
+      "dev": true
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npm.taobao.org/memory-fs/download/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "dev": true,
+      "requires": {
+        "errno": "^0.1.3",
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "meow": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
+      "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
+      "dev": true,
+      "requires": {
+        "@types/minimist": "^1.2.0",
+        "camelcase-keys": "^6.2.2",
+        "decamelize": "^1.2.0",
+        "decamelize-keys": "^1.1.0",
+        "hard-rejection": "^2.1.0",
+        "minimist-options": "4.1.0",
+        "normalize-package-data": "^3.0.0",
+        "read-pkg-up": "^7.0.1",
+        "redent": "^3.0.0",
+        "trim-newlines": "^3.0.0",
+        "type-fest": "^0.18.0",
+        "yargs-parser": "^20.2.3"
+      },
+      "dependencies": {
+        "hosted-git-info": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
+          "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
+        "normalize-package-data": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz",
+          "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==",
+          "dev": true,
+          "requires": {
+            "hosted-git-info": "^4.0.1",
+            "resolve": "^1.20.0",
+            "semver": "^7.3.4",
+            "validate-npm-package-license": "^3.0.1"
+          }
+        },
+        "semver": {
+          "version": "7.3.5",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+          "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "type-fest": {
+          "version": "0.18.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
+          "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
+          "dev": true
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
+        }
+      }
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/merge-descriptors/download/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "merge-source-map": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz",
+      "integrity": "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY=",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
+          "dev": true
+        }
+      }
+    },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npm.taobao.org/merge-stream/download/merge-stream-2.0.0.tgz",
+      "integrity": "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A=",
+      "dev": true
+    },
+    "merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npm.taobao.org/merge2/download/merge2-1.4.1.tgz?cache=0&sync_timestamp=1591170081942&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmerge2%2Fdownload%2Fmerge2-1.4.1.tgz",
+      "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=",
+      "dev": true
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true
+    },
+    "micromark": {
+      "version": "2.11.4",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz",
+      "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.0.0",
+        "parse-entities": "^2.0.0"
+      }
+    },
+    "micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npm.taobao.org/micromatch/download/micromatch-3.1.10.tgz?cache=0&sync_timestamp=1618054740956&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmicromatch%2Fdownload%2Fmicromatch-3.1.10.tgz",
+      "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "braces": "^2.3.1",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "extglob": "^2.0.4",
+        "fragment-cache": "^0.2.1",
+        "kind-of": "^6.0.2",
+        "nanomatch": "^1.2.9",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.2"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npm.taobao.org/miller-rabin/download/miller-rabin-4.0.1.tgz",
+      "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.12.0",
+          "resolved": "https://registry.npm.taobao.org/bn.js/download/bn.js-4.12.0.tgz",
+          "integrity": "sha1-d1s/J477uXGO7HNh9IP7Nvu/6og=",
+          "dev": true
+        }
+      }
+    },
+    "mime": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npm.taobao.org/mime/download/mime-2.5.2.tgz?cache=0&sync_timestamp=1613584838235&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime%2Fdownload%2Fmime-2.5.2.tgz",
+      "integrity": "sha1-bj3GzCuVEGQ4MOXxnVy3U9pe6r4=",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.47.0",
+      "resolved": "https://registry.nlark.com/mime-db/download/mime-db-1.47.0.tgz",
+      "integrity": "sha1-jLMT5Zll08Bc+/iYkVomevRqM1w=",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.30",
+      "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.30.tgz?cache=0&sync_timestamp=1617340124913&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-types%2Fdownload%2Fmime-types-2.1.30.tgz",
+      "integrity": "sha1-bnvotMR5gl+F7WMmaV23P5MF1i0=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.47.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npm.taobao.org/mimic-fn/download/mimic-fn-1.2.0.tgz?cache=0&sync_timestamp=1617823674050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmimic-fn%2Fdownload%2Fmimic-fn-1.2.0.tgz",
+      "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=",
+      "dev": true
+    },
+    "min-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
+      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
+      "dev": true
+    },
+    "mini-css-extract-plugin": {
+      "version": "0.9.0",
+      "resolved": "https://registry.nlark.com/mini-css-extract-plugin/download/mini-css-extract-plugin-0.9.0.tgz",
+      "integrity": "sha1-R/LPB6oWWrNXM7H8l9TEbAVkM54=",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "normalize-url": "1.9.1",
+        "schema-utils": "^1.0.0",
+        "webpack-sources": "^1.1.0"
+      },
+      "dependencies": {
+        "normalize-url": {
+          "version": "1.9.1",
+          "resolved": "https://registry.nlark.com/normalize-url/download/normalize-url-1.9.1.tgz?cache=0&sync_timestamp=1621862036609&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fnormalize-url%2Fdownload%2Fnormalize-url-1.9.1.tgz",
+          "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+          "dev": true,
+          "requires": {
+            "object-assign": "^4.0.1",
+            "prepend-http": "^1.0.0",
+            "query-string": "^4.1.0",
+            "sort-keys": "^1.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npm.taobao.org/schema-utils/download/schema-utils-1.0.0.tgz?cache=0&sync_timestamp=1601922425223&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fschema-utils%2Fdownload%2Fschema-utils-1.0.0.tgz",
+          "integrity": "sha1-C3mpMgTXtgDUsoUNH2bCo0lRx3A=",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/minimalistic-assert/download/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/minimalistic-crypto-utils/download/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz",
+      "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz",
+      "integrity": "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=",
+      "dev": true
+    },
+    "minimist-options": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
+      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
+      "dev": true,
+      "requires": {
+        "arrify": "^1.0.1",
+        "is-plain-obj": "^1.1.0",
+        "kind-of": "^6.0.3"
+      },
+      "dependencies": {
+        "is-plain-obj": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+          "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+          "dev": true
+        }
+      }
+    },
+    "minipass": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npm.taobao.org/minipass/download/minipass-3.1.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminipass%2Fdownload%2Fminipass-3.1.3.tgz",
+      "integrity": "sha1-fUL/HzljVILhX5zbUxhN7r1YFf0=",
+      "dev": true,
+      "requires": {
+        "yallist": "^4.0.0"
+      },
+      "dependencies": {
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz",
+          "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=",
+          "dev": true
+        }
+      }
+    },
+    "mississippi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npm.taobao.org/mississippi/download/mississippi-3.0.0.tgz",
+      "integrity": "sha1-6goykfl+C16HdrNj1fChLZTGcCI=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "^1.5.0",
+        "duplexify": "^3.4.2",
+        "end-of-stream": "^1.1.0",
+        "flush-write-stream": "^1.0.0",
+        "from2": "^2.1.0",
+        "parallel-transform": "^1.1.0",
+        "pump": "^3.0.0",
+        "pumpify": "^1.3.3",
+        "stream-each": "^1.1.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "mitt": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz",
+      "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg=="
+    },
+    "mixin-deep": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npm.taobao.org/mixin-deep/download/mixin-deep-1.3.2.tgz",
+      "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz",
+          "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.5.tgz?cache=0&sync_timestamp=1587535418745&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.5.tgz",
+      "integrity": "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8=",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.5"
+      }
+    },
+    "mocha": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.0.0.tgz",
+      "integrity": "sha512-GRGG/q9bIaUkHJB9NL+KZNjDhMBHB30zW3bZW9qOiYr+QChyLjPzswaxFWkI1q6lGlSL28EQYzAi2vKWNkPx+g==",
+      "dev": true,
+      "requires": {
+        "@ungap/promise-all-settled": "1.1.2",
+        "ansi-colors": "4.1.1",
+        "browser-stdout": "1.3.1",
+        "chokidar": "3.5.1",
+        "debug": "4.3.1",
+        "diff": "5.0.0",
+        "escape-string-regexp": "4.0.0",
+        "find-up": "5.0.0",
+        "glob": "7.1.7",
+        "growl": "1.10.5",
+        "he": "1.2.0",
+        "js-yaml": "4.1.0",
+        "log-symbols": "4.1.0",
+        "minimatch": "3.0.4",
+        "ms": "2.1.3",
+        "nanoid": "3.1.23",
+        "serialize-javascript": "5.0.1",
+        "strip-json-comments": "3.1.1",
+        "supports-color": "8.1.1",
+        "which": "2.0.2",
+        "wide-align": "1.1.3",
+        "workerpool": "6.1.4",
+        "yargs": "16.2.0",
+        "yargs-parser": "20.2.4",
+        "yargs-unparser": "2.0.0"
+      },
+      "dependencies": {
+        "ansi-colors": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+          "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "argparse": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+          "dev": true
+        },
+        "chalk": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+          "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "7.2.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+              "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+              "dev": true,
+              "requires": {
+                "has-flag": "^4.0.0"
+              }
+            }
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "escape-string-regexp": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+          "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+          "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^6.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "js-yaml": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+          "dev": true,
+          "requires": {
+            "argparse": "^2.0.1"
+          }
+        },
+        "locate-path": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+          "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^5.0.0"
+          }
+        },
+        "log-symbols": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+          "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^4.1.0",
+            "is-unicode-supported": "^0.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+          "dev": true
+        },
+        "p-limit": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+          "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+          "dev": true,
+          "requires": {
+            "yocto-queue": "^0.1.0"
+          }
+        },
+        "p-locate": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+          "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^3.0.2"
+          }
+        },
+        "serialize-javascript": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
+          "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
+          "dev": true,
+          "requires": {
+            "randombytes": "^2.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "8.1.1",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+          "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "20.2.4",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+          "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+          "dev": true
+        }
+      }
+    },
+    "mochapack": {
+      "version": "1.1.15",
+      "resolved": "https://registry.npmjs.org/mochapack/-/mochapack-1.1.15.tgz",
+      "integrity": "sha512-/gOsgJk3CWlNiOdef7hrNhp37VpatB9IiWzSCxS2p8pG21R7NAKJBBsU5T0eUWT9oz1NQhyubXdQgh51U7oVZA==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime-corejs2": "^7.0.0",
+        "chalk": "^2.4.2",
+        "chokidar": "^2.0.0",
+        "glob-parent": "5.1.0",
+        "globby": "^10.0.1",
+        "interpret": "^1.2.0",
+        "is-glob": "^4.0.1",
+        "loader-utils": "^1.2.3",
+        "lodash": "^4.17.15",
+        "memory-fs": "^0.4.1",
+        "minimatch": "^3.0.4",
+        "nodent-runtime": "^3.2.1",
+        "normalize-path": "^3.0.0",
+        "progress": "^2.0.3",
+        "source-map-support": "^0.5.13",
+        "toposort": "^2.0.2",
+        "yargs": "14.0.0"
+      },
+      "dependencies": {
+        "@nodelib/fs.stat": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+          "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+          "dev": true
+        },
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          },
+          "dependencies": {
+            "normalize-path": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+              "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+              "dev": true,
+              "requires": {
+                "remove-trailing-separator": "^1.0.1"
+              }
+            }
+          }
+        },
+        "array-union": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+          "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+          "dev": true
+        },
+        "binary-extensions": {
+          "version": "1.13.1",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+          "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+          "dev": true
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        },
+        "chokidar": {
+          "version": "2.1.8",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+          "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+          "dev": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "glob-parent": "^3.1.0",
+            "inherits": "^2.0.3",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^4.0.0",
+            "normalize-path": "^3.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.2.1",
+            "upath": "^1.1.1"
+          },
+          "dependencies": {
... 14627 lines suppressed ...


[iotdb-web-workbench] 25/34: iotdb-web-workbench 1.1.0 verson code (#10)

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 77e581d0d937f8d66475d70214dee5646370eee1
Author: zhengqiang-cisdi <lo...@qq.com>
AuthorDate: Tue Jan 11 08:58:29 2022 +0800

    iotdb-web-workbench 1.1.0 verson code (#10)
    
    * Add German translation
    
    * fix(pages)删除deep选择器warning
    
    * feat(project)vue升级到vue3.2
    
    * 导入导出csv模块
    
    * 1.增加物理量数据的删改查接口2.修改csv模块
    
    * feat(docs)添加apache 许可注释
    
    * 1.获取设备列表接口变更2.增加判断设备是否存在的接口
    
    * 将存储组、实体和物理量改为全路径名
    
    * 增加获取iotdb统计信息的接口
    
    * 变更“新增或编辑实体”接口
    
    * 变更“获取指定设备下的物理量详情”接口
    
    * 变更“获取指定物理量的最新两百条数据记录”接口
    
    * 增加"随机导入物理量数据"接口
    
    * 1.完善"随机导入物理量数据"接口;2.解决由于存在子实体引起的一些问题
    
    * 增加"导出指定实体下的物理量数据"接口
    
    * 增加角色相关的部分接口
    
    * 增加角色相关接口
    
    * 修改了“新增或编辑实体”接口
    
    * 修改"获取指定实体下的物理量数据"接口,以满足不同的时间范围条件
    
    * 数据连接切图
    
    * 修改"导出指定实体下的物理量数据"接口
    
    * 增加"获取iotdb数据模型"接口
    
    * 修改“获取指定设备下的物理量详情”接口
    
    * 添加spotless插件,格式化代码
    
    * 1.增加获取用户/角色权限管理权限接口;2.优化部分错误码提示
    
    * 1.增加修改用户/角色权限管理权限接口
    
    * 优化连接池和结果集的关闭
    
    * feat(指令): elementPlus全局组件注册
    
    * feat(用户角色): 部分页面完成
    
    * feat(lefttree)add page left menu tree
    
    * 添加获取数据管理权限相关接口
    
    * feat(用户角色): api接口更新
    
    * 添加修改数据管理权限相关接口
    
    * feat(用户角色): 部分接口对接
    
    * 1.1权限管理权限联调&&账号权限截图
    
    * feat(角色): 用户管理权限弹窗完成
    
    * feat(treemenu):support twin tab
    
    * fix(lefttree)add child device new button
    
    * 增加获取用户所有权限管理权限的接口
    
    * feat(element): 全局tag样式新增el-tag-deep-green
    
    * feat(用户角色): 数据管理权限列表
    
    * feat(用户角色): 展示态修改
    
    * feat(element): checkbox pager 样式
    
    * feat(权限): 前端限制权限添加
    
    * 修复ttl单位的bug
    
    * fix(menutree): fix menutree icon
    
    * fix(#9628): 标签可以为空
    
    * feat(styleint): deep不报错
    
    * feat(实体): eslint stylelint修复
    
    * fix(logo): fix logo png
    
    * fix(style): fix page style
    
    * fix(style): tab color fix
    
    * popconfirm 英文
    
    * 修复编辑物理量的bug
    
    * fix(style): tab css global error  fix
    
    * feat(menu): add feedback menu entry
    
    * fix(query btn):fix create query btn bug
    
    * fix(sql): 运行结果统计修改
    
    Co-authored-by: wangdan-cisdi <47...@qq.com>
    Co-authored-by: huangrui <hu...@163.com>
    Co-authored-by: wenjin <12...@qq.com>
    Co-authored-by: julian <j....@pragmaticminds.de>
    Co-authored-by: qhy <97...@qq.com>
    Co-authored-by: qhy <qh...@163.com>
    Co-authored-by: benqhy <85...@users.noreply.github.com>
    Co-authored-by: shuhong.liu <01...@cisdi.com.cn>
    Co-authored-by: curiosityLiu <81...@qq.com>
    Co-authored-by: Xiangdong Huang <hx...@apache.org>
---
 .gitignore                                         |  118 +-
 README.md                                          |   33 +-
 backend/Dockerfile                                 |    7 -
 backend/README.md                                  |    8 -
 backend/doc/config.md                              |   48 -
 backend/doc/image/welcome.PNG                      |  Bin 0 -> 26247 bytes
 backend/doc/intro.md                               |    8 +-
 backend/doc/note.md                                |   37 +-
 backend/gradle/wrapper/gradle-wrapper.jar          |  Bin 0 -> 59203 bytes
 backend/gradle/wrapper/gradle-wrapper.properties   |    5 +
 backend/pom.xml                                    |   35 +-
 .../org/apache/iotdb/admin/AdminApplication.java   |    3 +-
 .../iotdb/admin/aop/BaseExceptionAdvice.java       |    4 +-
 .../apache/iotdb/admin/aop/ParamValidAspect.java   |    7 +-
 .../apache/iotdb/admin/common/ScheduledTask.java   |   64 +
 .../admin/common/exception/BaseException.java      |    1 -
 .../iotdb/admin/common/exception/ErrorCode.java    |  392 ++-
 .../admin/common/utils/AuthenticationUtils.java    |    2 +-
 .../DeviceDTO.java => config/FileProperties.java}  |   25 +-
 .../apache/iotdb/admin/config/FilterConfig.java    |    3 +-
 .../iotdb/admin/config/MybatisPlusConfig.java      |   10 +-
 .../apache/iotdb/admin/config/SecurityConfig.java  |    3 +-
 .../apache/iotdb/admin/config/SwaggerConfig.java   |   10 +-
 .../iotdb/admin/config/ValidatorConfiguration.java |    2 +-
 .../admin/controller/ConnectionController.java     |   25 +-
 .../iotdb/admin/controller/FileController.java     |  131 +
 .../iotdb/admin/controller/HealthController.java   |    7 +-
 .../iotdb/admin/controller/IotDBController.java    |  889 ++++--
 .../iotdb/admin/controller/QueryController.java    |   30 +-
 .../iotdb/admin/controller/UserController.java     |   37 +-
 .../java/org/apache/iotdb/admin/demo/JDBC.java     |  152 -
 .../org/apache/iotdb/admin/demo/NativeAPI.java     |  113 -
 .../org/apache/iotdb/admin/filter/TokenFilter.java |    2 -
 .../vo/DeviceVO.java => mapper/RoleMapper.java}    |   17 +-
 .../{CountDTO.java => AuthorityPrivilegeDTO.java}  |    7 +-
 .../iotdb/admin/model/dto/ConnectionDTO.java       |   20 +-
 .../org/apache/iotdb/admin/model/dto/CountDTO.java |    1 -
 .../dto/{SearchDTO.java => DataDeleteDTO.java}     |   12 +-
 .../dto/{SearchDTO.java => DataQueryDTO.java}      |   13 +-
 .../dto/{DeviceInfoDTO.java => DataUpdateDTO.java} |   18 +-
 .../apache/iotdb/admin/model/dto/DeviceDTO.java    |   15 +
 .../iotdb/admin/model/dto/DeviceInfoDTO.java       |    8 +-
 .../org/apache/iotdb/admin/model/dto/GroupDTO.java |    4 +-
 .../apache/iotdb/admin/model/dto/IotDBRole.java    |   11 +-
 .../apache/iotdb/admin/model/dto/IotDBUser.java    |   13 +-
 .../iotdb/admin/model/dto/MeasurementDTO.java      |    1 -
 .../iotdb/admin/model/dto/PrivilegeInfoDTO.java    |    3 +-
 .../{DeviceInfoDTO.java => RandomImportDTO.java}   |   22 +-
 .../model/dto/{CountDTO.java => RoleGrantDTO.java} |    8 +-
 .../apache/iotdb/admin/model/dto/SearchDTO.java    |    2 +-
 .../model/dto/{CountDTO.java => UserGrantDTO.java} |    8 +-
 .../iotdb/admin/model/entity/Connection.java       |   28 +-
 .../apache/iotdb/admin/model/entity/Device.java    |   10 +-
 .../iotdb/admin/model/entity/Measurement.java      |    4 +-
 .../org/apache/iotdb/admin/model/entity/Query.java |    4 +-
 .../model/entity/{Measurement.java => Role.java}   |   13 +-
 .../iotdb/admin/model/entity/StorageGroup.java     |    8 +-
 .../org/apache/iotdb/admin/model/entity/User.java  |    8 +-
 .../org/apache/iotdb/admin/model/vo/BaseVO.java    |    6 +-
 .../org/apache/iotdb/admin/model/vo/ConnVO.java    |    6 +-
 .../apache/iotdb/admin/model/vo/ConnectionVO.java  |    1 -
 .../model/vo/{QueryVO.java => DataCountVO.java}    |    9 +-
 .../model/vo/{MeasurementVO.java => DataInfo.java} |    9 +-
 .../vo/{GroupInfoVO.java => DataModelVO.java}      |   41 +-
 .../DataPrivilegeVO.java}                          |   14 +-
 .../model/vo/{SqlResultVO.java => DataVO.java}     |    9 +-
 .../apache/iotdb/admin/model/vo/DeviceInfo.java    |    3 +-
 .../apache/iotdb/admin/model/vo/DeviceInfoVO.java  |    1 -
 .../org/apache/iotdb/admin/model/vo/DeviceVO.java  |    1 -
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |    1 -
 .../org/apache/iotdb/admin/model/vo/GroupVO.java   |    1 -
 .../{MeasuremtnInfoVO.java => ImportDataVO.java}   |   16 +-
 .../apache/iotdb/admin/model/vo/MeasurementVO.java |    7 +-
 .../iotdb/admin/model/vo/MeasuremtnInfoVO.java     |    1 -
 .../vo/{MeasuremtnInfoVO.java => NodeTreeVO.java}  |   19 +-
 .../org/apache/iotdb/admin/model/vo/QueryVO.java   |    1 -
 .../org/apache/iotdb/admin/model/vo/RecordVO.java  |    7 +-
 .../admin/model/vo/{DeviceVO.java => RoleVO.java}  |   11 +-
 .../apache/iotdb/admin/model/vo/SqlResultVO.java   |    2 -
 .../iotdb/admin/model/vo/StorageGroupVO.java       |    1 -
 .../model/vo/{RecordVO.java => UserRolesVO.java}   |    8 +-
 .../iotdb/admin/service/ConnectionService.java     |    1 -
 .../apache/iotdb/admin/service/DeviceService.java  |    1 -
 .../service/{UserService.java => FileService.java} |   11 +-
 .../apache/iotdb/admin/service/GroupService.java   |    1 -
 .../apache/iotdb/admin/service/IotDBService.java   |   88 +-
 .../iotdb/admin/service/MeasurementService.java    |    1 -
 .../apache/iotdb/admin/service/QueryService.java   |    3 +-
 .../service/{UserService.java => RoleService.java} |   12 +-
 .../apache/iotdb/admin/service/UserService.java    |    1 -
 .../admin/service/impl/ConnectionServiceImpl.java  |   16 +-
 .../admin/service/impl/DeviceServiceImpl.java      |    2 +-
 .../iotdb/admin/service/impl/FileServiceImpl.java  |   77 +
 .../iotdb/admin/service/impl/GroupServiceImpl.java |    3 -
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 3010 +++++++++++++-------
 .../admin/service/impl/MeasurementServiceImpl.java |    4 +-
 .../iotdb/admin/service/impl/QueryServiceImpl.java |    4 +-
 .../iotdb/admin/service/impl/RoleServiceImpl.java  |   99 +
 .../org/apache/iotdb/admin/tool/ExportCsv.java     |  214 ++
 .../org/apache/iotdb/admin/tool/ImportCsv.java     |  388 +++
 .../src/main/resources/application-dev.properties  |   19 +-
 .../src/main/resources/application-prod.properties |   17 +-
 .../src/main/resources/application-test.properties |    9 +-
 backend/src/main/resources/application.properties  |    2 +-
 backend/src/main/resources/banner.txt              |    8 +
 backend/src/main/resources/file/template.csv       |   34 +
 backend/src/main/resources/log4j2-prod.xml         |    3 +-
 backend/src/main/resources/log4j2.xml              |    3 +-
 backend/src/main/resources/sqlite/iotdb.db         |  Bin 36864 -> 36864 bytes
 .../test/java/org/apache/iotdb/admin/DemoJDBC.java |   38 -
 .../admin/controller/ConnectionControllerTest.java |    1 -
 .../admin/controller/IotDBControllerTest.java      |    1 -
 .../admin/controller/QueryControllerTest.java      |    2 -
 ...ControllerTest.java => UserControllerTest.java} |   52 +-
 frontend/.eslintignore                             |    2 +-
 frontend/.eslintrc.js                              |    2 +-
 frontend/.prettierrc.js                            |    3 +-
 frontend/.stylelintrc.js                           |    4 +-
 frontend/babel.config.js                           |    2 +-
 frontend/package-lock.json                         | 1175 ++++----
 frontend/package.json                              |    8 +-
 frontend/public/iconfont.js                        |   77 +-
 frontend/public/index.html                         |   19 -
 frontend/src/App.vue                               |   34 +-
 frontend/src/assets/data.png                       |  Bin 0 -> 908 bytes
 frontend/src/assets/device.png                     |  Bin 0 -> 598 bytes
 frontend/src/assets/logo.png                       |  Bin 7465 -> 4184 bytes
 frontend/src/assets/storage.png                    |  Bin 0 -> 1178 bytes
 frontend/src/components/Echarts.vue                |   32 +-
 frontend/src/components/FormTable.vue              |  188 +-
 frontend/src/components/HelloWorld.vue             |   32 +-
 frontend/src/components/StandTable.vue             |  384 ++-
 frontend/src/components/TreeSelect.vue             |  196 ++
 frontend/src/directive/icon.js                     |    2 +-
 frontend/src/directive/index.js                    |    2 +-
 frontend/src/i18n/cn.js                            |  157 +-
 frontend/src/i18n/de.js                            |  131 +-
 frontend/src/i18n/en.js                            |  550 ++--
 frontend/src/i18n/index.js                         |    2 +-
 frontend/src/lib/Button.vue                        |   21 +
 frontend/src/main.js                               |    6 +-
 frontend/src/plugins/element_plus.js               |  168 ++
 frontend/src/plugins/event_bus.js                  |    6 +
 frontend/src/plugins/index.js                      |   12 +
 frontend/src/router/index.js                       |   16 +-
 frontend/src/shims-vue.d.ts                        |   19 -
 frontend/src/store/dataBaseM/index.js              |   41 +-
 frontend/src/store/index.js                        |   21 +-
 frontend/src/store/moduleA/index.js                |    2 +-
 frontend/src/store/storage/index.js                |    2 +-
 frontend/src/styles/element.scss                   |  150 +-
 frontend/src/styles/reset.scss                     |    9 +-
 frontend/src/styles/variables.scss                 |    8 +-
 frontend/src/util/api_axios.js                     |    2 +-
 frontend/src/util/axios.js                         |   10 +-
 frontend/src/util/constant.js                      |    6 +
 frontend/src/util/export.js                        |   31 +
 frontend/src/util/setOperation.js                  |   33 +
 frontend/src/views/About/index.vue                 |   43 +-
 .../views/DataBaseM/components/dataListTree.vue    |  212 +-
 .../src/views/DataBaseM/components/iconTypes.vue   |   54 +-
 .../src/views/DataBaseM/hooks/useElementResize.js  |    2 +-
 frontend/src/views/DataBaseM/index.vue             |  113 +-
 frontend/src/views/Device/api/index.js             |   10 +-
 frontend/src/views/Device/index.vue                |  204 +-
 frontend/src/views/DeviceMessage/api/index.js      |   46 +-
 .../src/views/DeviceMessage/components/action.vue  |   72 +-
 frontend/src/views/DeviceMessage/index.vue         |  957 ++++++-
 frontend/src/views/Home.vue                        |   34 +-
 frontend/src/views/Login/index.vue                 |   71 +-
 frontend/src/views/Root/hooks/useLangSwitch.js     |    8 +-
 frontend/src/views/Root/index.vue                  |   49 +-
 frontend/src/views/Source/api/index.js             |  110 +
 frontend/src/views/Source/components/dataModal.vue |  189 ++
 .../src/views/Source/components/dataModalAll.vue   |  326 +++
 frontend/src/views/Source/components/empty.vue     |   40 +-
 frontend/src/views/Source/components/newSource.vue |   55 +-
 .../src/views/Source/components/permitDialog.vue   |  541 ++++
 .../views/Source/components/role/AuthManage.vue    |  398 +++
 .../views/Source/components/role/DataManage.vue    |  409 +++
 .../Source/components/role/DialogGrantUser.vue     |  211 ++
 .../src/views/Source/components/role/Index.vue     |   50 +
 .../views/Source/components/role/PowerManage.vue   |  101 +
 .../src/views/Source/components/role/RoleInfo.vue  |  191 ++
 .../src/views/Source/components/role/RoleList.vue  |  270 ++
 .../src/views/Source/components/roleDialog.vue     |  228 ++
 frontend/src/views/Source/components/treeData.vue  |  351 +++
 frontend/src/views/Source/index.vue                | 1759 ++++++++----
 frontend/src/views/SqlSerch/api/index.js           |   25 +-
 .../src/views/SqlSerch/components/codemirror.vue   |   81 +-
 .../src/views/SqlSerch/components/eltooltip.vue    |   34 +-
 .../src/views/SqlSerch/components/formserch.vue    |   36 +-
 .../views/SqlSerch/components/formserchData.vue    |   56 +-
 .../src/views/SqlSerch/components/sqlDrawer.vue    |   75 +-
 frontend/src/views/SqlSerch/hooks/codemirror.js    |    2 +-
 frontend/src/views/SqlSerch/hooks/function.js      |    2 +-
 frontend/src/views/SqlSerch/hooks/keywords.js      |   52 +-
 frontend/src/views/SqlSerch/hooks/selectList.js    |    2 +-
 .../src/views/SqlSerch/hooks/useElementResize.js   |    3 +-
 frontend/src/views/SqlSerch/index.vue              |  174 +-
 frontend/src/views/storage/index.vue               |  224 +-
 frontend/src/views/storage/newStorage.vue          |   65 +-
 frontend/tests/unit/example.spec.js                |   19 -
 frontend/vue.config.js                             |    4 +-
 package-lock.json                                  |    3 +
 205 files changed, 13317 insertions(+), 4978 deletions(-)

diff --git a/.gitignore b/.gitignore
index a0b9c7b..73dfeae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,109 +1,13 @@
-**/*.pid
-**/gc.log*
-**/logs/*
-**/lib/**
-**/data/**
-
-# Python runtime file
-**/__pycache__/**
-
-# Eclipse IDE files
-**/.classpath
-**/.project
-**/.settings/
-# src/main/resources/
-# intellij IDE files
-**/*.iml
-**/.idea/
-**/*.log
-**/*.ipr
-**/*.iws
-# Apple OS X related
-**/.DS_Store
-derby-tsfile-db
-
-# build generated
-**/target/
-
-# intermediately generated locally
-
-tsfile-timeseries/src/main/resources/logback.out.out.xml
-tsfile-timeseries/src/main/resources/logback.out.xml
-tsfile-service/derby-tsfile-db/
-tsfile-timeseries/src/test/resources/data
-src/main/resources/metadata/mlog.txt
-tsfile-jdbc/src/main/resources/output/queryRes.csv
-
-*.txt
-
-*.jar
-*.gz
-*.tar.gz
-*.tar
-#src/test/resources/logback.xml
-
-### CSV ###
+.gradle
+.gradle/
+gradle/
+build/
+.idea/
+.mvn/
+*.iml
 *.csv
-### Maven ###
-grafana/target/
-!grafana/.mvn/wrapper/maven-wrapper.jar
-grafana/.mvn/
-
-grafana/logs/
-*.log
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-
-
-### NetBeans ###
-**/nbproject/private/
-**/nbbuild/
-**/dist/
-**/nbdist/
-**/.nb-gradle/
-grafana/data/
-
-### vscode project
-**/.vscode/
-
-
-grafana/data/test.csv
-**/lib/
-/target/
-*.tsfile
-tsfile/src/test/resources/*.ts
-
-### Apache release ###
-local-snapshots-dir/
-venv/
-
-partitions.tmp
-partitions
-node_identifier
-
-### temporary file of the distributed version ###
-remote/
-
-# gitpod
-.theia/
-
-classes/
-
-### Cmake files ###
-*.cmake
-Makefile
-**/CMakeFiles/
-
-### cluster test data
-node1/
-node2/
-node3/
+!template.csv
+*.txt
+target/
+*.versionsBackup
 
-# Exclude copied license
-/client-py/LICENSE
diff --git a/README.md b/README.md
index 6d6c312..c2a9c75 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,24 @@
-<!--
+[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
+[![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/loveher147/iotdb-admin/releases)
+![](https://img.shields.io/badge/java--language-1.8-blue.svg)
 
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
+# IoTDB-Workbench
 
-        http://www.apache.org/licenses/LICENSE-2.0
+IoTDB-Workbench是IoTDB的可视化管理工具,可对IoTDB的数据进行增删改查、权限控制等,简化IoTDB的使用及学习成本。
+在我们心中IoTDB是最棒的时序数据库之一,我们将一直不遗余力地推动国产时序数据库IoTDB的应用和发展,为本土开源能力的提高、开源生态的发展,贡献自己的力量,欢迎大家加入IoTDB-Workbench的开发及维护,期待你的加入:
 
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
+![微信](backend/doc/image/wechat.png)
 
--->
+## 后端服务运行
+
+[后端服务设计及运行说明](backend/README.md)
+
+## 前端服务运行
+
+[前端服务运行说明](frontend/README.md)
 
-[English](./README.md) | [中文](./README_zh.md)
 
-# Overview
 
-This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
 
 ## Docker
 
diff --git a/backend/Dockerfile b/backend/Dockerfile
index 62723a4..cccb7ff 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -17,13 +17,6 @@
 # under the License.
 #
 
-FROM maven:3.8.2-amazoncorretto-8 as builder
-
-WORKDIR /app
-
-COPY . .
-
-RUN mvn package
 
 
 
diff --git a/backend/README.md b/backend/README.md
index 63d3d6e..2e5c067 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -23,14 +23,6 @@
 
 [IoTDB-Workbench快速入门](doc/intro.md)
 
-## Building the Backend
-
-The backend can be built using maven by using
-
-```
-mvn clean install
-```
-
 ## 开发环境搭建
 
 [Maven配置](doc/maven.md)
diff --git a/backend/doc/config.md b/backend/doc/config.md
deleted file mode 100644
index bd1b453..0000000
--- a/backend/doc/config.md
+++ /dev/null
@@ -1,48 +0,0 @@
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-
--->
-
-# 配置中心 Apollo
-
-##接入步骤
-1. 添加依赖 ,在pom.xml 中添加依赖,如不需要apolo,可以去掉该依赖
-
-```xml
-<dependency>
-  <groupId>com.ctrip.framework.apollo</groupId>
-  <artifactId>apollo-client</artifactId>
-  <version>1.2.0</version>
-</dependency>
-```
-
-版本号请使用1.2.0,服务器版本xxx
-
-2. 在application.properties文件中增加必要配置
-
-```properties
-    #配置中心服务地址
-    apollo.meta=http://192.168.1.241:8081
-    #开启配置中心
-    apollo.bootstrap.enabled=true
-    # 采用配置的形式注入命名空间application
-    apollo.bootstrap.namespaces=application
-```
-
-3. 编写读取配置的类。参考bean包下面的TestBean类。
diff --git a/backend/doc/image/welcome.PNG b/backend/doc/image/welcome.PNG
new file mode 100644
index 0000000..1eac27b
Binary files /dev/null and b/backend/doc/image/welcome.PNG differ
diff --git a/backend/doc/intro.md b/backend/doc/intro.md
index b57f038..7984784 100644
--- a/backend/doc/intro.md
+++ b/backend/doc/intro.md
@@ -49,7 +49,9 @@
 项目提供maven、gradle两种构建工具,以maven为例启动项目:  
 首先通过IntelliJ IDEA打开本项目,右键点击pom.xml,点击Add as Maven Project导入项目相关依赖。
 ![](image/pom.PNG)  
-导入完成后启动AdminApplication项目,如果未报错并出现如下界面则代表项目运行成功。  
+导入完成后启动AdminApplication项目,启动成功后你应该能看到如下界面。  
 ![](image/启动成功.PNG)  
-本系统默认登录用户为root,密码为123456。  
-具体部署步骤请参考[部署文档](deploy.md)
\ No newline at end of file
+接着,你可以通过浏览器访问127.0.0.1:8080/api/,看到如下页面则代表后端启动成功。
+![](image/welcome.PNG)  
+具体部署步骤请参考[部署文档](deploy.md)  
+本系统默认登录用户为root,密码为123456。  
\ No newline at end of file
diff --git a/backend/doc/note.md b/backend/doc/note.md
index 16f74b0..5c9312e 100644
--- a/backend/doc/note.md
+++ b/backend/doc/note.md
@@ -23,29 +23,29 @@
 
 ```java
 /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT 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 to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
 
 package org.apache.iotdb.xxx;
 
 import org.apache.iotdb.xxx;
 import org.apache.iotdb.rpc.xxx;
-import org.apache.iotdb.service.rpc.xxx;
+import org.apache.iotdb.service.rpc.xxx;
 
 import org.apache.thrift.xxx;
 
@@ -70,5 +70,4 @@ import java.util.Map;
 排列整齐 不同层级之间用空格分开
 
 ## 注释
-
 注释使用英文注释
diff --git a/backend/gradle/wrapper/gradle-wrapper.jar b/backend/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/backend/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/backend/gradle/wrapper/gradle-wrapper.properties b/backend/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..da9702f
--- /dev/null
+++ b/backend/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/backend/pom.xml b/backend/pom.xml
index 63f9921..45d3bea 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -19,7 +19,7 @@
   -->
 
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.springframework.boot</groupId>
@@ -32,10 +32,9 @@
   <version>1.0.0</version>
   <packaging>jar</packaging>
   <name>IoTDB Workbench</name>
-  <description>Apache IoTDB Workbench开源项目</description>
+  <description>Apache IoTDB Workbench</description>
 
   <properties>
-    <!-- 对应java 1.8,如果编译错误,可能需要调整 -->
     <java.version>1.8</java.version>
     <skipTests>true</skipTests>
     <spotless.version>2.4.2</spotless.version>
@@ -66,36 +65,30 @@
       <artifactId>spring-boot-starter-security</artifactId>
     </dependency>
 
-    <!--sqlite驱动-->
     <dependency>
       <groupId>org.xerial</groupId>
       <artifactId>sqlite-jdbc</artifactId>
       <version>3.34.0</version>
     </dependency>
 
-    <!--jwt-->
     <dependency>
       <groupId>com.auth0</groupId>
       <artifactId>java-jwt</artifactId>
       <version>3.4.0</version>
     </dependency>
 
-    <!-- get set方法自动生成 -->
     <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <optional>true</optional>
     </dependency>
 
-    <!-- mybatis-plus -->
     <dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.4.0</version>
     </dependency>
-    <!-- 数据库结束 -->
 
-    <!-- 常用工具库 -->
     <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>fastjson</artifactId>
@@ -107,10 +100,8 @@
       <artifactId>commons-lang3</artifactId>
       <version>3.11</version>
     </dependency>
-    <!-- 常用工具库结束 -->
 
 
-    <!-- spring单元测试 -->
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
@@ -127,9 +118,7 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
-    <!-- spring单元测试结束 -->
 
-    <!-- swagger 组件,用于自动生成api接口文档 -->
     <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger2</artifactId>
@@ -140,9 +129,7 @@
       <artifactId>springfox-swagger-ui</artifactId>
       <version>2.7.0</version>
     </dependency>
-    <!-- swagger 组件结束-->
 
-    <!-- 校验框架-->
     <dependency>
       <groupId>org.hibernate.validator</groupId>
       <artifactId>hibernate-validator</artifactId>
@@ -154,12 +141,11 @@
       <artifactId>aspectjweaver</artifactId>
       <version>1.9.6</version>
     </dependency>
-    <!-- 校验框架结束-->
 
     <dependency>
       <groupId>org.apache.iotdb</groupId>
       <artifactId>iotdb-session</artifactId>
-      <version>0.12.0</version>
+      <version>0.12.1</version>
       <exclusions>
         <exclusion>
           <artifactId>logback-classic</artifactId>
@@ -171,7 +157,7 @@
     <dependency>
       <groupId>org.apache.iotdb</groupId>
       <artifactId>iotdb-jdbc</artifactId>
-      <version>0.12.0</version>
+      <version>0.12.1</version>
       <exclusions>
         <exclusion>
           <artifactId>logback-classic</artifactId>
@@ -195,17 +181,7 @@
           </execution>
         </executions>
       </plugin>
-      <!--https://blog.csdn.net/eguid/article/details/78291497-->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.8.1</version>
-        <configuration>
-          <verbose>true</verbose>
-          <fork>true</fork>
-          <executable>${JAVA_HOME}/bin/javac</executable>
-        </configuration>
-      </plugin>
+
       <plugin>
         <groupId>org.apache.rat</groupId>
         <artifactId>apache-rat-plugin</artifactId>
@@ -220,6 +196,7 @@
           </execution>
         </executions>
       </plugin>
+
       <plugin>
         <groupId>com.diffplug.spotless</groupId>
         <artifactId>spotless-maven-plugin</artifactId>
diff --git a/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java b/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
index 9ac6ffd..2795859 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
@@ -22,12 +22,13 @@ package org.apache.iotdb.admin;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 
-/** 后端代码启动类 1. MapperScan需要配置为mapper所在的包,自动扫描mapper,MapperScan是用于数据库组件自动扫描使用的。 */
 @SpringBootApplication
 @MapperScan("org.apache.iotdb.admin.mapper")
 @EnableWebSecurity
+@EnableScheduling
 public class AdminApplication {
 
   public static void main(String[] args) {
diff --git a/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java b/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
index 0f76a83..bd4fee0 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
@@ -27,7 +27,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseBody;
 
-/** 通用异常处理拦截器 */
+/** Global exception handler */
 @Slf4j
 @ControllerAdvice
 public class BaseExceptionAdvice {
@@ -35,7 +35,7 @@ public class BaseExceptionAdvice {
   @ExceptionHandler(BaseException.class)
   @ResponseBody
   public BaseVO handleBaseException(BaseException e) {
-    log.error("调用接口异常", e);
+    log.error("Base exception:", e);
     BaseVO result = new BaseVO(e.getErrorCode(), e.getMessage(), null);
     return result;
   }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java b/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
index f58767f..a12ab6c 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
@@ -36,7 +36,6 @@ import javax.validation.Validator;
 
 import java.util.Set;
 
-/** 参数验证 */
 @Aspect
 @Slf4j
 @Component
@@ -44,11 +43,10 @@ public class ParamValidAspect {
 
   @Autowired private Validator validator;
 
-  /** 定义校验包的未知 */
+  /** Define the location of the package to be verified */
   @Pointcut("execution(* org.apache.iotdb.admin.controller..*.*(..))")
   public void pointcut() {}
 
-  /** 处理参数校验错误的具体方法,抛出异常组件中的异常,遵循异常规范 */
   @Around("pointcut()")
   public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
     Object[] args = pjp.getArgs();
@@ -59,10 +57,9 @@ public class ParamValidAspect {
           for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
             Path property = constraintViolation.getPropertyPath();
             String name = property.iterator().next().getName();
-            // 打印具体异常信息,对应校验框架注解中的message
             log.error("[" + name + "]" + constraintViolation.getMessage());
             throw new BaseException(
-                ErrorCode.WRONG_PARAM, "参数错误:" + constraintViolation.getMessage());
+                ErrorCode.WRONG_PARAM, "Parameter error:" + constraintViolation.getMessage());
           }
         }
       }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/ScheduledTask.java b/backend/src/main/java/org/apache/iotdb/admin/common/ScheduledTask.java
new file mode 100644
index 0000000..bbc635e
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/ScheduledTask.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.common;
+
+import org.apache.iotdb.admin.config.FileProperties;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/** Periodically delete files generated during CSV import and export */
+@Slf4j
+@Component
+public class ScheduledTask {
+  private final Path fileStorageLocation;
+
+  private final File fileStorageDirectory;
+
+  @Autowired
+  public ScheduledTask(FileProperties fileProperties) {
+    fileStorageLocation = Paths.get(fileProperties.getTempDir()).toAbsolutePath().normalize();
+    fileStorageDirectory = new File(fileStorageLocation.toString());
+    try {
+      Files.createDirectories(fileStorageLocation);
+    } catch (Exception e) {
+      log.error("Could not create the directory:" + fileStorageLocation, e);
+      throw new RuntimeException("Could not create the directory:" + fileStorageLocation, e);
+    }
+  }
+
+  @Scheduled(fixedRate = 1000 * 60 * 10L)
+  public void scheduledTask() {
+    File[] files = fileStorageDirectory.listFiles();
+    for (File file : files) {
+      if (file.lastModified() < System.currentTimeMillis() - 1000 * 60 * 10L) {
+        file.delete();
+        log.info("Delete file:" + file.getAbsolutePath());
+      }
+    }
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
index 38c4a20..587605f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.admin.common.exception;
 
-/** 异常类 */
 public class BaseException extends Exception {
 
   private String errorCode;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
index 499ab83..2084338 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
@@ -19,265 +19,401 @@
 
 package org.apache.iotdb.admin.common.exception;
 
-/** 错误码类 */
 public class ErrorCode {
 
-  // 连接相关
+  // Connection
   public static final String ALIAS_REPEAT = "CONN-0001";
-  public static final String ALIAS_REPEAT_MSG = "别名重复";
+  public static final String ALIAS_REPEAT_MSG = "Connection alias already exists";
 
   public static final String INSERT_CONN_FAIL = "CONN-0002";
-  public static final String INSERT_CONN_FAIL_MSG = "添加或更新连接失败";
+  public static final String INSERT_CONN_FAIL_MSG = "Failed to update or create connection";
 
   public static final String DELETE_CONN_FAIL = "CONN-0003";
-  public static final String DELETE_CONN_FAIL_MSG = "删除连接失败";
+  public static final String DELETE_CONN_FAIL_MSG = "Failed to delete connection";
 
   public static final String NO_CONN = "CONN-0004";
-  public static final String NO_CONN_MSG = "连接不存在";
+  public static final String NO_CONN_MSG = "The connection doesn't exist";
 
   public static final String GET_CONN_FAIL = "CONN-0005";
-  public static final String GET_CONN_FAIL_MSG = "获取连接失败";
+  public static final String GET_CONN_FAIL_MSG = "Failed to get connection";
 
   public static final String CHECK_FAIL = "CONN-0006";
-  public static final String CHECK_FAIL_MSG = "没有权限或连接不存在";
+  public static final String CHECK_FAIL_MSG =
+      "The connection doesn't exist or the account doesn't have permissions";
 
   public static final String TEST_CONN_FAIL = "CONN-0007";
-  public static final String TEST_CONN_FAIL_MSG = "连接不可达或连接超时";
-
-  public static final String TEST_CONN_WRONG = "CONN-0008";
-  public static final String TEST_CONN_WRONG_MSG = "连接失败,主机输入不合法";
+  public static final String TEST_CONN_FAIL_MSG = "Unreachable connection";
 
   public static final String TIME_OUT = "CONN-0009";
-  public static final String TIME_OUT_MSG = "连接超时";
+  public static final String TIME_OUT_MSG = "Connection timeout";
 
   public static final String TEST_CONN_FAIL_PWD = "CONN-0010";
-  public static final String TEST_CONN_FAIL_PWD_MSG = "连接失败,用户名或密码错误";
+  public static final String TEST_CONN_FAIL_PWD_MSG = "The user name or password is incorrect";
 
-  // 登录相关
+  // Login
   public static final String LOGIN_FAIL_USER = "USER-0001";
-  public static final String LOGIN_FAIL_USER_MSG = "登录失败,用户不存在";
+  public static final String LOGIN_FAIL_USER_MSG = "The user does not exist";
 
   public static final String USER_EXIST = "USER-0002";
-  public static final String USER_EXIST_MSG = "用户已存在";
+  public static final String USER_EXIST_MSG = "The user name already exists";
 
   public static final String LOGIN_FAIL_PWD = "USER-0003";
-  public static final String LOGIN_FAIL_PWD_MSG = "登录失败,密码错误";
+  public static final String LOGIN_FAIL_PWD_MSG = "Login failed, password is incorrect";
 
   public static final String INSERT_USER_FAIL = "USER-0004";
-  public static final String INSERT_USER_FAIL_MSG = "插入失败";
+  public static final String INSERT_USER_FAIL_MSG = "Failed to create user";
 
   public static final String WRONG_USER_PARAM = "USER-0005";
-  public static final String WRONG_USER_PARAM_MSG = "请输入合法的用户名和密码";
+  public static final String WRONG_USER_PARAM_MSG = "Please enter a valid user name and password";
 
   public static final String DELETE_USER_FAIL = "USER-0006";
-  public static final String DELETE_USER_FAIL_MSG = "删除用户失败";
+  public static final String DELETE_USER_FAIL_MSG = "Failed to delete user";
 
   public static final String NO_USER = "USER-0007";
-  public static final String NO_USER_MSG = "用户未指定";
+  public static final String NO_USER_MSG = "User not specified";
 
   public static final String USER_AUTH_FAIL = "USER-0008";
-  public static final String USER_AUTH_FAIL_MSG = "用户不一致,不能进行操作";
+  public static final String USER_AUTH_FAIL_MSG = "Validation fails, the users are inconsistent";
 
   public static final String TOKEN_ERR = "USER-0009";
-  public static final String TOKEN_ERR_MSG = "请登录或token失效";
+  public static final String TOKEN_ERR_MSG = "No login or token is invalid";
 
   public static final String GET_TOKEN_FAIL = "USER-0010";
-  public static final String GET_TOKEN_FAIL_MSG = "获取token失败";
+  public static final String GET_TOKEN_FAIL_MSG = "Failed to get token";
 
   public static final String SET_JWT_FAIL = "USER-0011";
-  public static final String SET_JWT_FAIL_MSG = "JWT编解码失败";
+  public static final String SET_JWT_FAIL_MSG = "JWT encoding or decoding failed";
+
+  // CSV
+  public static final String FILE_NAME_ILLEGAL = "CSV-0001";
+  public static final String FILE_NAME_ILLEGAL_MSG = "The file must be a CSV file";
+
+  public static final String UPLOAD_FILE_FAIL = "CSV-0002";
+  public static final String UPLOAD_FILE_FAIL_MSG = "Failed to upload the CSV file";
+
+  public static final String FILE_FIRST_LINE_ILLEGAL = "CSV-0003";
+  public static final String FILE_FIRST_LINE_ILLEGAL_MSG =
+      "The CSV file format is incorrect.Please check line 1";
+
+  public static final String FILE_LINE_ILLEGAL = "CSV-0004";
+  public static final String FILE_LINE_ILLEGAL_MSG = "CSV file format error, illegal line:";
+
+  public static final String FILE_FORMAT_ILLEGAL = "CSV-0005";
+  public static final String FILE_FORMAT_ILLEGAL_MSG =
+      "CSV file format error. The number of columns in the data row cannot be smaller than that in the first row";
+
+  public static final String FILE_TIME_ILLEGAL = "CSV-0006";
+  public static final String FILE_TIME_ILLEGAL_MSG =
+      "The timestamp format of the CSV file is incorrect";
+
+  public static final String FILE_IO_FAIL = "CSV-0007";
+  public static final String FILE_IO_FAIL_MSG = "File read or write failed due to:";
+
+  public static final String IMPORT_CSV_FAIL = "CSV-0008";
+  public static final String IMPORT_CSV_FAIL_MSG = "Failed to import CSV file because:";
 
-  // iotDB相关
+  public static final String CREATE_FILE_FAIL = "CSV-0009";
+  public static final String CREATE_FILE_FAIL_MSG = "Failed to create file";
+
+  public static final String EXPORT_CSV_FAIL = "CSV-0010";
+  public static final String EXPORT_CSV_FAIL_MSG = "Failed to export the CSV file because:";
+
+  public static final String FILE_NOT_FOUND = "CSV-0011";
+  public static final String FILE_NOT_FOUND_MSG = "File not found";
+
+  // IoTDB
   public static final String INSERT_TS_FAIL = "IOTDB-0001";
-  public static final String INSERT_TS_FAIL_MSG = "插入时间序列失败";
+  public static final String INSERT_TS_FAIL_MSG = "Failed to create measurement";
 
   public static final String DELETE_TS_FAIL = "IOTDB-0002";
-  public static final String DELETE_TS_FAIL_MSG = "删除时间序列失败";
-
-  public static final String DB_BOOL_WRONG = "IOTDB-0003";
-  public static final String DB_BOOL_WRONG_MSG = "Boolean值输入错误,0为false,1为true";
+  public static final String DELETE_TS_FAIL_MSG = "Failed to delete measurement";
 
   public static final String DB_DATATYPE_WRONG = "IOTDB-0004";
-  public static final String DB_DATATYPE_WRONG_MSG = "TSDataType类型传入错误";
-
-  public static final String GET_DBCONN_FAIL = "IOTDB-005";
-  public static final String GET_DBCONN_FAIL_MSG = "获取数据库连接失败";
+  public static final String DB_DATATYPE_WRONG_MSG = "The data type of measurement is wrong";
 
   public static final String GET_SESSION_FAIL = "IOTDB-0006";
-  public static final String GET_SESSION_FAIL_MSG = "获取session失败";
+  public static final String GET_SESSION_FAIL_MSG = "Failed to connect to IoTDB database";
 
   public static final String CLOSE_DBCONN_FAIL = "IOTDB-0007";
-  public static final String CLOSE_DBCONN_FAIL_MSG = "关闭连接失败";
+  public static final String CLOSE_DBCONN_FAIL_MSG = "Failed to close connection";
 
   public static final String SQL_EP = "IOTDB-0008";
-  public static final String SQL_EP_MSG = "没有权限或sql异常";
-
-  public static final String QUERY_FAIL = "IOTDB-0009";
-  public static final String QUERY_FAIL_MSG = "sql查询失败";
-
-  public static final String SQL_PARAM_WRONG = "IOTDB-0010";
-  public static final String SQL_PARAM_WRONG_MSG = "sql参数不合法";
+  public static final String SQL_EP_MSG = "No privileges or SQL errors";
 
   public static final String WRONG_DB_PARAM = "IOTDB-0011";
-  public static final String WRONG_DB_PARAM_MSG = "输入参数不合法";
-
-  public static final String GET_USER_FAIL = "IOTDB-0012";
-  public static final String GET_USER_FAIL_MSG = "获取用户信息失败";
+  public static final String WRONG_DB_PARAM_MSG = "The input parameter is invalid";
 
   public static final String GET_SQL_ONE_VALUE_FAIL = "IOTDB-0013";
-  public static final String GET_SQL_ONE_VALUE_FAIL_MSG = "获取值失败";
+  public static final String GET_SQL_ONE_VALUE_FAIL_MSG = "Failed to get data value";
 
   public static final String SET_TTL_FAIL = "IOTDB-0014";
-  public static final String SET_TTL_FAIL_MSG = "设置存活时间失败";
-
-  public static final String DEL_TTL_FAIL = "IOTDB-0015";
-  public static final String DEL_TTL_FAIL_MSG = "删除存活时间失败";
+  public static final String SET_TTL_FAIL_MSG = "Failed to set the TTL.";
 
   public static final String GET_SQL_ONE_COLUMN_FAIL = "IOTDB-0016";
-  public static final String GET_SQL_ONE_COLUMN_FAIL_MSG = "获取列表失败";
-
-  public static final String GET_SQL_SET_FAIL = "IOTDB-0017";
-  public static final String GET_SQL_SET_FAIL_MSG = "获取列表集合失败";
-
-  public static final String INSERT_DEV_FAIL = "IOTDB-0018";
-  public static final String INSERT_DEV_FAIL_MSG = "插入实体失败";
+  public static final String GET_SQL_ONE_COLUMN_FAIL_MSG = "Failed to get the data list";
 
   public static final String GET_MSM_FAIL = "IOTDB-0019";
-  public static final String GET_MSM_FAIL_MSG = "获取物理量数据信息失败";
-
-  public static final String NO_SUCH_FIELD = "IOTDB-0020";
-  public static final String NO_SUCH_FIELD_MSG = "返回集没此属性";
-
-  public static final String GET_LAST_VALUE_FAIL = "IOTDB-0021";
-  public static final String GET_LAST_VALUE_FAIL_MSG = "获取物理量最新值失败";
+  public static final String GET_MSM_FAIL_MSG = "Failed to get the measurement information";
 
   public static final String SET_GROUP_FAIL = "IOTDB-0022";
-  public static final String SET_GROUP_FAIL_MSG = "创建存储组失败";
+  public static final String SET_GROUP_FAIL_MSG = "Failed to create storage group";
 
   public static final String DELETE_GROUP_FAIL = "IOTDB-0023";
-  public static final String DELETE_GROUP_FAIL_MSG = "删除存储组失败";
+  public static final String DELETE_GROUP_FAIL_MSG = "Failed to delete storage group";
 
   public static final String DELETE_DB_USER_FAIL = "IOTDB-0024";
-  public static final String DELETE_DB_USER_FAIL_MSG = "删除数据库用户失败";
+  public static final String DELETE_DB_USER_FAIL_MSG = "Failed to delete IoTDB user";
 
   public static final String DELETE_DB_ROLE_FAIL = "IOTDB-0025";
-  public static final String DELETE_DB_ROLE_FAIL_MSG = "删除数据库角色失败";
+  public static final String DELETE_DB_ROLE_FAIL_MSG = "Failed to delete IoTDB role";
 
   public static final String SET_DB_USER_FAIL = "IOTDB-0026";
-  public static final String SET_DB_USER_FAIL_MSG = "创建数据库用户失败";
+  public static final String SET_DB_USER_FAIL_MSG = "Failed to create IoTDB user";
 
   public static final String SET_DB_ROLE_FAIL = "IOTDB-0027";
-  public static final String SET_DB_ROLE_FAIL_MSG = "创建数据库角色或对应权限时失败";
+  public static final String SET_DB_ROLE_FAIL_MSG = "Failed to create IoTDB role";
 
   public static final String NO_TYPE = "IOTDB-0028";
-  public static final String NO_TYPE_MSG = "粒度类型不存在";
-
-  public static final String PRIV_ROOT_FAIL = "IOTDB-0029";
-  public static final String PRIV_ROOT_FAIL_MSG = "根路径权限操作失败";
-
-  public static final String PRIV_GROUP_FAIL = "IOTDB-0030";
-  public static final String PRIV_GROUP_FAIL_MSG = "组路径权限操作失败";
-
-  public static final String PRIV_DEVICE_FAIL = "IOTDB-0031";
-  public static final String PRIV_DEVICE_FAIL_MSG = "实体路径权限操作失败";
-
-  public static final String PRIV_TIMESERIES_FAIL = "IOTDB-0032";
-  public static final String PRIV_TIMESERIES_FAIL_MSG = "物理量路径权限操作失败";
+  public static final String NO_TYPE_MSG = "Privileges type does not exist";
 
   public static final String GET_RECORD_FAIL = "IOTDB-0033";
-  public static final String GET_RECORD_FAIL_MSG = "获取物理量记录失败";
+  public static final String GET_RECORD_FAIL_MSG = "Failed to get the measurement record";
 
   public static final String NO_SQL = "IOTDB-0034";
-  public static final String NO_SQL_MSG = "没有sql执行语句";
+  public static final String NO_SQL_MSG = "The query script has no SQL statements";
 
   public static final String UPDATE_GROUP_INFO_FAIL = "IOTDB-0035";
-  public static final String UPDATE_GROUP_INFO_FAIL_MSG = "更新组信息失败";
+  public static final String UPDATE_GROUP_INFO_FAIL_MSG =
+      "Failed to update the storage group information";
 
   public static final String NO_GROUP_INFO = "IOTDB-0036";
-  public static final String NO_GROUP_INFO_MSG = "不存在存储组信息";
-
-  public static final String NO_GROUP = "IOTDB-0037";
-  public static final String NO_GROUP_MSG = "不存在存储组";
+  public static final String NO_GROUP_INFO_MSG = "The storage group information doesn't exist";
 
   public static final String NO_DEVICE_INFO = "IOTDB-0038";
-  public static final String NO_DEVICE_INFO_MSG = "不存在设备信息";
+  public static final String NO_DEVICE_INFO_MSG = "The entity information doesn't exist";
 
   public static final String UPDATE_PWD_FAIL = "IOTDB-0039";
-  public static final String UPDATE_PWD_FAIL_MSG = "修改账号密码失败";
+  public static final String UPDATE_PWD_FAIL_MSG = "Failed to change the account password";
 
   public static final String NO_QUERY = "IOTDB-0040";
-  public static final String NO_QUERY_MSG = "不存在此查询";
-
-  public static final String NO_ALL_NUM_SEARCH = "IOTDB-0041";
-  public static final String NO_ALL_NUM_SEARCH_MSG = "不支持纯数字查询";
+  public static final String NO_QUERY_MSG = "The query does not exist or has ended";
 
   public static final String NO_PRI_SET_TTL = "IOTDB-0042";
-  public static final String NO_PRI_SET_TTL_MSG = "没有权限设置存活时间";
+  public static final String NO_PRI_SET_TTL_MSG = "No privilege to set the TTL";
 
   public static final String NO_PRI_CREATE_TIMESERIES = "IOTDB-0043";
-  public static final String NO_PRI_CREATE_TIMESERIES_MSG = "没有权限创建物理量";
+  public static final String NO_PRI_CREATE_TIMESERIES_MSG =
+      "No privilege to create the measurement";
 
   public static final String NO_PRI_READ_TIMESERIES = "IOTDB-0044";
-  public static final String NO_PRI_READ_TIMESERIES_MSG = "没有权限查看物理量";
+  public static final String NO_PRI_READ_TIMESERIES_MSG = "No privilege to read the measurement";
 
   public static final String NO_PRI_DELETE_TIMESERIES = "IOTDB-0045";
-  public static final String NO_PRI_DELETE_TIMESERIES_MSG = "没有权限删除物理量";
+  public static final String NO_PRI_DELETE_TIMESERIES_MSG =
+      "No privilege to delete the measurement";
 
   public static final String CONN_REFUSED = "IOTDB-0046";
-  public static final String CONN_REFUSED_MSG = "连接错误,检查输入";
+  public static final String CONN_REFUSED_MSG = "Connecting to IoTDB error";
 
   public static final String WRONG_USER = "IOTDB-0047";
-  public static final String WRONG_USER_MSG = "连接用户名或密码错误";
+  public static final String WRONG_USER_MSG =
+      "The user name or password of connection is incorrect";
 
   public static final String NO_PRI_SET_GROUP = "IOTDB-0048";
-  public static final String NO_PRI_SET_GROUP_MSG = "没有权限操作存储组";
+  public static final String NO_PRI_SET_GROUP_MSG = "No privilege to set the storage group";
 
   public static final String NO_PRI_DELETE_GROUP = "IOTDB-0048";
-  public static final String NO_PRI_DELETE_GROUP_MSG = "没有权限删除存储组";
-
-  public static final String NO_SUPPORT_SQL = "IOTDB-0049";
-  public static final String NO_SUPPORT_SQL_MSG = "不支持此sql执行";
+  public static final String NO_PRI_DELETE_GROUP_MSG = "No privilege to delete the storage group";
 
   public static final String TTL_WRONG = "IOTDB-0050";
-  public static final String TTL_WRONG_MSG = "存活时间必须大于等于0";
+  public static final String TTL_WRONG_MSG = "The TTL must be greater than or equal to 0";
 
   public static final String NO_PRI_TIMESERIES_DATA = "IOTDB-0051";
-  public static final String NO_PRI_TIMESERIES_DATA_MSG = "没有权限查看测点数据";
+  public static final String NO_PRI_TIMESERIES_DATA_MSG =
+      "No privilege to read the measurement data";
 
   public static final String NO_SUP_CONTAIN_ROOT = "IOTDB-0052";
-  public static final String NO_SUP_CONTAIN_ROOT_MSG = "不支持包含\"root\"的输入";
+  public static final String NO_SUP_CONTAIN_ROOT_MSG =
+      "Root must and can only be the beginning of a path";
+
+  public static final String GET_DATA_FAIL = "IOTDB-0053";
+  public static final String GET_DATA_FAIL_MSG = "Failed to get measurement data";
+
+  public static final String UPDATE_DATA_FAIL = "IOTDB-0054";
+  public static final String UPDATE_DATA_FAIL_MSG = "Failed to update measurement data";
+
+  public static final String DELETE_DATA_FAIL = "IOTDB-0055";
+  public static final String DELETE_DATA_FAIL_MSG = "Failed to delete measurement data";
+
+  public static final String GET_DATA_COUNT_FAIL = "IOTDB-0056";
+  public static final String GET_DATA_COUNT_FAIL_MSG = "Failed to obtain data statistics";
+
+  public static final String DB_COMPRESSION_WRONG = "IOTDB-0057";
+  public static final String DB_COMPRESSION_WRONG_MSG =
+      "The compression type is passed in incorrectly";
+
+  public static final String DB_ENCODING_WRONG = "IOTDB-0058";
+  public static final String DB_ENCODING_WRONG_MSG = "The encoding type is passed in incorrectly";
+
+  public static final String UPSERT_ALIAS_FAIL = "IOTDB-0059";
+  public static final String UPSERT_ALIAS_FAIL_MSG =
+      "Failed to set the alias. Please check whether the alias already exists under the current entity";
 
-  // 存储组表相关
+  public static final String UPSERT_TAGS_FAIL = "IOTDB-0060";
+  public static final String UPSERT_TAGS_FAIL_MSG = "Failed to set the tags";
+
+  public static final String UPSERT_ATTRIBUTES_FAIL = "IOTDB-0061";
+  public static final String UPSERT_ATTRIBUTES_FAIL_MSG = "Failed to set the attributes";
+
+  public static final String GET_MEASUREMENT_DATA_COUNT_FAIL = "IOTDB-0062";
+  public static final String GET_MEASUREMENT_DATA_COUNT_FAIL_MSG =
+      "Failed to get measurement data statistics";
+
+  public static final String RANDOM_IMPORT_DATA_FAIL = "IOTDB-0063";
+  public static final String RANDOM_IMPORT_DATA_FAIL_MSG =
+      "Failed to import measurement data randomly";
+
+  public static final String NO_MEASUREMENT = "IOTDB-0064";
+  public static final String NO_MEASUREMENT_MSG = " No measurement, cannot insert data";
+
+  public static final String ROLE_GET_USERS_FAIL = "IOTDB-0065";
+  public static final String ROLE_GET_USERS_FAIL_MSG = "Failed to get the user list for the role";
+
+  public static final String REVOKE_ROLE = "IOTDB-0066";
+  public static final String REVOKE_ROLE_MSG = "Failed to revoke the role of user.";
+
+  public static final String GRANT_ROLE = "IOTDB-0067";
+  public static final String GRANT_ROLE_MSG = "Failed to grant role to the user";
+
+  public static final String NO_PRI_DO_THIS = "IOTDB-0068";
+  public static final String NO_PRI_DO_THIS_MSG = "No privilege to do this";
+
+  public static final String NO_PRI_CREATE_USER = "IOTDB-0069";
+  public static final String NO_PRI_CREATE_USER_MSG = "No privilege to create user";
+
+  public static final String NO_PRI_DELETE_USER = "IOTDB-0070";
+  public static final String NO_PRI_DELETE_USER_MSG = "No privilege to delete user";
+
+  public static final String NO_PRI_CREATE_ROLE = "IOTDB-0071";
+  public static final String NO_PRI_CREATE_ROLE_MSG = "No privilege to create role";
+
+  public static final String NO_PRI_DELETE_ROLE = "IOTDB-0072";
+  public static final String NO_PRI_DELETE_ROLE_MSG = "No privilege to delete role";
+
+  public static final String NO_PRI_LIST_ROLE = "IOTDB-0073";
+  public static final String NO_PRI_LIST_ROLE_MSG = "No privilege to list role";
+
+  public static final String NO_PRI_GRANT_USER_ROLE = "IOTDB-0074";
+  public static final String NO_PRI_GRANT_USER_ROLE_MSG = "No privilege to grant user role";
+
+  public static final String NO_PRI_REVOKE_USER_ROLE = "IOTDB-0075";
+  public static final String NO_PRI_REVOKE_USER_ROLE_MSG = "No privilege to revoke user role";
+
+  public static final String NO_PRI_GRANT_PRIVILEGE = "IOTDB-0076";
+  public static final String NO_PRI_GRANT_PRIVILEGE_MSG = "No privilege to authorize user or role";
+
+  public static final String GET_USER_PRIVILEGE_FAIL = "IOTDB-0080";
+  public static final String GET_USER_PRIVILEGE_FAIL_MSG =
+      "Failed to get user privilege information";
+
+  public static final String GET_ROLE_PRIVILEGE_FAIL = "IOTDB-0081";
+  public static final String GET_ROLE_PRIVILEGE_FAIL_MSG =
+      "Failed to get role privilege information";
+
+  public static final String NOT_SUPPORT_ALL_DIGIT = "IOTDB-0082";
+  public static final String NOT_SUPPORT_ALL_DIGIT_MSG = "The name cannot contain only digits";
+
+  public static final String USER_NAME_EXISTS = "IOTDB-0083";
+  public static final String USER_NAME_EXISTS_MSG = "The user name already exists";
+
+  public static final String ROLE_NAME_EXISTS = "IOTDB-0083";
+  public static final String ROLE_NAME_EXISTS_MSG = "The role name already exists";
+
+  public static final String NO_SUP_CONTAIN_WORD = "IOTDB-0084";
+  public static final String NO_SUP_CONTAIN_WORD_MSG =
+      "As, null, or like cannot be used as a path name";
+
+  public static final String MEASUREMENTS_NAME_CONTAIN_DOT = "IOTDB-0085";
+  public static final String MEASUREMENTS_NAME_CONTAIN_DOT_MSG =
+      "The measurement layer name cannot have multiple layers";
+
+  public static final String MEASUREMENT_NAME_EQUALS_DEVICE = "IOTDB-0086";
+  public static final String MEASUREMENT_NAME_EQUALS_DEVICE_MSG =
+      "The entity name cannot be the same as an existing measurement";
+
+  public static final String GET_DATA_PRIVILEGE_FAIL = "IOTDB-0087";
+  public static final String GET_DATA_PRIVILEGE_FAIL_MSG =
+      "Failed to get data management privilege";
+
+  public static final String NO_PRI_INSERT_DATA = "IOTDB-0088";
+  public static final String NO_PRI_INSERT_DATA_MSG = "No privilege to insert data";
+
+  public static final String NO_PRI_ALTER_MEASUREMENT = "IOTDB-0089";
+  public static final String NO_PRI_ALTER_MEASUREMENT_MSG = "No privilege to update measurement";
+
+  public static final String NO_SUP_WORD = "IOTDB-0090";
+  public static final String NO_SUP_WORD_MSG = "The tag or attribute cannot be as, null, or like";
+
+  public static final String NO_SUP_ALL_DIGIT = "IOTDB-0091";
+  public static final String NO_SUP_ALL_DIGIT_MSG =
+      "The keys of tags or attributes cannot be pure numbers";
+
+  public static final String NO_SUP_ALIAS_WORD = "IOTDB-0092";
+  public static final String NO_SUP_ALIAS_WORD_MSG =
+      "Measurement alias cannot be as, like, or pure numbers";
+
+  public static final String TTL_OVER = "IOTDB-0093";
+  public static final String TTL_OVER_MSG = "The TTL is too long";
+
+  public static final String MEASUREMENT_ALREADY_EXIST = "IOTDB-0094";
+  public static final String MEASUREMENT_ALREADY_EXIST_MSG =
+      "Failed to create a measurement. Check whether the measurement has the same name as an existing measurement or alias";
+
+  // Storage group table
   public static final String INSERT_GROUP_INFO_FAIL = "GROUP-0001";
-  public static final String INSERT_GROUP_INFO_FAIL_MSG = "插入存储组信息失败";
+  public static final String INSERT_GROUP_INFO_FAIL_MSG =
+      "Failed to insert storage group information";
 
   public static final String DELETE_GROUP_INFO_FAIL = "GROUP-0002";
-  public static final String DELETE_GROUP_INFO_FAIL_MSG = "删除存储组信息失败";
+  public static final String DELETE_GROUP_INFO_FAIL_MSG =
+      "Failed to delete storage group information";
 
-  // 实体表相关
+  // Entity table
   public static final String DELETE_DEVICE_INFO_FAIL = "DEV-0001";
-  public static final String DELETE_DEVICE_INFO_FAIL_MSG = "删除实体信息失败";
+  public static final String DELETE_DEVICE_INFO_FAIL_MSG = "Failed to delete entity information";
 
   public static final String SET_DEVICE_INFO_FAIL = "DEV-0002";
-  public static final String SET_DEVICE_INFO_FAIL_MSG = "插入实体信息失败";
+  public static final String SET_DEVICE_INFO_FAIL_MSG = "Failed to insert entity information";
 
-  // 物理量表相关
+  // Measurement table
   public static final String DELETE_MEASUREMENT_INFO_FAIL = "MEASU-0001";
-  public static final String DELETE_MEASUREMENT_INFO_FAIL_MSG = "删除物理量信息失败";
+  public static final String DELETE_MEASUREMENT_INFO_FAIL_MSG =
+      "Failed to delete measurement information";
 
   public static final String SET_MEASUREMENT_INFO_FAIL = "MEASU-0002";
-  public static final String SET_MEASUREMENT_INFO_FAIL_MSG = "插入物理量信息失败";
+  public static final String SET_MEASUREMENT_INFO_FAIL_MSG =
+      "Failed to insert measurement information";
 
   public static final String GET_MSM_DES_FAIL = "MEASU-0003";
-  public static final String GET_MSM_DES_FAIL_MSG = "获取物理量描述信息失败";
+  public static final String GET_MSM_DES_FAIL_MSG = "Failed to get measurement information";
 
-  // 查询表相关
+  // query table
   public static final String QUERY_EXIST = "QUERY-0001";
-  public static final String QUERY_EXIST_MSG = "脚本名已存在";
+  public static final String QUERY_EXIST_MSG = "The query script name already exists";
 
   public static final String QUERY_NOT_EXIST = "QUERY-0002";
-  public static final String QUERY_NOT_EXIST_MSG = "脚本不存在";
+  public static final String QUERY_NOT_EXIST_MSG = "The query script name doesn't exist";
+
+  // role table
+  public static final String UPSERT_ROLE_INFO_FAIL = "ROLE-0001";
+  public static final String UPSERT_ROLE_INFO_FAIL_MSG = "Failed to upsert role information";
+
+  public static final String DELETE_ROLE_INFO_FAIL = "ROLE-0002";
+  public static final String DELETE_ROLE_INFO_FAIL_MSG = "Failed to delete role information";
+
+  public static final String GET_ROLE_INFO_FAIL = "ROLE-0003";
+  public static final String GET_ROLE_INFO_FAIL_MSG = "Failed to get role information";
 
-  // 参数校验相关
+  // Parameter verify
   public static final String WRONG_PARAM = "PARAM-0001";
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java b/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
index 98047dd..1b2e149 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
@@ -27,7 +27,7 @@ import com.auth0.jwt.interfaces.DecodedJWT;
 
 import javax.servlet.http.HttpServletRequest;
 
-/** 校验工具类 */
+/** Validation tool class */
 public class AuthenticationUtils {
 
   public static void userAuthentication(Integer userId, HttpServletRequest request)
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java b/backend/src/main/java/org/apache/iotdb/admin/config/FileProperties.java
similarity index 66%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/config/FileProperties.java
index e26eea3..a98351a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/FileProperties.java
@@ -17,20 +17,21 @@
  * under the License.
  */
 
-package org.apache.iotdb.admin.model.dto;
+package org.apache.iotdb.admin.config;
 
-import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
 
-import java.io.Serializable;
+@Component
+@ConfigurationProperties(prefix = "file")
+public class FileProperties {
+  private String tempDir;
 
-@Data
-public class DeviceDTO implements Serializable {
+  public String getTempDir() {
+    return tempDir;
+  }
 
-  private String timeseries;
-
-  private String dataType;
-
-  private String encoding;
-
-  private String description;
+  public void setTempDir(String tempDir) {
+    this.tempDir = tempDir;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
index 3a00d52..6a6ed82 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
@@ -29,7 +29,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 import java.util.ArrayList;
 import java.util.List;
 
-/** 拦截器配置类 */
+/** Interceptor configuration class */
 @Component
 public class FilterConfig implements WebMvcConfigurer {
 
@@ -39,6 +39,7 @@ public class FilterConfig implements WebMvcConfigurer {
     List<String> paths = new ArrayList();
     paths.add("/servers/**");
     paths.add("/get");
+    paths.add("/downloadFile/**");
     interceptorRegistration.addPathPatterns(paths);
   }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
index 607aa1e..32b8ec2 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
@@ -25,22 +25,14 @@ import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerIntercept
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-/** 该类是Mybatis-Plus的配置类,mybatis以插件的形式来实现特定功能 */
 @Configuration
 public class MybatisPlusConfig {
 
-  /**
-   * 分页插件配置,对相关数据库进行拦截并分页
-   *
-   * @return 分页拦截器
-   */
   @Bean
   public MybatisPlusInterceptor paginationInterceptor() {
     MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-    // 使用不同的数据库,可以更改DbType.MYSQL的类型
     PaginationInnerInterceptor paginationInnerInterceptor =
-        new PaginationInnerInterceptor(DbType.MYSQL);
-    // 每页最多100条,可以更改,但不建议太大
+        new PaginationInnerInterceptor(DbType.SQLITE);
     paginationInnerInterceptor.setMaxLimit(100L);
     interceptor.addInnerInterceptor(paginationInnerInterceptor);
     return interceptor;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
index e4c0340..2c25f3b 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
@@ -25,10 +25,9 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
-/** 加密算法配置类 hash算法 */
+/** Encryption algorithm configuration class */
 @Configuration
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests()
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
index 70eb759..1c46d70 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.admin.config;
 
+import io.swagger.annotations.ApiOperation;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Profile;
@@ -36,7 +37,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 import java.util.ArrayList;
 import java.util.List;
 
-/** swagger配置类 */
+/** swagger configuration class */
 @Configuration
 @EnableSwagger2
 @Profile({"dev", "test"})
@@ -50,14 +51,15 @@ public class SwaggerConfig {
         .globalOperationParameters(jwtToken())
         .select()
         .apis(RequestHandlerSelectors.basePackage("org.apache.iotdb.admin.controller"))
+        .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
         .paths(PathSelectors.any())
         .build();
   }
 
   private ApiInfo apiinfo() {
     return new ApiInfoBuilder()
-        .title("IOTDB接口文档")
-        .description("iotDB层级关系 存储组 -> 实体(设备) -> 测点(时间序列)")
+        .title("IoTDB-Workbench API")
+        .description("IoTDB hierarchy: storage group -> entity -> measurement")
         .build();
   }
 
@@ -67,7 +69,7 @@ public class SwaggerConfig {
     List<Parameter> pars = new ArrayList<>();
     tokenPar
         .name("Authorization")
-        .description("jwt令牌")
+        .description("java web token")
         .modelRef(new ModelRef("string"))
         .parameterType("header")
         .required(false);
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java b/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
index 4a7653f..3bf4945 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
@@ -27,7 +27,7 @@ import javax.validation.Validation;
 import javax.validation.Validator;
 import javax.validation.ValidatorFactory;
 
-/** 校验框架配置类 */
+/** Validator configuration classes */
 @Configuration
 public class ValidatorConfiguration {
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
index 90086d1..768972e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
@@ -42,56 +42,55 @@ import java.net.Socket;
 import java.util.List;
 
 @RestController
-@Api(value = "连接相关接口")
+@Api(value = "Connection related")
 public class ConnectionController {
 
   @Autowired private ConnectionService connectionService;
 
   @PostMapping("/servers")
-  @ApiOperation("保存或更新连接")
+  @ApiOperation("Upsert connection")
   public BaseVO saveOrUpdateConnection(
       @RequestBody Connection connection, HttpServletRequest request) throws BaseException {
     AuthenticationUtils.userAuthentication(connection.getUserId(), request);
     if (connection.getId() != null) {
       connectionService.update(connection);
-      return BaseVO.success("更新成功", null);
+      return BaseVO.success("Update successfully", null);
     }
     connectionService.insert(connection);
-
-    return BaseVO.success("保存成功", null);
+    return BaseVO.success("Save successfully", null);
   }
 
   @DeleteMapping("/servers/{serverId}")
-  @ApiOperation("删除连接")
+  @ApiOperation("Delete connection")
   public BaseVO deleteConnection(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     Integer userId = AuthenticationUtils.getUserId(request);
     connectionService.check(serverId, userId);
     connectionService.deleteById(serverId, userId);
-    return BaseVO.success("删除成功", null);
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/servers/{serverId}")
-  @ApiOperation("获取连接具体配置")
+  @ApiOperation("Get detailed information of the specified connection")
   public BaseVO<Connection> getConnection(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     Integer userId = AuthenticationUtils.getUserId(request);
     connectionService.check(serverId, userId);
-    return BaseVO.success("获取成功", connectionService.getById(serverId));
+    return BaseVO.success("Get successfully", connectionService.getById(serverId));
   }
 
   @GetMapping("/servers")
-  @ApiOperation("获取所有连接")
+  @ApiOperation("Get all connection")
   public BaseVO<ConnectionVO> getAllConnections(
       @RequestParam("userId") Integer userId, HttpServletRequest request) throws BaseException {
     AuthenticationUtils.userAuthentication(userId, request);
     List<ConnVO> connVOs = connectionService.getAllConnections(userId);
     ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, null);
-    return BaseVO.success("获取成功", connectionVO);
+    return BaseVO.success("Get successfully", connectionVO);
   }
 
   @PostMapping("/test")
-  @ApiOperation("连通性测试")
+  @ApiOperation("Connectivity test")
   public BaseVO testConnection(@RequestBody ConnectionDTO conn) throws BaseException {
     Socket socket = null;
     try {
@@ -123,6 +122,6 @@ public class ConnectionController {
         throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
       }
     }
-    return BaseVO.success("连通成功", null);
+    return BaseVO.success("Connection successfully", null);
   }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java
new file mode 100644
index 0000000..ea0106b
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/FileController.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.controller;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
+import org.apache.iotdb.admin.model.entity.Connection;
+import org.apache.iotdb.admin.model.vo.BaseVO;
+import org.apache.iotdb.admin.model.vo.ImportDataVO;
+import org.apache.iotdb.admin.service.ConnectionService;
+import org.apache.iotdb.admin.service.FileService;
+import org.apache.iotdb.admin.tool.ExportCsv;
+import org.apache.iotdb.admin.tool.ImportCsv;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@Api(value = "File related")
+public class FileController {
+  @Autowired private FileService fileService;
+
+  @Autowired private ConnectionService connectionService;
+
+  @Autowired private ImportCsv importCsv;
+
+  @Autowired private ExportCsv exportCsv;
+
+  @ApiOperation("Import measurement data from a CSV file")
+  @PostMapping("/servers/{serverId}/importData")
+  public BaseVO<ImportDataVO> importData(
+      @RequestParam("file") MultipartFile file,
+      @PathVariable("serverId") Integer serverId,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    if (!file.getOriginalFilename().toLowerCase().endsWith(".csv")) {
+      throw new BaseException(ErrorCode.FILE_NAME_ILLEGAL, ErrorCode.FILE_NAME_ILLEGAL_MSG);
+    }
+    String fileName = "import" + System.currentTimeMillis() + ".csv";
+    String fileFullName = fileService.storeFile(file, fileName);
+
+    Connection connection = connectionService.getById(serverId);
+    String host = connection.getHost();
+    Integer port = connection.getPort();
+    String username = connection.getUsername();
+    String password = connection.getPassword();
+    ImportDataVO importDataVO =
+        importCsv.importCsv(host, port, username, password, fileFullName, null);
+
+    return BaseVO.success("Import data successfully", importDataVO);
+  }
+
+  @ApiOperation("Export the query result as a CSV file")
+  @GetMapping("/servers/{serverId}/exportData")
+  public ResponseEntity<Resource> exportData(
+      @PathVariable("serverId") Integer serverId,
+      @RequestParam("sql") String sql,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+
+    String host = connection.getHost();
+    Integer port = connection.getPort();
+    String username = connection.getUsername();
+    String password = connection.getPassword();
+    String fileName = exportCsv.exportCsv(host, port, username, password, sql, null);
+
+    Resource resource = fileService.loadFileAsResource(fileName);
+    return getResponseEntity(resource);
+  }
+
+  @GetMapping("/downloadFile/{fileName}")
+  public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) throws BaseException {
+    Resource resource = fileService.loadFileAsResource(fileName);
+    return getResponseEntity(resource);
+  }
+
+  @ApiOperation("Download the CSV template file")
+  @GetMapping("/downloadFile/template")
+  public ResponseEntity<Resource> downloadTemplateFile() throws BaseException {
+    Resource resource = new ClassPathResource("file/template.csv");
+    if (!resource.exists()) {
+      throw new BaseException(ErrorCode.FILE_NOT_FOUND, ErrorCode.FILE_NOT_FOUND_MSG);
+    }
+    return getResponseEntity(resource);
+  }
+
+  private ResponseEntity<Resource> getResponseEntity(Resource resource) {
+    String contentType = "application/octet-stream";
+
+    return ResponseEntity.ok()
+        .contentType(MediaType.parseMediaType(contentType))
+        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + resource.getFilename())
+        .body(resource);
+  }
+
+  private void check(HttpServletRequest request, Integer serverId) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
index dbc4cd7..899b11a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
@@ -28,17 +28,18 @@ import javax.servlet.http.HttpServletResponse;
 
 import java.io.IOException;
 
-/** 运维平台通过存活、就绪探针表示应用是否存活,就绪。这个类大家最好不好删除,url地址也不要改变 */
+/**
+ * The operation and maintenance platform indicates whether the application is alive and ready
+ * through the alive and ready probe
+ */
 @Controller
 public class HealthController {
 
-  /** 存活探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示存活, 如果多次返回500,则表示这个程序已经死了,会重启这个程序。 */
   @GetMapping(value = "/healthz/liveness")
   public void liveness(HttpServletResponse response) throws IOException, BaseException {
     response.setStatus(HttpServletResponse.SC_OK);
   }
 
-  /** 就绪探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示程序已经可用, 如果多次返回500,则表示这个程序未启动成功,会重启这个程序。 */
   @GetMapping(value = "/healthz/readiness")
   public void readiness(HttpServletResponse response) throws IOException {
     response.setStatus(HttpServletResponse.SC_OK);
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
index 5c4e86c..612816e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
@@ -25,25 +25,34 @@ import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
 import org.apache.iotdb.admin.model.dto.*;
 import org.apache.iotdb.admin.model.entity.Connection;
 import org.apache.iotdb.admin.model.entity.Device;
+import org.apache.iotdb.admin.model.entity.Role;
 import org.apache.iotdb.admin.model.entity.StorageGroup;
 import org.apache.iotdb.admin.model.vo.*;
 import org.apache.iotdb.admin.service.*;
+import org.apache.iotdb.admin.tool.ExportCsv;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
+@Slf4j
 @RestController
-@Api(value = "iotdb操作相关接口")
+@Api(value = "IoTDB related")
 @RequestMapping("/servers/{serverId}")
 public class IotDBController {
 
@@ -57,8 +66,34 @@ public class IotDBController {
 
   @Autowired private MeasurementService measurementService;
 
+  @Autowired private RoleService roleService;
+
+  @Autowired private FileService fileService;
+
+  @Autowired private ExportCsv exportCsv;
+
+  @GetMapping("/dataCount")
+  @ApiOperation("Get IoTDB data statistics")
+  public BaseVO<DataCountVO> getDataCount(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    DataCountVO dataCountVO = iotDBService.getDataCount(connection);
+    return BaseVO.success("Get IoTDB data statistics successfully", dataCountVO);
+  }
+
+  @GetMapping("/dataModel")
+  @ApiOperation("Get IoTDB data model")
+  public BaseVO<DataModelVO> getDataModel(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    DataModelVO dataModelVO = iotDBService.getDataModel(connection);
+    return BaseVO.success("Get IoTDB data model successfully", dataModelVO);
+  }
+
   @GetMapping("/storageGroups/info")
-  @ApiOperation("获得存储组信息列表")
+  @ApiOperation("Get information of the storage group list")
   public BaseVO<List<GroupInfoVO>> getAllStorageGroupsInfo(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     check(request, serverId);
@@ -66,23 +101,23 @@ public class IotDBController {
     List<String> groupNames = iotDBService.getAllStorageGroups(connection);
     List<GroupInfoVO> groupInfoList = new ArrayList<>();
     if (groupNames == null || groupNames.size() == 0) {
-      return BaseVO.success("获取成功", groupInfoList);
+      return BaseVO.success("Get successfully", groupInfoList);
     }
     String host = connection.getHost();
     List<Integer> deviceCounts = iotDBService.getDevicesCount(connection, groupNames);
     List<String> descriptions = groupService.getGroupDescription(host, groupNames);
     for (int i = 0; i < groupNames.size(); i++) {
       GroupInfoVO groupInfoVO = new GroupInfoVO();
-      groupInfoVO.setGroupName(groupNames.get(i).replaceFirst("root.", ""));
+      groupInfoVO.setGroupName(groupNames.get(i));
       groupInfoVO.setDeviceCount(deviceCounts.get(i));
       groupInfoVO.setDescription(descriptions.get(i));
       groupInfoList.add(groupInfoVO);
     }
-    return BaseVO.success("获取成功", groupInfoList);
+    return BaseVO.success("Get successfully", groupInfoList);
   }
 
   @GetMapping("/storageGroups")
-  @ApiOperation("获得存储组列表")
+  @ApiOperation("Get storage group list")
   public BaseVO<List<StorageGroupVO>> getAllStorageGroups(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     check(request, serverId);
@@ -90,37 +125,43 @@ public class IotDBController {
     List<StorageGroupVO> storageGroupVOList = new ArrayList<>();
     List<String> groupNames = iotDBService.getAllStorageGroups(connection);
     if (groupNames == null || groupNames.size() == 0) {
-      return BaseVO.success("获取成功", storageGroupVOList);
+      return BaseVO.success("Get successfully", storageGroupVOList);
     }
     String host = connection.getHost();
     for (String groupName : groupNames) {
       StorageGroupVO storageGroupVO = new StorageGroupVO();
       Integer id = groupService.getGroupId(host, groupName);
       storageGroupVO.setGroupId(id);
-      groupName = groupName.replaceFirst("root.", "");
       storageGroupVO.setGroupName(groupName);
       storageGroupVOList.add(storageGroupVO);
     }
-    return BaseVO.success("获取成功", storageGroupVOList);
+    return BaseVO.success("Get successfully", storageGroupVOList);
+  }
+
+  @GetMapping("/storageGroups/nodeTree")
+  @ApiOperation("Get storage group list(Node tree structure)")
+  public BaseVO<List<NodeTreeVO>> getGroupsNodeTree(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<NodeTreeVO> groupsNodeTree = iotDBService.getGroupsNodeTree(connection);
+    return BaseVO.success("Get successfully", groupsNodeTree);
   }
 
   @PostMapping("/storageGroups")
-  @ApiOperation("新增或修改存储组")
+  @ApiOperation("Upsert storage group")
   public BaseVO saveStorageGroup(
       @PathVariable("serverId") Integer serverId,
       @RequestBody GroupDTO groupDTO,
       HttpServletRequest request)
       throws BaseException {
+    String groupName = groupDTO.getGroupName();
+    checkParameter(groupName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    String groupName = groupDTO.getGroupName();
-    String checkName = groupName.toLowerCase();
-    if (checkName.contains("root")) {
-      throw new BaseException(ErrorCode.NO_SUP_CONTAIN_ROOT, ErrorCode.NO_SUP_CONTAIN_ROOT_MSG);
-    }
-    groupName = "root." + groupName;
     Long ttl = groupDTO.getTtl();
     String ttlUnit = groupDTO.getTtlUnit();
+    checkTtl(ttl, ttlUnit);
     Integer groupId = groupDTO.getGroupId();
     groupDTO.setGroupName(groupName);
 
@@ -147,43 +188,37 @@ public class IotDBController {
         throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
       }
     }
-    return BaseVO.success("新增或更新成功", null);
+    return BaseVO.success("Upsert successfully", null);
   }
 
   @DeleteMapping("/storageGroups/{groupName}")
-  @ApiOperation("删除存储组")
+  @ApiOperation("Delete storage group")
   public BaseVO deleteStorageGroup(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
     String host = connection.getHost();
     iotDBService.deleteStorageGroup(connection, groupName);
     groupService.deleteGroupInfo(host, groupName);
     deviceService.deleteDeviceInfo(host, groupName);
     measurementService.deleteMeasurementInfo(host, groupName);
-    return BaseVO.success("删除成功", null);
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/storageGroups/{groupName}")
-  @ApiOperation("存储组详情获取")
+  @ApiOperation("Get detailed information of the specified storage group")
   public BaseVO<GroupVO> getStorageGroup(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
     String host = connection.getHost();
     StorageGroup group = groupService.getGroupInfo(host, groupName);
     String ttl = iotDBService.getGroupTTL(connection, groupName);
@@ -207,13 +242,13 @@ public class IotDBController {
       String createTime = simpleDateFormat.format(date);
       groupVO.setCreateTime(createTime);
     }
-    groupVO.setGroupName(groupName.replaceFirst("root.", ""));
+    groupVO.setGroupName(groupName);
     groupVO.setAlias(connection.getAlias());
-    return BaseVO.success("获取成功", groupVO);
+    return BaseVO.success("Get successfully", groupVO);
   }
 
   @GetMapping("/storageGroups/{groupName}/devices/info")
-  @ApiOperation("获取指定存储组下的实体(设备)信息列表")
+  @ApiOperation("Gets information of entities under the specified storage group")
   public BaseVO<DeviceInfoVO> getDevicesInfoByGroupName(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
@@ -222,15 +257,9 @@ public class IotDBController {
       @RequestParam(value = "keyword", required = false) String keyword,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    if (pageSize == null || pageNum == null) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
     CountDTO countDTO =
         iotDBService.getDevicesByGroup(connection, groupName, pageSize, pageNum, keyword);
     List<String> deviceNames = countDTO.getObjects();
@@ -245,12 +274,10 @@ public class IotDBController {
     if (deviceNames != null) {
       for (int i = 0; i < deviceNames.size(); i++) {
         String deviceName = deviceNames.get(i);
-        if (groupName.equals(deviceName)) {
-          continue;
-        }
         DeviceInfo deviceInfo = new DeviceInfo();
-        deviceInfo.setDeviceName(deviceName.replaceFirst(groupName + ".", ""));
+        deviceInfo.setDeviceName(deviceName);
         deviceInfo.setLine(lines.get(i));
+        deviceInfo.setParents(iotDBService.getDeviceParents(connection, groupName, deviceName));
         if (devices.get(i) != null) {
           deviceInfo.setDeviceId(devices.get(i).getId());
           deviceInfo.setCreator(devices.get(i).getCreator());
@@ -260,116 +287,145 @@ public class IotDBController {
       }
     }
     deviceInfoVO.setDeviceInfos(deviceInfos);
-    return BaseVO.success("获取成功", deviceInfoVO);
+    return BaseVO.success("Get successfully", deviceInfoVO);
   }
 
   @GetMapping("/storageGroups/{groupName}/devices")
-  @ApiOperation("获取指定存储组下的实体(设备)列表")
-  public BaseVO<List<String>> getDevicesByGroupName(
+  @ApiOperation("Gets a list of entities under the specified storage group")
+  public BaseVO<List<String>> getDevicesByGroup(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    List<String> deviceNamesStr = iotDBService.getDevices(connection, groupName);
-    List<String> deviceNames = new ArrayList<>();
-    for (String s : deviceNamesStr) {
-      String deviceName;
-      if (groupName.equals(s)) {
-        continue;
-      } else {
-        deviceName = s.replaceFirst(groupName + ".", "");
-      }
-      deviceNames.add(deviceName);
-    }
-    return BaseVO.success("获取成功", deviceNames);
+    final List<String> devices = iotDBService.getDevices(connection, groupName);
+    return BaseVO.success("Get successfully", devices);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/nodeTree")
+  @ApiOperation("Get entity list(Node tree structure) of the specified storage group")
+  public BaseVO<List<NodeTreeVO>> getDevicesNodeTreeByGroup(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkParameter(groupName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<NodeTreeVO> deviceList = iotDBService.getDeviceNodeTree(connection, groupName);
+    return BaseVO.success("Get successfully", deviceList);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/tree")
+  @ApiOperation("Get entity list(Tree structure) of the specified storage group")
+  public BaseVO<NodeTreeVO> getDevicesTreeByGroup(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkParameter(groupName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    NodeTreeVO deviceList = iotDBService.getDeviceList(connection, groupName);
+    return BaseVO.success("Get successfully", deviceList);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/parents")
+  @ApiOperation("Get the list of the parent entities of the specified entity")
+  public BaseVO<List<String>> getDeviceParents(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkParameter(groupName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<String> deviceParents = iotDBService.getDeviceParents(connection, groupName, deviceName);
+    return BaseVO.success("Get successfully", deviceParents);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/exist")
+  @ApiOperation("Check whether the device already exists")
+  public BaseVO<Boolean> deviceExist(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkParameter(groupName, deviceName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    Boolean isExist = iotDBService.deviceExist(connection, groupName, deviceName);
+    return BaseVO.success("Get successfully", isExist);
   }
 
   @PostMapping("/storageGroups/{groupName}/devices")
-  @ApiOperation("新增或编辑实体(设备)")
-  public BaseVO<List<String>> saveOrUpdateDevice(
+  @ApiOperation("Upsert entity")
+  public BaseVO saveOrUpdateDevice(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @RequestBody DeviceInfoDTO deviceInfoDTO,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    if (deviceInfoDTO.getDeviceDTOList() == null || deviceInfoDTO.getDeviceDTOList().size() == 0) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+      checkParameter(groupName, deviceInfoDTO.getDeviceName(), deviceDTO.getTimeseries());
     }
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceInfoDTO.setDeviceName(groupName + "." + deviceInfoDTO.getDeviceName());
-    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
-      deviceDTO.setTimeseries(deviceInfoDTO.getDeviceName() + "." + deviceDTO.getTimeseries());
-    }
+    iotDBService.upsertMeasurements(connection, deviceInfoDTO);
     String host = connection.getHost();
-    iotDBService.createDeviceWithMeasurements(connection, deviceInfoDTO);
     if (deviceInfoDTO.getDeviceId() == null) {
       deviceService.setDeviceInfo(connection, deviceInfoDTO);
-      measurementService.setMeasurementsInfo(host, deviceInfoDTO);
+      measurementService.updateMeasurementsInfo(host, deviceInfoDTO);
     } else {
       deviceService.updateDeviceInfo(deviceInfoDTO);
       measurementService.updateMeasurementsInfo(host, deviceInfoDTO);
     }
-    return BaseVO.success("新增或更新成功", null);
+    return BaseVO.success("Upsert successfully", null);
   }
 
   @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}")
-  @ApiOperation("删除实体(设备)")
+  @ApiOperation("Delete entity")
   public BaseVO deleteDevice(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName, deviceName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
     String host = connection.getHost();
-    iotDBService.deleteTimeseriesByDevice(connection, deviceName);
+    List<String> deletedTimeseriesList =
+        iotDBService.deleteTimeseriesByDevice(connection, deviceName);
     deviceService.deleteDeviceInfoByDeviceName(host, deviceName);
-    measurementService.deleteMeasurementInfoByDeviceName(host, deviceName);
-    return BaseVO.success("删除成功", null);
+    for (String timeseries : deletedTimeseriesList) {
+      measurementService.deleteMeasurementInfo(host, timeseries);
+    }
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/storageGroups/{groupName}/devices/{deviceName}")
-  @ApiOperation("获取实体(设备)详情")
+  @ApiOperation("Get information of the specified entity")
   public BaseVO<DeviceVO> getDeviceInfo(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
       HttpServletRequest request)
       throws BaseException {
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName, deviceName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
     String host = connection.getHost();
     DeviceVO deviceVO = deviceService.getDevice(host, deviceName);
-    return BaseVO.success("获取成功", deviceVO);
+    return BaseVO.success("Get successfully", deviceVO);
   }
 
   @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/info")
-  @ApiOperation("获取指定实体(设备)下的物理量列表详情")
+  @ApiOperation("Gets detailed information of measurements under the specified entity")
   public BaseVO<MeasuremtnInfoVO> getMeasurementsByDeviceName(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
@@ -379,16 +435,9 @@ public class IotDBController {
       @RequestParam(value = "keyword", required = false) String keyword,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName, deviceName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
     CountDTO countDTO =
         iotDBService.getMeasurementsByDevice(connection, deviceName, pageSize, pageNum, keyword);
     List<MeasurementDTO> measurementDTOList = countDTO.getObjects();
@@ -398,16 +447,46 @@ public class IotDBController {
       for (MeasurementDTO measurementDTO : measurementDTOList) {
         MeasurementVO measurementVO = new MeasurementVO();
         BeanUtils.copyProperties(measurementDTO, measurementVO);
-        if (measurementVO.getTimeseries() != null) {
-          measurementVO.setTimeseries(
-              measurementVO.getTimeseries().replaceFirst(deviceName + ".", ""));
-        }
         String description =
             measurementService.getDescription(host, measurementDTO.getTimeseries());
         String newValue =
             iotDBService.getLastMeasurementValue(connection, measurementDTO.getTimeseries());
+        Integer dataCount =
+            iotDBService.getOneDataCount(connection, deviceName, measurementDTO.getTimeseries());
+        measurementVO.setDataCount(dataCount);
         measurementVO.setNewValue(newValue);
         measurementVO.setDescription(description);
+        ObjectMapper mapper = new ObjectMapper();
+        List<List<String>> tags = new ArrayList<>();
+        List<List<String>> attributes = new ArrayList<>();
+        try {
+          if (!"null".equals(measurementDTO.getTags())) {
+
+            Map<String, String> tagsMap = mapper.readValue(measurementDTO.getTags(), Map.class);
+            for (String key : tagsMap.keySet()) {
+              List<String> tag = new ArrayList<>();
+              tag.add(key);
+              tag.add(tagsMap.get(key));
+              tags.add(tag);
+            }
+          }
+          measurementVO.setTags(tags);
+          if (!"null".equals(measurementDTO.getAttributes())) {
+
+            Map<String, String> attributesMap =
+                mapper.readValue(measurementDTO.getAttributes(), Map.class);
+            for (String key : attributesMap.keySet()) {
+              List<String> attribute = new ArrayList<>();
+              attribute.add(key);
+              attribute.add(attributesMap.get(key));
+              attributes.add(attribute);
+            }
+          }
+          measurementVO.setAttributes(attributes);
+        } catch (JsonProcessingException e) {
+          log.error(e.getMessage());
+          throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+        }
         measurementVOList.add(measurementVO);
       }
     }
@@ -415,119 +494,199 @@ public class IotDBController {
     measuremtnInfoVO.setTotalCount(countDTO.getTotalCount());
     measuremtnInfoVO.setTotalPage(countDTO.getTotalPage());
     measuremtnInfoVO.setMeasurementVOList(measurementVOList);
-    return BaseVO.success("获取成功", measuremtnInfoVO);
+    return BaseVO.success("Get successfully", measuremtnInfoVO);
   }
 
   @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
-  @ApiOperation("获取指定物理量的最新两百条数据记录")
+  @ApiOperation("Get the latest 200 data records of the specified measurement")
   public BaseVO<RecordVO> getMeasurementInfo(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
       @PathVariable("timeseriesName") String timeseriesName,
+      @RequestParam("dataType") String dataType,
       HttpServletRequest request)
       throws BaseException {
-    if (groupName == null || !groupName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName, deviceName, timeseriesName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
-    RecordVO recordVO = iotDBService.getRecords(connection, deviceName, timeseriesName);
-    return BaseVO.success("获取成功", recordVO);
+    RecordVO recordVO = iotDBService.getRecords(connection, deviceName, timeseriesName, dataType);
+    return BaseVO.success("Get successfully", recordVO);
   }
 
-  @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
-  @ApiOperation("创建时间序列  (未使用)")
-  public BaseVO insertTimeseries(
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
+  @ApiOperation("Get the list of measurement under the specified entity")
+  public BaseVO<List<String>> getTimeseries(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
-      @RequestBody Timeseries timeseries,
       HttpServletRequest request)
       throws BaseException {
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName, deviceName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
-    iotDBService.insertTimeseries(connection, deviceName, timeseries);
-    return BaseVO.success("创建成功", null);
+    List<String> timeseries = iotDBService.getTimeseries(connection, deviceName);
+    return BaseVO.success("Get successfully", timeseries);
   }
 
-  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/info")
-  @ApiOperation("指定设备下的所有物理量  (未使用)")
-  public BaseVO<SqlResultVO> showTimeseries(
+  @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
+  @ApiOperation("Delete measurement")
+  public BaseVO deleteTimeseries(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
+      @PathVariable("timeseriesName") String timeseriesName,
       HttpServletRequest request)
       throws BaseException {
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
+    checkParameter(groupName, deviceName, timeseriesName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
-    SqlResultVO resultVO = iotDBService.showTimeseries(connection, deviceName);
-    return BaseVO.success("获取成功", resultVO);
+    iotDBService.deleteTimeseries(connection, timeseriesName);
+    String host = connection.getHost();
+    measurementService.deleteMeasurementInfo(host, timeseriesName);
+    return BaseVO.success("Delete successfully", null);
   }
 
-  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
-  @ApiOperation("指定设备下的物理量列表")
-  public BaseVO<List<String>> getTimeseries(
+  @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/data")
+  @ApiOperation("Get measurement data of the specified entity")
+  public BaseVO<DataVO> getDataByDevice(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @RequestParam("pageSize") Integer pageSize,
+      @RequestParam("pageNum") Integer pageNum,
+      @RequestBody DataQueryDTO dataQueryDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    checkParameter(groupName, deviceName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    DataVO dataVO =
+        iotDBService.getDataByDevice(connection, deviceName, pageSize, pageNum, dataQueryDTO);
+    return BaseVO.success("Get successfully", dataVO);
+  }
+
+  @PutMapping("/storageGroups/{groupName}/devices/{deviceName}/data")
+  @ApiOperation("Update measurement data")
+  public BaseVO updateDataByDevice(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
+      @RequestBody DataUpdateDTO dataUpdateDTO,
       HttpServletRequest request)
       throws BaseException {
-    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+    if (dataUpdateDTO.getValueList().size() != dataUpdateDTO.getMeasurementList().size()) {
       throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
     }
+    for (String measurement : dataUpdateDTO.getMeasurementList()) {
+      checkParameter(groupName, deviceName, measurement);
+    }
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
-    List<String> timeseriesStr = iotDBService.getTimeseries(connection, deviceName);
-    List<String> timeseries = new ArrayList<>();
-    for (String s : timeseriesStr) {
-      timeseries.add(s.replaceFirst(deviceName + ".", ""));
+    iotDBService.updateDataByDevice(connection, deviceName, dataUpdateDTO);
+    return BaseVO.success("Upsert successfully", null);
+  }
+
+  @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}/data")
+  @ApiOperation("Delete measurement data")
+  public BaseVO deleteDataByDevice(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @RequestBody DataDeleteDTO dataDeleteDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    for (String measurement : dataDeleteDTO.getMeasurementList()) {
+      checkParameter(groupName, deviceName, measurement);
     }
-    return BaseVO.success("获取成功", timeseries);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.deleteDataByDevice(connection, deviceName, dataDeleteDTO);
+    return BaseVO.success("Delete successfully", null);
   }
 
-  @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
-  @ApiOperation("删除物理量")
-  public BaseVO deleteTimeseries(
+  @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/randomImport")
+  @ApiOperation("Import measurement data of specified devices in batches")
+  public BaseVO randomImport(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
-      @PathVariable("timeseriesName") String timeseriesName,
+      @RequestBody RandomImportDTO randomImportDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    checkParameter(groupName, deviceName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.randomImport(connection, deviceName, randomImportDTO);
+    return BaseVO.success("Randomly import successfully", null);
+  }
+
+  @ApiOperation("Export measurement data of the specified entity")
+  @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/exportData")
+  public ResponseEntity<Resource> exportData(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @RequestBody DataQueryDTO dataQueryDTO,
       HttpServletRequest request)
       throws BaseException {
-    if (timeseriesName == null || !timeseriesName.matches("^[^ ]+$")) {
+    List<String> measurementList = dataQueryDTO.getMeasurementList();
+    if (measurementList == null || measurementList.size() == 0) {
       throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
     }
+    for (String measurement : measurementList) {
+      checkParameter(groupName, deviceName, measurement);
+    }
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    groupName = "root." + groupName;
-    deviceName = groupName + "." + deviceName;
-    timeseriesName = deviceName + "." + timeseriesName;
-    iotDBService.deleteTimeseries(connection, timeseriesName);
     String host = connection.getHost();
-    measurementService.deleteMeasurementInfo(host, timeseriesName);
-    return BaseVO.success("删除成功", null);
+    Integer port = connection.getPort();
+    String username = connection.getUsername();
+    String password = connection.getPassword();
+
+    String sql = iotDBService.getSqlForExport(deviceName, dataQueryDTO);
+    String fileName = exportCsv.exportCsv(host, port, username, password, sql, null);
+
+    org.springframework.core.io.Resource resource = fileService.loadFileAsResource(fileName);
+    String contentType = "application/octet-stream";
+    return ResponseEntity.ok()
+        .contentType(MediaType.parseMediaType(contentType))
+        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + resource.getFilename())
+        .body(resource);
+  }
+
+  @PostMapping("/users")
+  @ApiOperation("Create IoTDB user")
+  public BaseVO setIotDBUser(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody IotDBUser iotDBUser,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    if (iotDBUser.getUserName().matches("^\\d+$")) {
+      throw new BaseException(ErrorCode.NOT_SUPPORT_ALL_DIGIT, ErrorCode.NOT_SUPPORT_ALL_DIGIT_MSG);
+    }
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.setIotDBUser(connection, iotDBUser);
+    return BaseVO.success("Create successfully", null);
+  }
+
+  @DeleteMapping("/users/{userName}")
+  @ApiOperation("Delete IoTDB user")
+  public BaseVO deleteIotDBUser(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.deleteIotDBUser(connection, userName);
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/users")
-  @ApiOperation("获取数据库用户列表")
+  @ApiOperation("Get IoTDB users")
   public BaseVO<List<String>> getIotDBUserList(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     check(request, serverId);
@@ -537,9 +696,9 @@ public class IotDBController {
     if (users == null) {
       users = new ArrayList<>();
       users.add(username);
-      return BaseVO.success("获取成功", users);
+      return BaseVO.success("Get successfully", users);
     }
-    // 前端需要将当前用户处于列表第一位
+    // The page needs to place the current user first in the list
     List<String> newUsers = new ArrayList<>();
     newUsers.add(username);
     for (String user : users) {
@@ -548,62 +707,267 @@ public class IotDBController {
       }
       newUsers.add(user);
     }
-    return BaseVO.success("获取成功", newUsers);
+    return BaseVO.success("Get successfully", newUsers);
+  }
+
+  @GetMapping("/users/{userName}")
+  @ApiOperation("Get the password and role list of the specified user")
+  public BaseVO<UserRolesVO> getRolesOfUser(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    UserRolesVO userRolesVO = iotDBService.getRolesOfUser(connection, userName);
+    return BaseVO.success("Get successfully", userRolesVO);
+  }
+
+  @PostMapping("/users/pwd")
+  @ApiOperation("Alter user password")
+  public BaseVO updatePassword(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody IotDBUser iotDBUser,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.updatePwd(connection, iotDBUser);
+    return BaseVO.success("Alter password successfully", null);
+  }
+
+  @PostMapping("/roles")
+  @ApiOperation("Upsert role")
+  public BaseVO upsertIotDBRole(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody IotDBRole iotDBRole,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    if (iotDBRole.getRoleName().matches("^\\d+$")) {
+      throw new BaseException(ErrorCode.NOT_SUPPORT_ALL_DIGIT, ErrorCode.NOT_SUPPORT_ALL_DIGIT_MSG);
+    }
+    Connection connection = connectionService.getById(serverId);
+    if (iotDBRole.getId() == null) {
+      iotDBService.setIotDBRole(connection, iotDBRole);
+    }
+    roleService.upsertRoleInfo(connection.getHost(), connection.getPort(), iotDBRole);
+    return BaseVO.success("Upsert successfully", null);
+  }
+
+  @DeleteMapping("/roles/{roleName}")
+  @ApiOperation("Delete role")
+  public BaseVO deleteIotDBRole(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(roleName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.deleteIotDBRole(connection, roleName);
+    roleService.deleteRoleInfo(connection.getHost(), connection.getPort(), roleName);
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/roles")
-  @ApiOperation("获取数据库角色列表   (未使用)")
+  @ApiOperation("Get all roles)")
   public BaseVO<List<String>> getIotDBRoleList(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
     List<String> roles = iotDBService.getIotDBRoleList(connection);
-    return BaseVO.success("获取成功", roles);
+    return BaseVO.success("Get successfully", roles);
   }
 
-  @GetMapping("/users/{userName}")
-  @ApiOperation("获取数据源用户的具体信息或其他用户的权限信息")
-  public BaseVO<IotDBUserVO> getIotDBUser(
+  @GetMapping("/roles/{roleName}")
+  @ApiOperation("Get information and user list of the specified role")
+  public BaseVO<RoleVO> getIotDBRoleInfo(
       @PathVariable("serverId") Integer serverId,
-      @PathVariable("userName") String userName,
+      @PathVariable("roleName") String roleName,
       HttpServletRequest request)
       throws BaseException {
-    if (userName == null || !userName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    checkName(roleName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    RoleVO roleVO = iotDBService.getIotDBRoleInfo(connection, roleName);
+    Role roleInfo = roleService.getRoleInfo(connection.getHost(), connection.getPort(), roleName);
+    if (roleInfo != null) {
+      roleVO.setId(roleInfo.getId());
+      roleVO.setDescription(roleInfo.getDescription());
     }
+    return BaseVO.success("Get successfully", roleVO);
+  }
+
+  @PostMapping("/users/{userName}/grant")
+  @ApiOperation("Grant roles to specified user")
+  public BaseVO userGrant(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      @RequestBody UserGrantDTO userGrantDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    IotDBUserVO iotDBUserVO = iotDBService.getIotDBUser(connection, userName);
-    return BaseVO.success("获取成功", iotDBUserVO);
+    iotDBService.userGrant(connection, userName, userGrantDTO);
+    return BaseVO.success("Upsert successfully", null);
   }
 
-  @PostMapping("/users/{userName}")
-  @ApiOperation("数据库用户赋权")
+  @PostMapping("/roles/{roleName}/grant")
+  @ApiOperation("Grant specified role to users")
+  public BaseVO roleGrant(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      @RequestBody RoleGrantDTO roleGrantDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(roleName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.roleGrant(connection, roleName, roleGrantDTO);
+    return BaseVO.success("Upsert successfully", null);
+  }
+
+  @GetMapping("/users/{userName}/authorityPrivilege")
+  @ApiOperation("Get authority management privileges of user")
+  public BaseVO<Set<String>> getUserAuthorityPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    Set<String> userAuthorityPrivilege =
+        iotDBService.getUserAuthorityPrivilege(connection, userName);
+    return BaseVO.success("Get successfully", userAuthorityPrivilege);
+  }
+
+  @GetMapping("/users/{userName}/allAuthorityPrivilege")
+  @ApiOperation("Get all authority management privileges of user")
+  public BaseVO<Set<String>> getAllAuthorityPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    Set<String> userAuthorityPrivilege =
+        iotDBService.getAllAuthorityPrivilege(connection, userName);
+    return BaseVO.success("Get successfully", userAuthorityPrivilege);
+  }
+
+  @GetMapping("/roles/{roleName}/authorityPrivilege")
+  @ApiOperation("Get authority management privileges of role")
+  public BaseVO<Set<String>> getRoleAuthorityPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(roleName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    Set<String> roleAuthorityPrivilege =
+        iotDBService.getRoleAuthorityPrivilege(connection, roleName);
+    return BaseVO.success("Get successfully", roleAuthorityPrivilege);
+  }
+
+  @PostMapping("/users/{userName}/authorityPrivilege")
+  @ApiOperation("Modify authority management privileges of user")
+  public BaseVO upsertUserAuthorityPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      @RequestBody AuthorityPrivilegeDTO authorityPrivilegeDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.upsertAuthorityPrivilege(connection, userName, authorityPrivilegeDTO, "user");
+    return BaseVO.success("Upsert successfully", null);
+  }
+
+  @PostMapping("/roles/{roleName}/authorityPrivilege")
+  @ApiOperation("Modify authority management privileges of role")
+  public BaseVO upsertRoleAuthorityPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      @RequestBody AuthorityPrivilegeDTO authorityPrivilegeDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(roleName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.upsertAuthorityPrivilege(connection, roleName, authorityPrivilegeDTO, "role");
+    return BaseVO.success("Upsert successfully", null);
+  }
+
+  @GetMapping("/users/{userName}/dataPrivilege")
+  @ApiOperation("Get data management privileges of user")
+  public BaseVO<List<DataPrivilegeVO>> getUserDataPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(userName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<DataPrivilegeVO> dataPrivilegeList =
+        iotDBService.getUserDataPrivilege(connection, userName);
+    return BaseVO.success("Get successfully", dataPrivilegeList);
+  }
+
+  @GetMapping("/roles/{roleName}/dataPrivilege")
+  @ApiOperation("Get data management privileges of role")
+  public BaseVO<List<DataPrivilegeVO>> getRoleDataPrivilege(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      HttpServletRequest request)
+      throws BaseException {
+    checkName(roleName);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<DataPrivilegeVO> dataPrivilegeList =
+        iotDBService.getRoleDataPrivilege(connection, roleName);
+    return BaseVO.success("Get successfully", dataPrivilegeList);
+  }
+
+  @PostMapping("/users/{userName}/dataPrivilege")
+  @ApiOperation("Modify data management privileges of user")
   public BaseVO setUserPrivileges(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("userName") String userName,
       @RequestBody PrivilegeInfoDTO privilegeInfoDTO,
       HttpServletRequest request)
       throws BaseException {
-    if (userName == null || !userName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    if (privilegeInfoDTO == null) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    Integer type = privilegeInfoDTO.getType();
-    if (type != null && (type > 3 || type < 0)) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-    }
-    //        Integer delType = pathCheckAndGetDelType(privilegeInfoDTO);
-    pathCheck(privilegeInfoDTO);
     check(request, serverId);
+    checkName(userName);
+    checkPrivilegeInfoDTO(privilegeInfoDTO);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.upsertDataPrivileges(connection, "user", userName, privilegeInfoDTO);
+    return BaseVO.success("Upsert successfully", null);
+  }
+
+  @PostMapping("/roles/{roleName}/dataPrivilege")
+  @ApiOperation("Modify data management privileges of role")
+  public BaseVO setRolePrivileges(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      @RequestBody PrivilegeInfoDTO privilegeInfoDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    checkName(roleName);
+    checkPrivilegeInfoDTO(privilegeInfoDTO);
     Connection connection = connectionService.getById(serverId);
-    iotDBService.setUserPrivileges(connection, userName, privilegeInfoDTO);
-    return BaseVO.success("操作成功", null);
+    iotDBService.upsertDataPrivileges(connection, "role", roleName, privilegeInfoDTO);
+    return BaseVO.success("Upsert successfully", null);
   }
 
-  private void pathCheck(PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
+  private void checkPrivilegeInfoDTO(PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
     Integer type = privilegeInfoDTO.getType();
     List<String> groupPaths = privilegeInfoDTO.getGroupPaths();
     List<String> devicePaths = privilegeInfoDTO.getDevicePaths();
@@ -748,109 +1112,60 @@ public class IotDBController {
       default:
         throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
     }
-    //        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
-    //            if (delGroupPaths == null || delGroupPaths.size() != 1) {
-    //                throw new BaseException(ErrorCode.WRONG_DB_PARAM,
-    // ErrorCode.WRONG_DB_PARAM_MSG);
-    //            }
-    //            if (delDevicePaths == null || delDevicePaths.size() != 1) {
-    //                throw new BaseException(ErrorCode.WRONG_DB_PARAM,
-    // ErrorCode.WRONG_DB_PARAM_MSG);
-    //            }
-    //            return 3;
-    //        }
-    //        if (delDevicePaths != null && delDevicePaths.size() > 0) {
-    //            if (delGroupPaths == null || delGroupPaths.size() != 1) {
-    //                throw new BaseException(ErrorCode.WRONG_DB_PARAM,
-    // ErrorCode.WRONG_DB_PARAM_MSG);
-    //            }
-    //            return 2;
-    //        }
-    //        if (delGroupPaths != null && delGroupPaths.size() > 0) {
-    //            return 1;
-    //        }
-    //        return 0;
   }
 
-  @PostMapping("/users/pwd")
-  @ApiOperation("改变用户密码")
-  public BaseVO updatePassword(
-      @PathVariable("serverId") Integer serverId,
-      @RequestBody IotDBUser iotDBUser,
-      HttpServletRequest request)
-      throws BaseException {
-    check(request, serverId);
-    Connection connection = connectionService.getById(serverId);
-    iotDBService.updatePwd(connection, iotDBUser);
-    return BaseVO.success("修改成功", null);
+  private void check(HttpServletRequest request, Integer serverId) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
   }
 
-  @DeleteMapping("/users/{userName}")
-  @ApiOperation("删除数据库用户")
-  public BaseVO deleteIotDBUser(
-      @PathVariable("serverId") Integer serverId,
-      @PathVariable("userName") String userName,
-      HttpServletRequest request)
-      throws BaseException {
-    if (userName == null || !userName.matches("^[^ ]+$")) {
-      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+  private void checkParameter(String groupName) throws BaseException {
+    String checkName = StringUtils.removeStart(groupName, "root").toLowerCase();
+    if (!groupName.matches("^root\\.[^ ]+$")
+        || checkName.contains(".root.")
+        || checkName.matches("^[^ ]*\\.root$")) {
+      throw new BaseException(ErrorCode.NO_SUP_CONTAIN_ROOT, ErrorCode.NO_SUP_CONTAIN_ROOT_MSG);
+    }
+    if (checkName.contains(".as.")
+        || checkName.contains(".null.")
+        || checkName.contains(".like.")
+        || checkName.matches("^[^ ]*\\.as$")
+        || checkName.matches("^[^ ]*\\.null$")
+        || checkName.matches("^[^ ]*\\.like$")) {
+      throw new BaseException(ErrorCode.NO_SUP_CONTAIN_WORD, ErrorCode.NO_SUP_CONTAIN_WORD_MSG);
     }
-    check(request, serverId);
-    Connection connection = connectionService.getById(serverId);
-    iotDBService.deleteIotDBUser(connection, userName);
-    return BaseVO.success("删除成功", null);
   }
 
-  @DeleteMapping("/roles/{roleName}")
-  @ApiOperation("删除数据库角色  (未使用)")
-  public BaseVO deleteIotDBRole(
-      @PathVariable("serverId") Integer serverId,
-      @PathVariable("roleName") String roleName,
-      HttpServletRequest request)
-      throws BaseException {
-    if (roleName == null || roleName.matches("^[^ ]+$")) {
+  private void checkParameter(String groupName, String deviceName) throws BaseException {
+    checkParameter(deviceName);
+    checkParameter(groupName);
+    if (!deviceName.startsWith(groupName)) {
       throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
     }
-    check(request, serverId);
-    Connection connection = connectionService.getById(serverId);
-    iotDBService.deleteIotDBRole(connection, roleName);
-    return BaseVO.success("删除成功", null);
-  }
-
-  @PostMapping("/users")
-  @ApiOperation("创建数据库用户")
-  public BaseVO setIotDBUser(
-      @PathVariable("serverId") Integer serverId,
-      @RequestBody IotDBUser iotDBUser,
-      HttpServletRequest request)
-      throws BaseException {
-    check(request, serverId);
-    Connection connection = connectionService.getById(serverId);
-    iotDBService.setIotDBUser(connection, iotDBUser);
-    return BaseVO.success("创建成功", null);
   }
 
-  @PostMapping("/roles")
-  @ApiOperation("创建数据角色   (未使用)")
-  public BaseVO setIotDBUser(
-      @PathVariable("serverId") Integer serverId,
-      @RequestBody IotDBRole iotDBRole,
-      HttpServletRequest request)
+  private void checkParameter(String groupName, String deviceName, String timeseriesName)
       throws BaseException {
-    check(request, serverId);
-    Connection connection = connectionService.getById(serverId);
-    iotDBService.setIotDBRole(connection, iotDBRole);
-    return BaseVO.success("创建成功", null);
+    checkParameter(deviceName, timeseriesName);
+    checkParameter(groupName, deviceName);
+    if (StringUtils.removeStart(timeseriesName, deviceName + ".").contains(".")) {
+      throw new BaseException(
+          ErrorCode.MEASUREMENTS_NAME_CONTAIN_DOT, ErrorCode.MEASUREMENTS_NAME_CONTAIN_DOT_MSG);
+    }
   }
 
-  private void check(HttpServletRequest request, Integer serverId) throws BaseException {
-    Integer userId = AuthenticationUtils.getUserId(request);
-    connectionService.check(serverId, userId);
+  private void checkName(String name) throws BaseException {
+    if (name == null || !name.matches("^[^ ]{4,}$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
   }
 
   private Long switchTime(String ttlUnit) throws BaseException {
-    Long time = 0L;
+    Long time;
     switch (ttlUnit) {
+      case "millisecond":
+        time = 1L;
+        break;
       case "second":
         time = 1000L;
         break;
@@ -887,7 +1202,7 @@ public class IotDBController {
     long minuteTime = 60000L;
     long secondTime = 1000L;
     if (time == 0) {
-      return "milliSecond";
+      return "millisecond";
     }
     if ((time / yearTime != 0) && (time % yearTime == 0)) {
       return "year";
@@ -910,6 +1225,12 @@ public class IotDBController {
     if ((time / secondTime != 0) && (time % secondTime == 0)) {
       return "second";
     }
-    return null;
+    return "millisecond";
+  }
+
+  private void checkTtl(Long ttl, String unit) throws BaseException {
+    if (Long.MAX_VALUE / switchTime(unit) < ttl) {
+      throw new BaseException(ErrorCode.TTL_OVER, ErrorCode.TTL_OVER_MSG);
+    }
   }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
index b162210..82d2b89 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
@@ -42,7 +42,7 @@ import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 @RestController
-@Api(value = "查询相关接口")
+@Api(value = "Query related")
 @RequestMapping("/servers/{serverId}")
 public class QueryController {
 
@@ -53,7 +53,7 @@ public class QueryController {
   @Autowired private QueryService queryService;
 
   @PostMapping("/querySql")
-  @ApiOperation("用于查询器查询")
+  @ApiOperation("Execute the query script")
   public BaseVO<List<SqlResultVO>> query(
       @PathVariable("serverId") Integer serverId,
       @RequestBody SearchDTO searchDTO,
@@ -67,11 +67,11 @@ public class QueryController {
     Connection connection = connectionService.getById(serverId);
     Long timestamp = searchDTO.getTimestamp();
     List<SqlResultVO> sqlResultVOList = iotDBService.queryAll(connection, sqls, timestamp);
-    return BaseVO.success("查询成功", sqlResultVOList);
+    return BaseVO.success("Execute the query script successfully", sqlResultVOList);
   }
 
   @PostMapping("/query")
-  @ApiOperation("用于查询脚本保存或编辑")
+  @ApiOperation("Save or update the query script")
   public BaseVO saveQuery(
       @PathVariable("serverId") Integer serverId,
       @RequestBody Query query,
@@ -84,23 +84,23 @@ public class QueryController {
     check(request, serverId);
     if (query.getId() != null) {
       queryService.update(serverId, query);
-      return BaseVO.success("更新成功", null);
+      return BaseVO.success("Update successful", query.getId());
     }
-    queryService.save(serverId, query);
-    return BaseVO.success("保存成功", null);
+    Integer id = queryService.save(serverId, query);
+    return BaseVO.success("Save successful", id);
   }
 
   @GetMapping("/query")
-  @ApiOperation("获取脚本列表")
+  @ApiOperation("Get query scripts")
   public BaseVO<List<QueryVO>> getQueries(
       @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
     check(request, serverId);
     List<QueryVO> queryVOList = queryService.getQueryList(serverId);
-    return BaseVO.success("获取成功", queryVOList);
+    return BaseVO.success("Get successful", queryVOList);
   }
 
   @DeleteMapping("/query/{queryId}")
-  @ApiOperation("删除脚本")
+  @ApiOperation("Delete the query script")
   public BaseVO deleteQuery(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("queryId") Integer queryId,
@@ -108,11 +108,11 @@ public class QueryController {
       throws BaseException {
     check(request, serverId);
     queryService.deleteQuery(queryId);
-    return BaseVO.success("删除成功", null);
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/query/{queryId}")
-  @ApiOperation("获取指定脚本")
+  @ApiOperation("Get the specified query script")
   public BaseVO<Query> getQuery(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("queryId") Integer queryId,
@@ -120,11 +120,11 @@ public class QueryController {
       throws BaseException {
     check(request, serverId);
     Query query = queryService.getQuery(queryId);
-    return BaseVO.success("获取成功", query);
+    return BaseVO.success("Get successfully", query);
   }
 
   @GetMapping("/stop")
-  @ApiOperation("用于查询终止")
+  @ApiOperation("Stop the query")
   public BaseVO query(
       @PathVariable("serverId") Integer serverId,
       @RequestParam("timestamp") Long timestamp,
@@ -132,7 +132,7 @@ public class QueryController {
       throws BaseException {
     check(request, serverId);
     iotDBService.stopQuery(serverId, timestamp);
-    return BaseVO.success("停止成功", null);
+    return BaseVO.success("Stop the query successful", null);
   }
 
   public void check(HttpServletRequest request, Integer serverId) throws BaseException {
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
index ff0e235..b1a7f97 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
@@ -47,7 +47,7 @@ import java.util.Calendar;
 import java.util.List;
 
 @RestController
-@Api(value = "登录相关接口")
+@Api(value = "User related")
 public class UserController {
 
   @Autowired private UserService userService;
@@ -57,7 +57,7 @@ public class UserController {
   private static final Logger logger = LoggerFactory.getLogger(UserController.class);
 
   @PostMapping("/login")
-  @ApiOperation("登录")
+  @ApiOperation("login")
   public BaseVO<ConnectionVO> login(
       @RequestParam("name") String name,
       @RequestParam("password") String password,
@@ -71,27 +71,27 @@ public class UserController {
     List<ConnVO> connVOs = connectionService.getAllConnections(userId);
     ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, name);
     response.addHeader("Authorization", getToken(user));
-    return BaseVO.success("登录成功", connectionVO);
+    return BaseVO.success("Login  successful", connectionVO);
   }
 
   @PostMapping("/save")
-  @ApiOperation("创建用户  (未使用)")
+  @ApiOperation("Create user (not used)")
   public BaseVO save(@RequestBody User user) throws BaseException {
     userService.insert(user);
-    return BaseVO.success("保存成功", null);
+    return BaseVO.success("Save successful", null);
   }
 
   @DeleteMapping("/delete")
-  @ApiOperation("删除用户  (未使用)")
+  @ApiOperation("Delete user (not used)")
   public BaseVO delete(@RequestParam("userId") Integer userId, HttpServletRequest request)
       throws BaseException {
     AuthenticationUtils.userAuthentication(userId, request);
     userService.delete(userId);
-    return BaseVO.success("删除成功", null);
+    return BaseVO.success("Delete successfully", null);
   }
 
   @GetMapping("/get")
-  @ApiOperation("二次登录获取用户信息")
+  @ApiOperation("Get information of user")
   public BaseVO<User> getUser(HttpServletRequest request) {
     String authorization = request.getHeader("Authorization");
     DecodedJWT decode = JWT.decode(authorization);
@@ -102,7 +102,24 @@ public class UserController {
       user.setId(userId);
       user.setName(name);
     }
-    return BaseVO.success("获取成功", user);
+    return BaseVO.success("Get successfully", user);
+  }
+
+  @GetMapping("/")
+  public String welcome() {
+    String str =
+        "<!DOCTYPE html>\n"
+            + "<html lang=\"ch\">\n"
+            + "<head>\n"
+            + "    <meta charset=\"UTF-8\">\n"
+            + "    <title>welcome</title>\n"
+            + "</head>\n"
+            + "<body>\n"
+            + "<h1>You have successfully started IoTDB-Workbench backend application!</h1>\n"
+            + "<h2>For a better experience with IOTDB-Workbench, Please refer to the <a href=\"https://github.com/loveher147/iotdb-admin/blob/main/backend/doc/deploy.md\">deployment documentation</a> for deployment</h2>\n"
+            + "</body>\n"
+            + "</html>";
+    return str;
   }
 
   private String getToken(User user) throws BaseException {
@@ -115,7 +132,7 @@ public class UserController {
               .withClaim("name", user.getName())
               .withExpiresAt(instance.getTime())
               .sign(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()));
-      logger.info(user.getName() + "登录成功");
+      logger.info(user.getName() + "login successfully");
       return token;
     } catch (Exception e) {
       logger.info(e.getMessage());
diff --git a/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java b/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
deleted file mode 100644
index 750ef37..0000000
--- a/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.iotdb.admin.demo;
-
-import java.sql.*;
-
-/** JDBC demo代码 */
-public class JDBC {
-
-  public static void main(String[] args) throws SQLException {
-    Connection connection = getConnection();
-    if (connection == null) {
-      System.out.println("get connection defeat");
-      return;
-    }
-    Statement statement = connection.createStatement();
-    // 创建存储组
-    try {
-      statement.execute("SET STORAGE GROUP TO root.demo");
-    } catch (SQLException e) {
-      e.printStackTrace();
-    }
-    // 展示存储组
-    statement.execute("SHOW STORAGE GROUP");
-    outputResult(statement.getResultSet());
-    // 创建时间序列
-    // 不同的数据类型有不同的编码方式. 这里以INT32作为例子
-    try {
-      statement.execute("CREATE TIMESERIES root.demo.s0 WITH DATATYPE=INT32,ENCODING=RLE;");
-    } catch (SQLException e) {
-      System.out.println(e.getMessage());
-    }
-    // 展示时间序列
-    statement.execute("SHOW TIMESERIES root.demo");
-    outputResult(statement.getResultSet());
-    // 展示设备
-    statement.execute("SHOW DEVICES");
-    outputResult(statement.getResultSet());
-    // 计算时间序列个数
-    statement.execute("COUNT TIMESERIES root");
-    outputResult(statement.getResultSet());
-    // 计算给定级别的nodes个数
-    statement.execute("COUNT NODES root LEVEL=3");
-    outputResult(statement.getResultSet());
-    // 计算时间序列以级别3分组的个数
-    statement.execute("COUNT TIMESERIES root GROUP BY LEVEL=3");
-    outputResult(statement.getResultSet());
-
-    // 批量执行插入语句
-    statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
-    statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
-    statement.addBatch("insert into root.demo(timestamp,s0) values(2,15);");
-    statement.addBatch("insert into root.demo(timestamp,s0) values(2,17);");
-    statement.addBatch("insert into root.demo(timestamp,s0) values(4,12);");
-    statement.executeBatch();
-    statement.clearBatch();
-
-    // 查询语句
-    String sql = "select * from root.demo";
-    ResultSet resultSet = statement.executeQuery(sql);
-    System.out.println("sql: " + sql);
-    outputResult(resultSet);
-
-    // 精确的查询语句
-    sql = "select s0 from root.demo where time = 4;";
-    resultSet = statement.executeQuery(sql);
-    System.out.println("sql: " + sql);
-    outputResult(resultSet);
-
-    // 时间范围查询
-    sql = "select s0 from root.demo where time >= 2 and time < 5;";
-    resultSet = statement.executeQuery(sql);
-    System.out.println("sql: " + sql);
-    outputResult(resultSet);
-
-    // 聚合查询
-    sql = "select count(s0) from root.demo;";
-    resultSet = statement.executeQuery(sql);
-    System.out.println("sql: " + sql);
-    outputResult(resultSet);
-
-    // 删除时间序列
-    statement.execute("delete timeseries root.demo.s0");
-
-    // 关闭连接
-    statement.close();
-    connection.close();
-  }
-
-  public static Connection getConnection() {
-    // JDBC driver name and database URL
-    String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
-    String url = "jdbc:iotdb://127.0.0.1:6667/";
-
-    // Database credentials
-    String username = "root";
-    String password = "root";
-
-    Connection connection = null;
-    try {
-      Class.forName(driver);
-      connection = DriverManager.getConnection(url, username, password);
-    } catch (ClassNotFoundException e) {
-      e.printStackTrace();
-    } catch (SQLException e) {
-      e.printStackTrace();
-    }
-    return connection;
-  }
-
-  /** This is an example of outputting the results in the ResultSet */
-  private static void outputResult(ResultSet resultSet) throws SQLException {
-    if (resultSet != null) {
-      System.out.println("--------------------------");
-      final ResultSetMetaData metaData = resultSet.getMetaData();
-      final int columnCount = metaData.getColumnCount();
-      for (int i = 0; i < columnCount; i++) {
-        System.out.print(metaData.getColumnLabel(i + 1) + " ");
-      }
-      System.out.println();
-      while (resultSet.next()) {
-        for (int i = 1; ; i++) {
-          System.out.print(resultSet.getString(i));
-          if (i < columnCount) {
-            System.out.print(", ");
-          } else {
-            System.out.println();
-            break;
-          }
-        }
-      }
-      System.out.println("--------------------------\n");
-    }
-  }
-}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java b/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
deleted file mode 100644
index 892182d..0000000
--- a/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.iotdb.admin.demo;
-
-import org.apache.iotdb.rpc.IoTDBConnectionException;
-import org.apache.iotdb.rpc.StatementExecutionException;
-import org.apache.iotdb.session.Session;
-import org.apache.iotdb.session.SessionDataSet;
-import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
-import org.apache.iotdb.tsfile.read.common.Field;
-import org.apache.iotdb.tsfile.read.common.RowRecord;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** 原生api demo代码 */
-public class NativeAPI {
-
-  public static void main(String[] args)
-      throws IoTDBConnectionException, StatementExecutionException {
-    // 建立连接
-    Session session = new Session("localhost", 6667, "root", "root");
-    session.open();
-    //        SessionPool sessionPool = new SessionPool("localhost", 6667,"root","root",3);
-    //        sessionPool.insertRecord();
-    // 创建存储组
-    session.setStorageGroup("root.fyx");
-    // 创建时间序列
-    /**
-     * path:层级路径 TSDataType数据类型:六种 支持编码方式 boolean PLAIN,RLE int32 PLAIN,RLE,TS_2DIFF,GORILLA int64
-     * PLAIN,RLE,TS_2DIFF,GORILLA float PLAIN,RLE,TS_2DIFF,GORILLA double PLAIN,RLE,TS_2DIFF,GORILLA
-     * text(字符串) PLAIN
-     *
-     * <p>TSEncoding编码方式: PLAIN编码:不编码 压缩效率高 空间存储效率低 二阶差分编码(TS_2DIFF):适合单调序列数据 不适合编码波动较大的数据
-     * 游程编码(RLE):比较适合整数值连续出现的序列 GORILLA编码:无损编码,它比较适合编码前后值比较接近的数值序列 定频数据编码(REGULAR):仅适用于整型 允许数据缺失
-     *
-     * <p>CompressionType压缩方式: UMCOMPRESSED SNAPPY LZ4 GZIP SDT PAA PLA
-     */
-    session.createTimeseries(
-        "root.fyx.cq.dev.temp",
-        TSDataType.FLOAT,
-        TSEncoding.RLE,
-        CompressionType.SNAPPY,
-        null,
-        null,
-        null,
-        null);
-    // 创建多个时间序列
-    //        session.createMultiTimeseries();
-    // 插入数据
-    List<String> measurements = new ArrayList<>();
-    List<TSDataType> types = new ArrayList<>();
-    measurements.add("temp");
-    types.add(TSDataType.FLOAT);
-    for (long time = 0; time < 10; time++) {
-      List<Object> values = new ArrayList<>();
-      values.add(time * 6.6f);
-      // 如果不加type,服务器会做类型推断,会有额外耗时
-      session.insertRecord("root.fyx.cq.dev", time, measurements, types, values);
-    }
-    // 执行非查询语句的sql
-    session.executeNonQueryStatement(
-        "insert into root.fyx.cq.dev(timestamp,temp) values(now(),66.66)");
-    // 执行查询语句的sql
-    SessionDataSet sessionDataSet = session.executeQueryStatement("select * from root.fyx.cq.dev");
-    // 数据处理
-    int fetchSize = sessionDataSet.getFetchSize();
-    List<String> columnNames = sessionDataSet.getColumnNames();
-    List<TSDataType> columnTypes = sessionDataSet.getColumnTypes();
-    System.out.println(columnNames);
-    System.out.println(columnTypes);
-    if (fetchSize > 0) {
-      while (sessionDataSet.hasNext()) {
-        RowRecord next = sessionDataSet.next();
-        List<Field> fields = next.getFields();
-        // 查询结果第一个为时间戳
-        long timestamp = next.getTimestamp();
-        System.out.print(timestamp + "\t");
-        for (int i = 0; i < fields.size(); i++) {
-          Field field = fields.get(i);
-          // 这里的需要按照类型获取
-          System.out.print(field.getObjectValue(field.getDataType()));
-        }
-        System.out.println();
-      }
-    }
-    sessionDataSet.closeOperationHandle();
-    // 删除时间序列
-    session.deleteTimeseries("root.fyx.cq.dev.temp");
-    // 删除存储组
-    session.deleteStorageGroup("root.fyx");
-    session.close();
-  }
-}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java b/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
index 615ac99..22d1242 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
@@ -33,9 +33,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
-/** 拦截器 */
 public class TokenFilter implements HandlerInterceptor {
-
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
       throws BaseException {
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/RoleMapper.java
similarity index 75%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/mapper/RoleMapper.java
index 9030089..b791a52 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/RoleMapper.java
@@ -17,17 +17,12 @@
  * under the License.
  */
 
-package org.apache.iotdb.admin.model.vo;
+package org.apache.iotdb.admin.mapper;
 
-import lombok.Data;
+import org.apache.iotdb.admin.model.entity.Role;
 
-import java.io.Serializable;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Component;
 
-@Data
-public class DeviceVO implements Serializable {
-
-  private String description;
-  private String creator;
-  private String time;
-  private Integer deviceId;
-}
+@Component
+public interface RoleMapper extends BaseMapper<Role> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java
similarity index 87%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java
index 9b2246e..4a7ea78 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/AuthorityPrivilegeDTO.java
@@ -25,9 +25,8 @@ import java.io.Serializable;
 import java.util.List;
 
 @Data
-public class CountDTO<T> implements Serializable {
+public class AuthorityPrivilegeDTO implements Serializable {
+  private List<String> privileges;
 
-  private List<T> objects;
-  private Integer totalCount;
-  private Integer totalPage;
+  private List<String> cancelPrivileges;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
index d17f8ab..3841840 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
@@ -32,24 +32,24 @@ import java.io.Serializable;
 @Data
 public class ConnectionDTO implements Serializable {
 
-  @NotBlank(message = "主机地址不能为空或为null")
+  @NotBlank(message = "The host address cannot be empty or null")
   @Pattern(
       regexp =
           "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$",
-      message = "主机号输入不合法")
+      message = "The host is invalid")
   private String host;
 
-  @NotNull(message = "端口号不能为null")
-  @Range(min = 0, max = 65535, message = "端口号输入不合法")
+  @NotNull(message = "The port number cannot be null")
+  @Range(min = 0, max = 65535, message = "The host is invalid")
   private Integer port;
 
-  @NotBlank(message = "用户名不能为空或为null")
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
+  @NotBlank(message = "The username cannot be empty or null")
+  @Length(min = 4, message = "The username must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The username cannot contain spaces")
   private String username;
 
-  @NotBlank(message = "密码不能为空或为null")
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
+  @NotBlank(message = "The password cannot be empty or null")
+  @Length(min = 4, message = "The password must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The username cannot contain spaces")
   private String password;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
index 9b2246e..f287c90 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
@@ -26,7 +26,6 @@ import java.util.List;
 
 @Data
 public class CountDTO<T> implements Serializable {
-
   private List<T> objects;
   private Integer totalCount;
   private Integer totalPage;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataDeleteDTO.java
similarity index 74%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/DataDeleteDTO.java
index 366dff0..ef7bfb0 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataDeleteDTO.java
@@ -21,16 +21,18 @@ package org.apache.iotdb.admin.model.dto;
 
 import lombok.Data;
 
-import javax.validation.constraints.NotNull;
+import javax.validation.constraints.NotEmpty;
 
 import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 @Data
-public class SearchDTO implements Serializable {
+public class DataDeleteDTO implements Serializable {
 
-  private List<String> sqls;
+  @NotEmpty(message = "The timestamp list cannot be empty")
+  private List<Date> timestampList;
 
-  @NotNull(message = "不能为null")
-  private Long timestamp;
+  @NotEmpty(message = "The measurement list cannot be empty")
+  private List<String> measurementList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataQueryDTO.java
similarity index 77%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/DataQueryDTO.java
index 366dff0..f6b3f35 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataQueryDTO.java
@@ -21,16 +21,19 @@ package org.apache.iotdb.admin.model.dto;
 
 import lombok.Data;
 
-import javax.validation.constraints.NotNull;
+import javax.validation.constraints.NotEmpty;
 
 import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 @Data
-public class SearchDTO implements Serializable {
+public class DataQueryDTO implements Serializable {
 
-  private List<String> sqls;
+  private Date startTime;
 
-  @NotNull(message = "不能为null")
-  private Long timestamp;
+  private Date endTime;
+
+  @NotEmpty(message = "The measurement list cannot be empty")
+  private List<String> measurementList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataUpdateDTO.java
similarity index 71%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/DataUpdateDTO.java
index f2364af..c4f71f4 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataUpdateDTO.java
@@ -21,22 +21,22 @@ package org.apache.iotdb.admin.model.dto;
 
 import lombok.Data;
 
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Pattern;
 
 import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 @Data
-public class DeviceInfoDTO implements Serializable {
+public class DataUpdateDTO implements Serializable {
 
-  private List<DeviceDTO> deviceDTOList;
+  @NotNull(message = "The timestamp cannot be null")
+  private Date timestamp;
 
-  @NotNull(message = "设备名不能为null")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-  private String deviceName;
+  @NotEmpty(message = "The data value list cannot be empty")
+  private List<String> valueList;
 
-  private String description;
-
-  private Integer deviceId;
+  @NotEmpty(message = "The measurement list cannot be empty")
+  private List<String> measurementList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
index e26eea3..3d5f99f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
@@ -21,16 +21,31 @@ package org.apache.iotdb.admin.model.dto;
 
 import lombok.Data;
 
+import javax.validation.constraints.NotEmpty;
+
 import java.io.Serializable;
+import java.util.List;
 
 @Data
 public class DeviceDTO implements Serializable {
 
+  @NotEmpty(message = "The measurement cannot be empty")
   private String timeseries;
 
+  @NotEmpty(message = "The data type cannot be empty")
   private String dataType;
 
+  @NotEmpty(message = "The encoding cannot be empty")
   private String encoding;
 
   private String description;
+
+  private String alias;
+
+  @NotEmpty(message = "The compression cannot be empty")
+  private String compression;
+
+  private List<List<String>> tags;
+
+  private List<List<String>> attributes;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
index f2364af..a47413d 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
@@ -21,6 +21,8 @@ package org.apache.iotdb.admin.model.dto;
 
 import lombok.Data;
 
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
 
@@ -30,10 +32,12 @@ import java.util.List;
 @Data
 public class DeviceInfoDTO implements Serializable {
 
+  @NotEmpty(message = "The measurement list cannot be empty")
+  @Valid
   private List<DeviceDTO> deviceDTOList;
 
-  @NotNull(message = "设备名不能为null")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  @NotNull(message = "The device name cannot be null")
+  @Pattern(regexp = "^[^ ]+$", message = "The device name cannot contain spaces")
   private String deviceName;
 
   private String description;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
index 3e751b9..c49aa14 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
@@ -29,8 +29,8 @@ import java.io.Serializable;
 @Data
 public class GroupDTO implements Serializable {
 
-  @NotNull(message = "存储组名不能为null")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  @NotNull(message = "The storage group name cannot be null")
+  @Pattern(regexp = "^[^ ]+$", message = "The storage group name cannot contain spaces")
   private String groupName;
 
   private String description;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
index 4a25786..a25a5b5 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
@@ -22,15 +22,18 @@ package org.apache.iotdb.admin.model.dto;
 import lombok.Data;
 import org.hibernate.validator.constraints.Length;
 
+import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
-import java.util.List;
 
-/** 传输role信息类 */
 @Data
 public class IotDBRole implements Serializable {
 
-  @Length(min = 4, message = "长度必须大于等于4")
+  private Integer id;
+
+  @Length(min = 4, message = "The username must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The role name cannot contain spaces")
   private String roleName;
 
-  private List<String> privileges;
+  private String description;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
index d0beb5b..374ecb2 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
@@ -26,19 +26,14 @@ import javax.validation.constraints.Pattern;
 
 import java.io.Serializable;
 
-/** 传输User信息类 */
 @Data
 public class IotDBUser implements Serializable {
 
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  @Length(min = 4, message = "The username must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The username cannot contain spaces")
   private String userName;
 
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  @Length(min = 4, message = "The password must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The password cannot contain spaces")
   private String password;
-
-  //    private List<String> privileges;
-  //
-  //    private List<String> roles;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
index 7b2eda7..27048c2 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
@@ -25,7 +25,6 @@ import java.io.Serializable;
 
 @Data
 public class MeasurementDTO implements Serializable {
-
   private String timeseries;
   private String alias;
   private String storagegroup;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
index 7e55404..646938e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
@@ -26,8 +26,7 @@ import java.util.List;
 
 @Data
 public class PrivilegeInfoDTO implements Serializable {
-
-  // 0 1 2 3 对应 root、storageGroup、device、timeseries
+  // 0, 1, 2, 3 corresponding to root, storageGroup, device, timeseries
   private Integer type;
   private List<String> groupPaths;
   private List<String> devicePaths;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/RandomImportDTO.java
similarity index 62%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/RandomImportDTO.java
index f2364af..f037d0f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/RandomImportDTO.java
@@ -20,23 +20,25 @@
 package org.apache.iotdb.admin.model.dto;
 
 import lombok.Data;
+import org.hibernate.validator.constraints.Range;
 
+import javax.validation.constraints.Min;
 import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Pattern;
 
 import java.io.Serializable;
-import java.util.List;
+import java.util.Date;
 
 @Data
-public class DeviceInfoDTO implements Serializable {
+public class RandomImportDTO implements Serializable {
 
-  private List<DeviceDTO> deviceDTOList;
+  @NotNull(message = "The start time cannot be null")
+  private Date startTime;
 
-  @NotNull(message = "设备名不能为null")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-  private String deviceName;
+  @NotNull(message = "The step size cannot be null")
+  @Min(value = 1, message = "The step size must be at least 1ms")
+  private Integer stepSize;
 
-  private String description;
-
-  private Integer deviceId;
+  @NotNull(message = "The data line cannot be null")
+  @Range(min = 1, max = 1000000, message = "The number of data lines is between 1 and 1000000")
+  private Integer totalLine;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/RoleGrantDTO.java
similarity index 87%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/RoleGrantDTO.java
index 9b2246e..bd6fe87 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/RoleGrantDTO.java
@@ -25,9 +25,9 @@ import java.io.Serializable;
 import java.util.List;
 
 @Data
-public class CountDTO<T> implements Serializable {
+public class RoleGrantDTO implements Serializable {
 
-  private List<T> objects;
-  private Integer totalCount;
-  private Integer totalPage;
+  private List<String> UserList;
+
+  private List<String> cancelUserList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
index 366dff0..b9a3dea 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
@@ -31,6 +31,6 @@ public class SearchDTO implements Serializable {
 
   private List<String> sqls;
 
-  @NotNull(message = "不能为null")
+  @NotNull(message = "Timestamp cannot be null")
   private Long timestamp;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/UserGrantDTO.java
similarity index 87%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/dto/UserGrantDTO.java
index 9b2246e..67c98bf 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/UserGrantDTO.java
@@ -25,9 +25,9 @@ import java.io.Serializable;
 import java.util.List;
 
 @Data
-public class CountDTO<T> implements Serializable {
+public class UserGrantDTO implements Serializable {
 
-  private List<T> objects;
-  private Integer totalCount;
-  private Integer totalPage;
+  private List<String> roleList;
+
+  private List<String> cancelRoleList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
index 9080433..10eccec 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
@@ -37,32 +37,32 @@ public class Connection implements Serializable {
   @TableId(type = IdType.AUTO)
   private Integer id;
 
-  @NotBlank(message = "主机地址不能为空或为null")
+  @NotBlank(message = "The host address cannot be empty or null")
   @Pattern(
       regexp =
           "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$",
-      message = "主机号输入不合法")
+      message = "The host is invalid")
   private String host;
 
-  @NotNull(message = "端口号不能为null")
-  @Range(min = 0, max = 65535, message = "端口号输入不合法")
+  @NotNull(message = "The port number cannot be null")
+  @Range(min = 0, max = 65535, message = "The host is invalid")
   private Integer port;
 
-  @NotBlank(message = "用户名不能为空或为null")
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
+  @NotBlank(message = "The username cannot be empty or null")
+  @Length(min = 4, message = "The username must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The username cannot contain spaces")
   private String username;
 
-  @NotBlank(message = "密码不能为空或为null")
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
+  @NotBlank(message = "The password cannot be empty or null")
+  @Length(min = 4, message = "The password must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The username cannot contain spaces")
   private String password;
 
-  @NotBlank(message = "连接名不能为空或为null")
-  @Length(min = 3, max = 100, message = "连接名长度必须在3-100之间")
-  @Pattern(regexp = "^[^ ]+$", message = "连接名不能包含空格")
+  @NotBlank(message = "The connection name cannot be empty or null")
+  @Length(min = 3, max = 100, message = "The connection name must be between 3 and 100")
+  @Pattern(regexp = "^[^ ]+$", message = "The connection name cannot contains spaces")
   private String alias;
 
-  @NotNull(message = "用户id不能为null")
+  @NotNull(message = "The user id cannot be null")
   private Integer userId;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
index 7ce33e1..8e5d2fe 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
@@ -36,20 +36,20 @@ public class Device implements Serializable {
   @TableId(type = IdType.AUTO)
   private Integer id;
 
-  @NotNull(message = "未指定所属主机")
+  @NotNull(message = "The host cannot be null")
   private String host;
 
   private String description;
 
   @NotBlank
-  @Length(min = 4, message = "创建者名长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
+  @Length(min = 4, message = "The creator name must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The creator name cannot contains spaces")
   private String creator;
 
-  @NotNull(message = "未指定创建时间")
+  @NotNull(message = "The create time cannot be null")
   private Long createTime;
 
   @NotBlank
-  @Pattern(regexp = "^[^ ]+$", message = "设备名不能包含空格")
+  @Pattern(regexp = "^[^ ]+$", message = "The device name cannot contains spaces")
   private String deviceName;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
index 43f15f2..ae7fe50 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
@@ -33,10 +33,10 @@ public class Measurement implements Serializable {
   @TableId(type = IdType.AUTO)
   private Integer id;
 
-  @NotNull(message = "未指定所属主机")
+  @NotNull(message = "The host cannot be null")
   private String host;
 
-  @NotNull(message = "未指定测点名")
+  @NotNull(message = "The measurement name cannot be null")
   private String measurementName;
 
   private String description;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
index f2b7898..e9c741a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
@@ -33,10 +33,10 @@ public class Query implements Serializable {
   @TableId(type = IdType.AUTO)
   private Integer id;
 
-  @NotNull(message = "未指定所属连接id")
+  @NotNull(message = "The connection id cannot be null")
   private Integer connectionId;
 
-  @NotNull(message = "未指定脚本名")
+  @NotNull(message = "The query name cannot be null")
   private String queryName;
 
   private String sqls;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Role.java
similarity index 75%
copy from backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/entity/Role.java
index 43f15f2..17a8bf7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Role.java
@@ -22,22 +22,27 @@ package org.apache.iotdb.admin.model.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import lombok.Data;
+import org.hibernate.validator.constraints.Length;
 
 import javax.validation.constraints.NotNull;
 
 import java.io.Serializable;
 
 @Data
-public class Measurement implements Serializable {
+public class Role implements Serializable {
 
   @TableId(type = IdType.AUTO)
   private Integer id;
 
-  @NotNull(message = "未指定所属主机")
+  @NotNull(message = "The role name cannot be null")
+  @Length(min = 4, message = "The role name must contain at least 4 characters")
+  private String name;
+
+  @NotNull(message = "The host cannot be null")
   private String host;
 
-  @NotNull(message = "未指定测点名")
-  private String measurementName;
+  @NotNull(message = "The port cannot be null")
+  private Integer port;
 
   private String description;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
index 8550ac8..fb72929 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
@@ -36,17 +36,17 @@ public class StorageGroup implements Serializable {
   @TableId(type = IdType.AUTO)
   private Integer id;
 
-  @NotNull(message = "未指定所属主机")
+  @NotNull(message = "The host cannot be null")
   private String host;
 
   private String description;
 
   @NotBlank
-  @Length(min = 4, message = "创建者名长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
+  @Length(min = 4, message = "The creator name must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The creator name cannot contains spaces")
   private String creator;
 
-  @NotNull(message = "未指定创建时间")
+  @NotNull(message = "The create time cannot be null")
   private Long createTime;
 
   @NotBlank private String groupName;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
index c778fd7..4b82cbd 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
@@ -38,12 +38,12 @@ public class User implements Serializable {
   private Integer id;
 
   @NotBlank
-  @Length(min = 4, message = "长度必须大于等于4")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  @Length(min = 4, message = "The account name must contain at least 4 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The account name cannot contain spaces")
   private String name;
 
   @NotBlank
-  @Length(min = 6, message = "长度必须大于等于6")
-  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  @Length(min = 6, message = "The account password must contain at least 6 characters")
+  @Pattern(regexp = "^[^ ]+$", message = "The account password cannot contain spaces")
   private String password;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
index 23eec26..6bfc8df 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
@@ -21,17 +21,15 @@ package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
-/** 返回信息类 */
+/** Return base class */
 @Data
 public class BaseVO<T> {
 
-  /** 0 表示成功 其他表示错误类型 */
+  /** 0 indicates success and other indicates error types */
   private String code;
 
-  /** 定义出错时候用户可读的信息 */
   private String message;
 
-  /** 这是一个返回数据的通用类型模板 */
   private T data;
 
   public BaseVO() {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
index 0f33ac9..6e2debd 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
@@ -25,12 +25,14 @@ import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
 
-/** 展示别名及serverId */
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class ConnVO implements Serializable {
-
   private Integer id;
   private String alias;
+  private String host;
+  private Integer port;
+  private String username;
+  private String password;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
index ff7df4a..4ee6f87 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
@@ -26,7 +26,6 @@ import lombok.NoArgsConstructor;
 import java.io.Serializable;
 import java.util.List;
 
-/** 展示用户的连接列表 */
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java
similarity index 83%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java
index 0848dbe..cdef28c 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataCountVO.java
@@ -24,8 +24,9 @@ import lombok.Data;
 import java.io.Serializable;
 
 @Data
-public class QueryVO implements Serializable {
-
-  private Integer id;
-  private String queryName;
+public class DataCountVO implements Serializable {
+  private Integer groupCount;
+  private Integer deviceCount;
+  private Integer measurementCount;
+  private Integer dataCount;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataInfo.java
similarity index 87%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/DataInfo.java
index 3606c51..8c58ff9 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataInfo.java
@@ -24,11 +24,10 @@ import lombok.Data;
 import java.io.Serializable;
 
 @Data
-public class MeasurementVO implements Serializable {
-
-  private String timeseries;
+public class DataInfo implements Serializable {
   private String dataType;
-  private String encoding;
-  private String description;
+
   private String newValue;
+
+  private Integer dataCount;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java
similarity index 58%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java
index f60f74d..2763728 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataModelVO.java
@@ -19,18 +19,45 @@
 
 package org.apache.iotdb.admin.model.vo;
 
-import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 
 @Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class GroupInfoVO implements Serializable {
+public class DataModelVO implements Serializable {
+  private String name;
+
+  private Boolean isGroup;
+
+  private Boolean isDevice;
+
+  private Boolean isMeasurement;
+
+  private Integer groupCount;
 
-  private String groupName;
   private Integer deviceCount;
-  private String description;
+
+  private Integer measurementCount;
+
+  private DataInfo dataInfo;
+
+  private String path;
+
+  private List<DataModelVO> children;
+
+  public DataModelVO(String name) {
+    this.name = name;
+    this.isGroup = false;
+    this.isDevice = false;
+    this.isMeasurement = false;
+  }
+
+  public List<DataModelVO> initNodeChildren() {
+    if (children == null) {
+      children = new ArrayList<>();
+    }
+    return children;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataPrivilegeVO.java
similarity index 76%
copy from backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/DataPrivilegeVO.java
index 7e55404..52850ba 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataPrivilegeVO.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.admin.model.dto;
+package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
@@ -25,16 +25,14 @@ import java.io.Serializable;
 import java.util.List;
 
 @Data
-public class PrivilegeInfoDTO implements Serializable {
-
-  // 0 1 2 3 对应 root、storageGroup、device、timeseries
+public class DataPrivilegeVO implements Serializable {
+  // 0, 1, 2, 3 corresponding to root, storageGroup, device, timeseries
   private Integer type;
   private List<String> groupPaths;
   private List<String> devicePaths;
   private List<String> timeseriesPaths;
   private List<String> privileges;
-  private List<String> cancelPrivileges;
-  private List<String> delGroupPaths;
-  private List<String> delDevicePaths;
-  private List<String> delTimeseriesPaths;
+  private List<String> allTimeseriesPaths;
+  private List<NodeTreeVO> allDevicePaths;
+  private List<NodeTreeVO> allGroupPaths;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataVO.java
similarity index 86%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/DataVO.java
index d8ba158..ef34613 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DataVO.java
@@ -24,12 +24,11 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.List;
 
-/** sql查询的元数据列表和数据列表 */
 @Data
-public class SqlResultVO implements Serializable {
-
+public class DataVO implements Serializable {
   private List<String> metaDataList;
   private List<List<String>> valueList;
-  private String queryTime;
-  private Long line;
+  private List<String> typeList;
+  private Integer totalCount;
+  private Integer totalPage;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
index b182eef..ca6d7a7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
@@ -22,13 +22,14 @@ package org.apache.iotdb.admin.model.vo;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.List;
 
 @Data
 public class DeviceInfo implements Serializable {
-
   private String deviceName;
   private String description;
   private String creator;
   private Integer line;
   private Integer deviceId;
+  private List<String> parents;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
index 779973a..9fb33f3 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
@@ -26,7 +26,6 @@ import java.util.List;
 
 @Data
 public class DeviceInfoVO implements Serializable {
-
   private List<DeviceInfo> deviceInfos;
   private Integer totalCount;
   private Integer totalPage;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
index 9030089..8f2b66f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
@@ -25,7 +25,6 @@ import java.io.Serializable;
 
 @Data
 public class DeviceVO implements Serializable {
-
   private String description;
   private String creator;
   private String time;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
index f60f74d..512deb7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
@@ -29,7 +29,6 @@ import java.io.Serializable;
 @NoArgsConstructor
 @AllArgsConstructor
 public class GroupInfoVO implements Serializable {
-
   private String groupName;
   private Integer deviceCount;
   private String description;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
index 09eeae3..352442b 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
@@ -25,7 +25,6 @@ import java.io.Serializable;
 
 @Data
 public class GroupVO implements Serializable {
-
   private String groupName;
   private String alias;
   private String description;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ImportDataVO.java
similarity index 74%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/ImportDataVO.java
index 1c56d63..d618b61 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ImportDataVO.java
@@ -22,12 +22,18 @@ package org.apache.iotdb.admin.model.vo;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.List;
 
 @Data
-public class MeasuremtnInfoVO implements Serializable {
-
-  private List<MeasurementVO> measurementVOList;
+public class ImportDataVO implements Serializable {
   private Integer totalCount;
-  private Integer totalPage;
+
+  private Integer failCount;
+
+  private String fileDownloadUri;
+
+  public ImportDataVO(Integer totalCount, Integer failCount, String fileDownloadUri) {
+    this.totalCount = totalCount;
+    this.failCount = failCount;
+    this.fileDownloadUri = fileDownloadUri;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
index 3606c51..a934231 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
@@ -22,13 +22,18 @@ package org.apache.iotdb.admin.model.vo;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.List;
 
 @Data
 public class MeasurementVO implements Serializable {
-
   private String timeseries;
   private String dataType;
   private String encoding;
   private String description;
   private String newValue;
+  private Integer dataCount;
+  private String alias;
+  private String compression;
+  private List<List<String>> tags;
+  private List<List<String>> attributes;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
index 1c56d63..d46fd4a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
@@ -26,7 +26,6 @@ import java.util.List;
 
 @Data
 public class MeasuremtnInfoVO implements Serializable {
-
   private List<MeasurementVO> measurementVOList;
   private Integer totalCount;
   private Integer totalPage;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java
similarity index 73%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java
index 1c56d63..cfa4acc 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java
@@ -22,12 +22,23 @@ package org.apache.iotdb.admin.model.vo;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 @Data
-public class MeasuremtnInfoVO implements Serializable {
+public class NodeTreeVO implements Serializable {
+  private String name;
 
-  private List<MeasurementVO> measurementVOList;
-  private Integer totalCount;
-  private Integer totalPage;
+  private List<NodeTreeVO> children;
+
+  public NodeTreeVO(String name) {
+    this.name = name;
+  }
+
+  public List<NodeTreeVO> initChildren() {
+    if (children == null) {
+      children = new ArrayList<>();
+    }
+    return children;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
index 0848dbe..6578d2e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
@@ -25,7 +25,6 @@ import java.io.Serializable;
 
 @Data
 public class QueryVO implements Serializable {
-
   private Integer id;
   private String queryName;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
index 696931e..4238b84 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
@@ -24,10 +24,13 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 @Data
 public class RecordVO implements Serializable {
-
   private List<Date> timeList;
-  private List<Long> valueList;
+
+  private List<String> valueList;
+
+  private Map<String, Integer> textCount;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleVO.java
similarity index 88%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleVO.java
index 9030089..6b683ba 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleVO.java
@@ -22,12 +22,13 @@ package org.apache.iotdb.admin.model.vo;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.List;
 
 @Data
-public class DeviceVO implements Serializable {
-
+public class RoleVO implements Serializable {
   private String description;
-  private String creator;
-  private String time;
-  private Integer deviceId;
+
+  private List<String> userList;
+
+  private Integer id;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
index d8ba158..4cffeac 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
@@ -24,10 +24,8 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.List;
 
-/** sql查询的元数据列表和数据列表 */
 @Data
 public class SqlResultVO implements Serializable {
-
   private List<String> metaDataList;
   private List<List<String>> valueList;
   private String queryTime;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
index 3303d9e..5dc1766 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
@@ -25,7 +25,6 @@ import java.io.Serializable;
 
 @Data
 public class StorageGroupVO implements Serializable {
-
   private String groupName;
   private Integer groupId;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/UserRolesVO.java
similarity index 87%
copy from backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
copy to backend/src/main/java/org/apache/iotdb/admin/model/vo/UserRolesVO.java
index 696931e..25721c1 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/UserRolesVO.java
@@ -22,12 +22,12 @@ package org.apache.iotdb.admin.model.vo;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.Date;
 import java.util.List;
 
 @Data
-public class RecordVO implements Serializable {
+public class UserRolesVO implements Serializable {
 
-  private List<Date> timeList;
-  private List<Long> valueList;
+  private String password;
+
+  private List<String> roleList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java b/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
index b5829a5..64317c4 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
@@ -26,7 +26,6 @@ import org.apache.iotdb.admin.model.vo.ConnVO;
 import java.util.List;
 
 public interface ConnectionService {
-
   List<ConnVO> getAllConnections(Integer id);
 
   void insert(Connection connection) throws BaseException;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java b/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
index d1de1b9..89b4d67 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
@@ -28,7 +28,6 @@ import org.apache.iotdb.admin.model.vo.DeviceVO;
 import java.util.List;
 
 public interface DeviceService {
-
   List<Device> getDevices(String host, List<String> deviceNames);
 
   void deleteDeviceInfo(String host, String groupName) throws BaseException;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java b/backend/src/main/java/org/apache/iotdb/admin/service/FileService.java
similarity index 76%
copy from backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
copy to backend/src/main/java/org/apache/iotdb/admin/service/FileService.java
index fb9c1e2..5a88461 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/FileService.java
@@ -20,13 +20,12 @@
 package org.apache.iotdb.admin.service;
 
 import org.apache.iotdb.admin.common.exception.BaseException;
-import org.apache.iotdb.admin.model.entity.User;
 
-public interface UserService {
+import org.springframework.core.io.Resource;
+import org.springframework.web.multipart.MultipartFile;
 
-  User login(String name, String password) throws BaseException;
+public interface FileService {
+  String storeFile(MultipartFile file, String fileName) throws BaseException;
 
-  void insert(User user) throws BaseException;
-
-  void delete(Integer userId) throws BaseException;
+  Resource loadFileAsResource(String fileName) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java b/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
index 76ee8c5..c08e04a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
@@ -27,7 +27,6 @@ import org.apache.iotdb.admin.model.entity.StorageGroup;
 import java.util.List;
 
 public interface GroupService {
-
   List<String> getGroupDescription(String host, List<String> groupNames) throws BaseException;
 
   void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
index 83c6a4a..70cd585 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
@@ -22,16 +22,20 @@ package org.apache.iotdb.admin.service;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.model.dto.*;
 import org.apache.iotdb.admin.model.entity.Connection;
-import org.apache.iotdb.admin.model.vo.IotDBUserVO;
-import org.apache.iotdb.admin.model.vo.RecordVO;
-import org.apache.iotdb.admin.model.vo.SqlResultVO;
+import org.apache.iotdb.admin.model.vo.*;
 
 import java.util.List;
+import java.util.Set;
 
 public interface IotDBService {
+  DataCountVO getDataCount(Connection connection) throws BaseException;
+
+  DataModelVO getDataModel(Connection connection) throws BaseException;
 
   List<String> getAllStorageGroups(Connection connection) throws BaseException;
 
+  List<NodeTreeVO> getGroupsNodeTree(Connection connection) throws BaseException;
+
   void saveStorageGroup(Connection connection, String groupName) throws BaseException;
 
   void deleteStorageGroup(Connection connection, String groupName) throws BaseException;
@@ -48,7 +52,7 @@ public interface IotDBService {
 
   List<String> getIotDBRoleList(Connection connection) throws BaseException;
 
-  IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException;
+  RoleVO getIotDBRoleInfo(Connection connection, String roleName) throws BaseException;
 
   void deleteIotDBUser(Connection connection, String userName) throws BaseException;
 
@@ -58,12 +62,36 @@ public interface IotDBService {
 
   void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException;
 
-  void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries)
+  UserRolesVO getRolesOfUser(Connection connection, String userName) throws BaseException;
+
+  void userGrant(Connection connection, String userName, UserGrantDTO userGrantDTO)
       throws BaseException;
 
-  void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException;
+  void roleGrant(Connection connection, String roleName, RoleGrantDTO roleGrantDTO)
+      throws BaseException;
+
+  Set<String> getUserAuthorityPrivilege(Connection connection, String userName)
+      throws BaseException;
+
+  Set<String> getAllAuthorityPrivilege(Connection connection, String userName) throws BaseException;
+
+  Set<String> getRoleAuthorityPrivilege(Connection connection, String roleName)
+      throws BaseException;
 
-  SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException;
+  void upsertAuthorityPrivilege(
+      Connection connection,
+      String userName,
+      AuthorityPrivilegeDTO authorityPrivilegeDTO,
+      String userOrRole)
+      throws BaseException;
+
+  List<DataPrivilegeVO> getUserDataPrivilege(Connection connection, String userName)
+      throws BaseException;
+
+  List<DataPrivilegeVO> getRoleDataPrivilege(Connection connection, String roleName)
+      throws BaseException;
+
+  void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException;
 
   List<Integer> getDevicesCount(Connection connection, List<String> groupNames)
       throws BaseException;
@@ -72,17 +100,16 @@ public interface IotDBService {
 
   void cancelGroupTtl(Connection connection, String groupName) throws BaseException;
 
-  Integer getDeviceCount(Connection connection, String groupName) throws BaseException;
-
   List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames)
       throws BaseException;
 
-  void deleteTimeseriesByDevice(Connection connection, String deviceName) throws BaseException;
-
-  void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO)
+  List<String> deleteTimeseriesByDevice(Connection connection, String deviceName)
       throws BaseException;
 
-  Integer getMeasurementsCount(Connection connection, String deviceName) throws BaseException;
+  void upsertMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+
+  Integer getOneDataCount(Connection connection, String deviceName, String measurementName)
+      throws BaseException;
 
   String getLastMeasurementValue(Connection connection, String timeseries) throws BaseException;
 
@@ -90,12 +117,43 @@ public interface IotDBService {
 
   List<String> getDevices(Connection connection, String groupName) throws BaseException;
 
+  List<NodeTreeVO> getDeviceNodeTree(Connection connection, String groupName) throws BaseException;
+
+  NodeTreeVO getDeviceList(Connection connection, String groupName) throws BaseException;
+
+  List<String> getDeviceParents(Connection connection, String groupName, String deviceName)
+      throws BaseException;
+
+  Boolean deviceExist(Connection connection, String groupName, String deviceName)
+      throws BaseException;
+
   List<String> getTimeseries(Connection connection, String deviceName) throws BaseException;
 
-  void setUserPrivileges(Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO)
+  DataVO getDataByDevice(
+      Connection connection,
+      String deviceName,
+      Integer pageSize,
+      Integer pageNum,
+      DataQueryDTO dataQueryDTO)
+      throws BaseException;
+
+  void updateDataByDevice(Connection connection, String deviceName, DataUpdateDTO dataUpdateDTO)
+      throws BaseException;
+
+  void deleteDataByDevice(Connection connection, String deviceName, DataDeleteDTO dataDeleteDTO)
+      throws BaseException;
+
+  void randomImport(Connection connection, String deviceName, RandomImportDTO randomImportDTO)
+      throws BaseException;
+
+  String getSqlForExport(String deviceName, DataQueryDTO dataQueryDTO) throws BaseException;
+
+  void upsertDataPrivileges(
+      Connection connection, String userOrRole, String name, PrivilegeInfoDTO privilegeInfoDTO)
       throws BaseException;
 
-  RecordVO getRecords(Connection connection, String deviceName, String timeseriesName)
+  RecordVO getRecords(
+      Connection connection, String deviceName, String timeseriesName, String dataType)
       throws BaseException;
 
   List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp)
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
index 1c0e699..c9c7845 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
 
 public interface MeasurementService {
-
   void deleteMeasurementInfo(String host, String groupName) throws BaseException;
 
   void deleteMeasurementInfoByDeviceName(String host, String deviceName) throws BaseException;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java b/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
index eeb8138..67efaf4 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
@@ -26,8 +26,7 @@ import org.apache.iotdb.admin.model.vo.QueryVO;
 import java.util.List;
 
 public interface QueryService {
-
-  void save(Integer serverId, Query query) throws BaseException;
+  Integer save(Integer serverId, Query query) throws BaseException;
 
   void update(Integer serverId, Query query) throws BaseException;
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java b/backend/src/main/java/org/apache/iotdb/admin/service/RoleService.java
similarity index 69%
copy from backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
copy to backend/src/main/java/org/apache/iotdb/admin/service/RoleService.java
index fb9c1e2..002d61e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/RoleService.java
@@ -20,13 +20,13 @@
 package org.apache.iotdb.admin.service;
 
 import org.apache.iotdb.admin.common.exception.BaseException;
-import org.apache.iotdb.admin.model.entity.User;
+import org.apache.iotdb.admin.model.dto.IotDBRole;
+import org.apache.iotdb.admin.model.entity.Role;
 
-public interface UserService {
+public interface RoleService {
+  void upsertRoleInfo(String host, Integer port, IotDBRole iotDBRole) throws BaseException;
 
-  User login(String name, String password) throws BaseException;
+  void deleteRoleInfo(String host, Integer port, String roleName) throws BaseException;
 
-  void insert(User user) throws BaseException;
-
-  void delete(Integer userId) throws BaseException;
+  Role getRoleInfo(String host, Integer port, String roleName) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java b/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
index fb9c1e2..449373f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.model.entity.User;
 
 public interface UserService {
-
   User login(String name, String password) throws BaseException;
 
   void insert(User user) throws BaseException;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
index 670f0cb..11f036b 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
@@ -47,7 +47,14 @@ public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connect
     List<Connection> connections = connectionMapper.selectList(queryWrapper);
     List<ConnVO> ConnVOs = new ArrayList();
     for (Connection connection : connections) {
-      ConnVOs.add(new ConnVO(connection.getId(), connection.getAlias()));
+      ConnVOs.add(
+          new ConnVO(
+              connection.getId(),
+              connection.getAlias(),
+              connection.getHost(),
+              connection.getPort(),
+              connection.getUsername(),
+              connection.getPassword()));
     }
     return ConnVOs;
   }
@@ -60,13 +67,10 @@ public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connect
     queryWrapper.eq("user_id", userId);
     queryWrapper.eq("alias", alias);
     Connection existConnection = connectionMapper.selectOne(queryWrapper);
-    // 别名唯一
+    // Alias are unique
     if (existConnection != null) {
       throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
     }
-    if ("127.0.0.1".equals(connection.getHost())) {
-      connection.setHost("localhost");
-    }
     int flag = connectionMapper.insert(connection);
     if (flag <= 0) {
       throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
@@ -116,7 +120,7 @@ public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connect
     queryWrapper.eq("user_id", userId);
     queryWrapper.eq("alias", alias);
     Connection existConnection = connectionMapper.selectOne(queryWrapper);
-    // 别名唯一
+    // Alias are unique
     if (existConnection != null && !connection.getId().equals(existConnection.getId())) {
       throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
     }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
index 0687f5c..7ff9ad3 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
@@ -115,7 +115,7 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
     queryWrapper.eq("host", host);
     queryWrapper.eq("device_name", deviceName);
     Device device = deviceMapper.selectOne(queryWrapper);
-    // 非系统创建的设备没有设备信息
+    // Non-system created devices do not have device information
     DeviceVO deviceVO = new DeviceVO();
     if (device != null) {
       deviceVO.setCreator(device.getCreator());
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/FileServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/FileServiceImpl.java
new file mode 100644
index 0000000..0942f55
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/FileServiceImpl.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.config.FileProperties;
+import org.apache.iotdb.admin.service.FileService;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+@Service
+public class FileServiceImpl implements FileService {
+
+  private final Path fileStorageLocation;
+
+  @Autowired
+  public FileServiceImpl(FileProperties fileProperties) {
+    this.fileStorageLocation = Paths.get(fileProperties.getTempDir()).toAbsolutePath().normalize();
+  }
+
+  @Override
+  public String storeFile(MultipartFile file, String fileName) throws BaseException {
+    try {
+      Path targetLocation = this.fileStorageLocation.resolve(fileName);
+      Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
+      String fileFullName = targetLocation.toString();
+      return fileFullName;
+    } catch (IOException ex) {
+      throw new BaseException(ErrorCode.UPLOAD_FILE_FAIL, ErrorCode.UPLOAD_FILE_FAIL_MSG);
+    }
+  }
+
+  @Override
+  public Resource loadFileAsResource(String fileName) throws BaseException {
+    Path filePath;
+    try {
+      filePath = this.fileStorageLocation.resolve(fileName).normalize();
+      Resource resource = new UrlResource(filePath.toUri());
+      if (resource.exists()) {
+        return resource;
+      } else {
+        throw new BaseException(ErrorCode.FILE_NOT_FOUND, ErrorCode.FILE_NOT_FOUND_MSG);
+      }
+    } catch (MalformedURLException ex) {
+      throw new BaseException(ErrorCode.FILE_NOT_FOUND, ErrorCode.FILE_NOT_FOUND_MSG);
+    }
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
index 5ae53be..3a81a14 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
@@ -57,9 +57,6 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, StorageGroup>
     String host = connection.getHost();
     String groupName = groupDTO.getGroupName();
     String description = groupDTO.getDescription();
-    if ("127.0.0.1".equals(host)) {
-      host = "localhost";
-    }
     queryWrapper.eq("host", host);
     queryWrapper.eq("group_name", groupName);
     StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
index 1c56635..803c4f5 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
@@ -34,78 +34,328 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.common.RowRecord;
 
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import java.lang.reflect.Field;
-import java.sql.*;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.Date;
 import java.util.concurrent.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @Service
 public class IotDBServiceImpl implements IotDBService {
 
   private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
 
-  private static final HashMap<String, Boolean> SPECIAL_PRIVILEGES = new HashMap();
+  private static final Set<String> AUTHORITY_PRIVILEGES = new HashSet<>();
 
-  private static final String NO_NEED_PRIVILEGES = "SET_STORAGE_GROUP";
-
-  private static final List<String> PRIVILEGES = new ArrayList<>();
+  private static final Set<String> DATA_PRIVILEGES = new HashSet<>();
 
   private static final HashMap<String, Boolean> QUERY_STOP = new HashMap<>();
 
   static {
-    SPECIAL_PRIVILEGES.put("CREATE_TIMESERIES", true);
-    SPECIAL_PRIVILEGES.put("INSERT_TIMESERIES", true);
-    SPECIAL_PRIVILEGES.put("READ_TIMESERIES", true);
-    SPECIAL_PRIVILEGES.put("DELETE_TIMESERIES", true);
+    AUTHORITY_PRIVILEGES.add("CREATE_USER");
+    AUTHORITY_PRIVILEGES.add("DELETE_USER");
+    AUTHORITY_PRIVILEGES.add("MODIFY_PASSWORD");
+    AUTHORITY_PRIVILEGES.add("LIST_USER");
+    AUTHORITY_PRIVILEGES.add("GRANT_USER_PRIVILEGE");
+    AUTHORITY_PRIVILEGES.add("REVOKE_USER_PRIVILEGE");
+    AUTHORITY_PRIVILEGES.add("GRANT_USER_ROLE");
+    AUTHORITY_PRIVILEGES.add("REVOKE_USER_ROLE");
+    AUTHORITY_PRIVILEGES.add("CREATE_ROLE");
+    AUTHORITY_PRIVILEGES.add("DELETE_ROLE");
+    AUTHORITY_PRIVILEGES.add("LIST_ROLE");
+    AUTHORITY_PRIVILEGES.add("GRANT_ROLE_PRIVILEGE");
+    AUTHORITY_PRIVILEGES.add("REVOKE_ROLE_PRIVILEGE");
+    AUTHORITY_PRIVILEGES.add("CREATE_FUNCTION");
+    AUTHORITY_PRIVILEGES.add("DROP_FUNCTION");
+    AUTHORITY_PRIVILEGES.add("CREATE_TRIGGER");
+    AUTHORITY_PRIVILEGES.add("DROP_TRIGGER");
+    AUTHORITY_PRIVILEGES.add("START_TRIGGER");
+    AUTHORITY_PRIVILEGES.add("STOP_TRIGGER");
   }
 
   static {
-    PRIVILEGES.add("SET_STORAGE_GROUP");
-    PRIVILEGES.add("CREATE_TIMESERIES");
-    PRIVILEGES.add("INSERT_TIMESERIES");
-    PRIVILEGES.add("READ_TIMESERIES");
-    PRIVILEGES.add("DELETE_TIMESERIES");
-    PRIVILEGES.add("CREATE_USER");
-    PRIVILEGES.add("DELETE_USER");
-    PRIVILEGES.add("MODIFY_PASSWORD");
-    PRIVILEGES.add("LIST_USER");
-    PRIVILEGES.add("GRANT_USER_PRIVILEGE");
-    PRIVILEGES.add("REVOKE_USER_PRIVILEGE");
-    PRIVILEGES.add("CREATE_FUNCTION");
-    PRIVILEGES.add("DROP_FUNCTION");
-    PRIVILEGES.add("CREATE_TRIGGER");
-    PRIVILEGES.add("DROP_TRIGGER");
-    PRIVILEGES.add("START_TRIGGER");
-    PRIVILEGES.add("STOP_TRIGGER");
+    DATA_PRIVILEGES.add("SET_STORAGE_GROUP");
+    DATA_PRIVILEGES.add("CREATE_TIMESERIES");
+    DATA_PRIVILEGES.add("INSERT_TIMESERIES");
+    DATA_PRIVILEGES.add("READ_TIMESERIES");
+    DATA_PRIVILEGES.add("DELETE_TIMESERIES");
+  }
+
+  @Override
+  public DataCountVO getDataCount(Connection connection) throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String groupCountStr = executeQueryOneValue(sessionPool, "count storage group");
+      int groupCount = Integer.parseInt(groupCountStr);
+      String deviceCountStr = executeQueryOneValue(sessionPool, "count devices");
+      int deviceCount = Integer.parseInt(deviceCountStr);
+      String measurementCountStr = executeQueryOneValue(sessionPool, "count timeseries");
+      int measurementCount = Integer.parseInt(measurementCountStr);
+      List<String> dataCountList = executeQueryOneLine(sessionPool, "select count(*) from root");
+      int dataCount = 0;
+      for (String dataCountStr : dataCountList) {
+        dataCount += Integer.parseInt(dataCountStr);
+      }
+      DataCountVO dataCountVO = new DataCountVO();
+      dataCountVO.setGroupCount(groupCount);
+      dataCountVO.setDeviceCount(deviceCount);
+      dataCountVO.setMeasurementCount(measurementCount);
+      dataCountVO.setDataCount(dataCount);
+      return dataCountVO;
+    } catch (NumberFormatException e) {
+      throw new BaseException(ErrorCode.GET_DATA_COUNT_FAIL, ErrorCode.GET_DATA_COUNT_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public DataModelVO getDataModel(Connection connection) throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      DataModelVO root = new DataModelVO("root");
+      assembleDataModel(root, "root", sessionPool);
+      root.setGroupCount(getGroupCount(sessionPool));
+      root.setPath("root");
+      return root;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private void assembleDataModel(DataModelVO node, String prefixPath, SessionPool sessionPool)
+      throws BaseException {
+    Set<String> childrenNode = getChildrenNode(prefixPath, sessionPool);
+    if (childrenNode == null) {
+      return;
+    }
+    for (String child : childrenNode) {
+      DataModelVO childNode = new DataModelVO(child);
+      assembleDataModel(childNode, prefixPath + "." + child, sessionPool);
+      setNodeInfo(childNode, sessionPool, prefixPath + "." + child);
+      node.initNodeChildren().add(childNode);
+    }
+  }
+
+  private Set<String> getChildrenNode(String prefixPath, SessionPool sessionPool)
+      throws BaseException {
+    String sql = "show storage group " + prefixPath;
+    List<String> children = executeQueryOneColumn(sessionPool, sql);
+    if (children.size() == 0 || (children.size() == 1 && children.get(0).equals(prefixPath))) {
+      sql = "show timeseries " + prefixPath;
+      children = executeQueryOneColumn(sessionPool, sql);
+      if (children.size() == 0 || (children.size() == 1 && children.get(0).equals(prefixPath))) {
+        return null;
+      }
+    }
+    Set<String> childrenNode = new HashSet<>();
+    for (String child : children) {
+      child = StringUtils.removeStart(child, prefixPath + ".").split("\\.")[0];
+      childrenNode.add(child);
+    }
+    return childrenNode;
+  }
+
+  private Integer getGroupCount(SessionPool sessionPool) throws BaseException {
+    String sql = "count storage group";
+    String value = executeQueryOneValue(sessionPool, sql);
+    Integer count = Integer.valueOf(value);
+    return count;
+  }
+
+  private Integer getDeviceCount(SessionPool sessionPool, String groupName) throws BaseException {
+    String sql = "count devices " + groupName;
+    String value = executeQueryOneValue(sessionPool, sql);
+    Integer count = Integer.valueOf(value);
+    return count;
+  }
+
+  private Integer getMeasurementsCount(SessionPool sessionPool, String deviceName)
+      throws BaseException {
+    String sql = "count timeseries " + deviceName;
+    String value = executeQueryOneValue(sessionPool, sql);
+    Integer count = Integer.valueOf(value);
+    return count;
+  }
+
+  private boolean isGroup(SessionPool sessionPool, String path) throws BaseException {
+    String sql = "show storage group " + path;
+    List<String> groups = executeQueryOneColumn(sessionPool, sql);
+    boolean isGroup = false;
+    for (String group : groups) {
+      if (group.equals(path)) {
+        isGroup = true;
+        break;
+      }
+    }
+    return isGroup;
+  }
+
+  private boolean isDevice(SessionPool sessionPool, String path) throws BaseException {
+    String sql = "show devices " + path;
+    List<String> devices = executeQueryOneColumn(sessionPool, sql);
+    boolean isDevice = false;
+    for (String device : devices) {
+      if (device.equals(path)) {
+        isDevice = true;
+        break;
+      }
+    }
+    return isDevice;
+  }
+
+  private boolean isMeasurement(SessionPool sessionPool, String path) throws BaseException {
+    String sql = "show timeseries " + path;
+    List<String> measurements = executeQueryOneColumn(sessionPool, sql);
+    boolean isMeasurement = false;
+    for (String measurement : measurements) {
+      if (measurement.equals(path)) {
+        isMeasurement = true;
+        break;
+      }
+    }
+    return isMeasurement;
+  }
+
+  private void setNodeInfo(DataModelVO dataModelVO, SessionPool sessionPool, String path)
+      throws BaseException {
+    dataModelVO.setPath(path);
+    if (isGroup(sessionPool, path)) {
+      dataModelVO.setDeviceCount(getDeviceCount(sessionPool, path));
+      dataModelVO.setIsGroup(true);
+    }
+    if (isDevice(sessionPool, path)) {
+      dataModelVO.setMeasurementCount(getMeasurementsCount(sessionPool, path));
+      dataModelVO.setIsDevice(true);
+      return;
+    }
+    if (isMeasurement(sessionPool, path)) {
+      DataInfo dataInfo = new DataInfo();
+      dataInfo.setNewValue(getLastValue(sessionPool, path));
+      dataInfo.setDataCount(getOneDataCount(sessionPool, path));
+      dataInfo.setDataType(getDataType(sessionPool, path));
+      dataModelVO.setDataInfo(dataInfo);
+      dataModelVO.setIsMeasurement(true);
+    }
+  }
+
+  private String getLastValue(SessionPool sessionPool, String timeseries) throws BaseException {
+    int index = timeseries.lastIndexOf(".");
+    String sql =
+        "select last_value("
+            + timeseries.substring(index + 1)
+            + ") from "
+            + timeseries.substring(0, index);
+    String value = executeQueryOneValue(sessionPool, sql);
+    return value;
+  }
+
+  private Integer getOneDataCount(SessionPool sessionPool, String timeseries) throws BaseException {
+    int index = timeseries.lastIndexOf(".");
+    String sql = "select count(*) from " + timeseries.substring(0, index);
+    String countStr = executeQueryOneLine(sessionPool, sql, "count(" + timeseries + ")");
+    return Integer.parseInt(countStr);
+  }
+
+  private String getDataType(SessionPool sessionPool, String timeseries) throws BaseException {
+    String sql = "show timeseries " + timeseries;
+    String dataType = executeQueryOneLine(sessionPool, sql, "dataType");
+    return dataType;
   }
 
   @Override
   public List<String> getAllStorageGroups(Connection connection) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
-    String sql = "show storage group";
-    List<String> users = executeQueryOneColumn(sessionPool, sql);
-    sessionPool.close();
-    return users;
+    List<String> groups;
+    try {
+      String sql = "show storage group";
+      groups = executeQueryOneColumn(sessionPool, sql);
+      return groups;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<NodeTreeVO> getGroupsNodeTree(Connection connection) throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      return getGroupsNodeTree(sessionPool);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private List<NodeTreeVO> getGroupsNodeTree(SessionPool sessionPool) throws BaseException {
+    Set<String> firstLevelNodes = getChildrenNode("root", "storage group", sessionPool);
+    if (firstLevelNodes == null || firstLevelNodes.size() == 0) {
+      return null;
+    }
+    List<NodeTreeVO> groupNodeVOList = new ArrayList<>();
+    for (String firstLevelNodeName : firstLevelNodes) {
+      NodeTreeVO firstLevelNode = new NodeTreeVO(firstLevelNodeName);
+      groupNodeVOList.add(firstLevelNode);
+      assembleNodeTree(firstLevelNode, firstLevelNodeName, "storage group", sessionPool);
+    }
+    return groupNodeVOList;
+  }
+
+  private void assembleNodeTree(
+      NodeTreeVO node, String prefixPath, String type, SessionPool sessionPool)
+      throws BaseException {
+    Set<String> childrenNode = getChildrenNode(prefixPath, type, sessionPool);
+    if (childrenNode == null) {
+      return;
+    }
+    for (String child : childrenNode) {
+      NodeTreeVO childNode = new NodeTreeVO(child);
+      assembleNodeTree(childNode, child, type, sessionPool);
+      node.initChildren().add(childNode);
+    }
+  }
+
+  private Set<String> getChildrenNode(String prefixPath, String type, SessionPool sessionPool)
+      throws BaseException {
+    String sql = "show " + type + " " + prefixPath;
+    List<String> children = executeQueryOneColumn(sessionPool, sql);
+    if (children.size() == 0 || (children.size() == 1 && children.get(0).equals(prefixPath))) {
+      return null;
+    }
+    Set<String> childrenNode = new HashSet<>();
+    for (String child : children) {
+      if (child.equals(prefixPath)) {
+        continue;
+      }
+      child = prefixPath + "." + StringUtils.removeStart(child, prefixPath + ".").split("\\.")[0];
+      childrenNode.add(child);
+    }
+    return childrenNode;
   }
 
   @Override
   public void saveStorageGroup(Connection connection, String groupName) throws BaseException {
-    paramValid(groupName);
     SessionPool sessionPool = getSessionPool(connection);
     try {
       sessionPool.setStorageGroup(groupName);
     } catch (StatementExecutionException e) {
-      // 300为存储组重复或者其前/后路径上已经有存储组了
       if (e.getStatusCode() == 602) {
         throw new BaseException(ErrorCode.NO_PRI_SET_GROUP, ErrorCode.NO_PRI_SET_GROUP_MSG);
       }
+      // 300 indicates that the storage group is repeated or there is already a storage group on its
+      // front or back path
       if (e.getStatusCode() == 300) {
         throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
       }
@@ -114,15 +364,12 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
   }
 
   @Override
   public void deleteStorageGroup(Connection connection, String groupName) throws BaseException {
-    paramValid(groupName);
     SessionPool sessionPool = getSessionPool(connection);
     try {
       sessionPool.deleteStorageGroup(groupName);
@@ -136,9 +383,7 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
   }
 
@@ -146,7 +391,6 @@ public class IotDBServiceImpl implements IotDBService {
   public CountDTO getDevicesByGroup(
       Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword)
       throws BaseException {
-    paramValid(groupName);
     SessionPool sessionPool = getSessionPool(connection);
     String sql = "show devices " + groupName;
     SessionDataSetWrapper sessionDataSetWrapper = null;
@@ -161,7 +405,6 @@ public class IotDBServiceImpl implements IotDBService {
           List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
           if (keyword != null || "".equals(keyword)) {
             String deviceName = fields.get(0).toString();
-            deviceName = StringUtils.removeStart(deviceName, groupName + ".");
             if (deviceName.contains(keyword)) {
               count++;
             } else {
@@ -193,12 +436,8 @@ public class IotDBServiceImpl implements IotDBService {
       throw new BaseException(
           ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
     } finally {
-      if (sessionDataSetWrapper != null) {
-        sessionDataSetWrapper.close();
-      }
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
     }
   }
 
@@ -206,7 +445,6 @@ public class IotDBServiceImpl implements IotDBService {
   public CountDTO getMeasurementsByDevice(
       Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword)
       throws BaseException {
-    paramValid(deviceName);
     SessionPool sessionPool = getSessionPool(connection);
     String sql = "show timeseries " + deviceName;
     SessionDataSetWrapper sessionDataSetWrapper = null;
@@ -219,9 +457,11 @@ public class IotDBServiceImpl implements IotDBService {
         while (sessionDataSetWrapper.hasNext()) {
           RowRecord rowRecord = sessionDataSetWrapper.next();
           List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+          String measurementName = fields.get(0).toString();
+          if (StringUtils.removeStart(measurementName, deviceName + ".").contains(".")) {
+            continue;
+          }
           if (keyword != null || "".equals(keyword)) {
-            String measurementName = fields.get(0).toString();
-            measurementName = StringUtils.removeStart(measurementName, deviceName + ".");
             if (measurementName.contains(keyword)) {
               count++;
             } else {
@@ -270,125 +510,94 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
     } finally {
-      if (sessionDataSetWrapper != null) {
-        sessionDataSetWrapper.close();
-      }
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
     }
   }
 
   @Override
   public List<String> getIotDBUserList(Connection connection) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
-    String sql = "list user";
-    List<String> users = executeQueryOneColumn(sessionPool, sql);
-    sessionPool.close();
-    return users;
+    List<String> users;
+    try {
+      String sql = "list user";
+      users = executeQueryOneColumn(sessionPool, sql);
+      return users;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
   }
 
   @Override
   public List<String> getIotDBRoleList(Connection connection) throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    String sql = "list role";
-    List<String> roles = executeQueryOneColumn(sessionPool, sql);
-    sessionPool.close();
-    return roles;
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String sql = "list role";
+      List<String> roles = executeQueryOneColumn(sessionPool, sql);
+      sessionPool.close();
+      return roles;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
   }
 
   @Override
-  public IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException {
-    paramValid(userName);
-    IotDBUserVO iotDBUserVO = new IotDBUserVO();
-    iotDBUserVO.setUserName(userName);
-    if (userName.equals(connection.getUsername())) {
-      iotDBUserVO.setPassword(connection.getPassword());
-    } else {
-      iotDBUserVO.setPassword(null);
-    }
-    if ("root".equalsIgnoreCase(userName)) {
-      List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
-      PrivilegeInfo privilegeInfo = new PrivilegeInfo();
-      privilegeInfo.setType(0);
-      privilegeInfo.setPrivileges(PRIVILEGES);
-      privilegeInfos.add(privilegeInfo);
-      iotDBUserVO.setPrivilegesInfo(privilegeInfos);
-      return iotDBUserVO;
-    }
-    SessionPool sessionpool = getSessionPool(connection);
-    String sql = "list user privileges " + userName;
-    try {
-      SessionDataSetWrapper sessionDataSetWrapper = sessionpool.executeQueryStatement(sql);
-      int batchSize = sessionDataSetWrapper.getBatchSize();
-      if (batchSize > 0) {
-        List<String> privileges = new ArrayList<>();
-        while (sessionDataSetWrapper.hasNext()) {
-          RowRecord next = sessionDataSetWrapper.next();
-          List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
-          for (int i = 0; i < fields.size(); i++) {
-            org.apache.iotdb.tsfile.read.common.Field field = fields.get(i);
-            if (i == 0) {
-              if (field != null && field.toString().length() > 0) {
-                break;
-              }
-              continue;
-            }
-            privileges.add(field.toString());
-          }
-        }
-        // privileges String内容形式 "path : 权限1 权限2 权限3"
-        // 组装成权限信息集合
-        List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
-        if (privileges != null && privileges.size() > 0) {
-          privilegeInfos = privilegesStrSwitchToObject(sessionpool, privileges);
-        }
-        iotDBUserVO.setPrivilegesInfo(privilegeInfos);
-      }
-    } catch (Exception e) {
-      throw new BaseException(ErrorCode.GET_USER_FAIL, ErrorCode.GET_USER_FAIL_MSG);
+  public RoleVO getIotDBRoleInfo(Connection connection, String roleName) throws BaseException {
+    SessionPool sessionPool = null;
+    RoleVO roleVO = new RoleVO();
+    try {
+      sessionPool = getSessionPool(connection);
+      String sql = "LIST ALL USER OF ROLE " + roleName;
+      List<String> users = executeQueryOneColumn(sessionPool, sql);
+      roleVO.setUserList(users);
+      return roleVO;
+    } catch (BaseException e) {
+      throw new BaseException(ErrorCode.ROLE_GET_USERS_FAIL, ErrorCode.ROLE_GET_USERS_FAIL_MSG);
     } finally {
-      if (sessionpool != null) {
-        sessionpool.close();
-      }
+      closeSessionPool(sessionPool);
     }
-    return iotDBUserVO;
   }
 
   @Override
   public void deleteIotDBUser(Connection connection, String userName) throws BaseException {
-    paramValid(userName);
     SessionPool sessionPool = getSessionPool(connection);
     String sql = "drop user " + userName;
     try {
       sessionPool.executeNonQueryStatement(sql);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_DELETE_USER, ErrorCode.NO_PRI_DELETE_USER_MSG);
+      } else {
+        throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
+      }
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
   }
 
   @Override
   public void deleteIotDBRole(Connection connection, String roleName) throws BaseException {
-    paramValid(roleName);
     SessionPool sessionPool = getSessionPool(connection);
     String sql = "drop role " + roleName;
     try {
       sessionPool.executeNonQueryStatement(sql);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_DELETE_ROLE, ErrorCode.NO_PRI_DELETE_ROLE_MSG);
+      } else {
+        throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
+      }
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
   }
 
@@ -402,29 +611,19 @@ public class IotDBServiceImpl implements IotDBService {
       sessionPool.executeNonQueryStatement(sql);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_CREATE_USER, ErrorCode.NO_PRI_CREATE_USER_MSG);
+      } else if (e.getMessage().contains("already exists")) {
+        throw new BaseException(ErrorCode.USER_NAME_EXISTS, ErrorCode.USER_NAME_EXISTS_MSG);
+      } else {
+        throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
+      }
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
-    //        // 用户角色
-    //        for (String role : iotDBUser.getRoles()) {
-    //            paramValid(role);
-    //            sql = "grant " + role + " to " + userName;
-    //            customExecute(conn, sql);
-    //        }
-    //        // 用户授权
-    //        List<String> privileges = iotDBUser.getPrivileges();
-    //        for (String privilege : privileges) {
-    //            sql = handlerPrivilegeStrToSql(privilege, userName, null);
-    //            if (sql != null) {
-    //                customExecute(conn, sql);
-    //            }
-    //        }
   }
 
   @Override
@@ -434,176 +633,673 @@ public class IotDBServiceImpl implements IotDBService {
     String sql = "create role " + roleName;
     try {
       sessionPool.executeNonQueryStatement(sql);
-      List<String> privileges = iotDBRole.getPrivileges();
-      for (String privilege : privileges) {
-        sql = handlerPrivilegeStrToSql(privilege, null, roleName);
-        if (sql != null) {
-          sessionPool.executeNonQueryStatement(sql);
-        }
-      }
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_CREATE_ROLE, ErrorCode.NO_PRI_CREATE_ROLE_MSG);
+      } else if (e.getMessage().contains("already exists")) {
+        throw new BaseException(ErrorCode.ROLE_NAME_EXISTS, ErrorCode.ROLE_NAME_EXISTS_MSG);
+      } else {
+        throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+      }
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
   }
 
-  //    @Override
-  //    public SqlResultVO query(Connection connection, String sql) throws BaseException {
-  //        java.sql.Connection conn = getConnection(connection);
-  //        SqlResultVO sqlResultVO = sqlQuery(conn, sql);
-  //        closeConnection(conn);
-  //        return sqlResultVO;
-  //    }
-
   @Override
-  public void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries)
-      throws BaseException {
+  public UserRolesVO getRolesOfUser(Connection connection, String userName) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
+    UserRolesVO userRolesVO = new UserRolesVO();
+    if (userName.equals(connection.getUsername())) {
+      userRolesVO.setPassword(connection.getPassword());
+    } else {
+      userRolesVO.setPassword(null);
+    }
+    String sql = "list all role of user " + userName;
     try {
-      List<TSDataType> types = handleTypeStr(timeseries.getTypes());
-      List<Object> values = handleValueStr(timeseries.getValues(), types);
-      sessionPool.insertRecord(
-          deviceName, timeseries.getTime(), timeseries.getMeasurements(), types, values);
-    } catch (IoTDBConnectionException e) {
-      throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
-    } catch (StatementExecutionException e) {
-      throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
-    } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
+      List<String> roleList = executeQueryOneColumn(sessionPool, sql);
+      userRolesVO.setRoleList(roleList);
+      return userRolesVO;
+    } catch (BaseException e) {
+      if (e.getErrorCode().equals(ErrorCode.NO_PRI_DO_THIS)) {
+        throw new BaseException(ErrorCode.NO_PRI_LIST_ROLE, ErrorCode.NO_PRI_LIST_ROLE_MSG);
+      } else {
+        throw e;
       }
+    } finally {
+      closeSessionPool(sessionPool);
     }
   }
 
   @Override
-  public void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException {
+  public void userGrant(Connection connection, String userName, UserGrantDTO userGrantDTO)
+      throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
+    List<String> roleList = userGrantDTO.getRoleList();
+    List<String> cancelRoleList = userGrantDTO.getCancelRoleList();
     try {
-      sessionPool.deleteTimeseries(timeseriesName);
-    } catch (IoTDBConnectionException e) {
-      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
-    } catch (StatementExecutionException e) {
-      if (e.getStatusCode() == 602) {
-        throw new BaseException(
-            ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+      if (cancelRoleList != null && cancelRoleList.size() != 0) {
+        for (String cancelRole : cancelRoleList) {
+          revokeRole(sessionPool, userName, cancelRole);
+        }
       }
-      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
-    } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
+      if (roleList != null && roleList.size() != 0) {
+        for (String garntRole : roleList) {
+          grantRole(sessionPool, userName, garntRole);
+        }
       }
+    } finally {
+      closeSessionPool(sessionPool);
     }
   }
 
   @Override
-  public SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException {
-    paramValid(deviceName);
-    java.sql.Connection conn = getConnection(connection);
-    String sql = "show timeseries " + deviceName;
-    SqlResultVO resultVO = sqlQuery(conn, sql);
-    closeConnection(conn);
-    return resultVO;
-  }
-
-  @Override
-  public List<Integer> getDevicesCount(Connection connection, List<String> groupNames)
+  public void roleGrant(Connection connection, String roleName, RoleGrantDTO roleGrantDTO)
       throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
-    List<Integer> devicesCount = new ArrayList<>();
-    for (String groupName : groupNames) {
-      String sql = "count devices " + groupName;
-      String value = executeQueryOneValue(sessionPool, sql);
-      if (value == null) {
-        devicesCount.add(0);
-        continue;
+    List<String> userList = roleGrantDTO.getUserList();
+    List<String> cancelUserList = roleGrantDTO.getCancelUserList();
+    try {
+      if (cancelUserList != null && cancelUserList.size() != 0) {
+        for (String cancelUser : cancelUserList) {
+          revokeRole(sessionPool, cancelUser, roleName);
+        }
+      }
+      if (userList != null && userList.size() != 0) {
+        for (String garntUser : userList) {
+          grantRole(sessionPool, garntUser, roleName);
+        }
       }
-      Integer count = Integer.valueOf(value);
-      devicesCount.add(count);
+    } finally {
+      closeSessionPool(sessionPool);
     }
-    sessionPool.close();
-    return devicesCount;
   }
 
-  @Override
-  public void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    String sql = "set ttl to " + groupName + " " + l;
+  private void revokeRole(SessionPool sessionPool, String userName, String roleName)
+      throws BaseException {
+    String sql = "revoke " + roleName + " from " + userName;
     try {
       sessionPool.executeNonQueryStatement(sql);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
       if (e.getStatusCode() == 602) {
-        throw new BaseException(ErrorCode.NO_PRI_SET_TTL, ErrorCode.NO_PRI_SET_TTL_MSG);
+        throw new BaseException(
+            ErrorCode.NO_PRI_REVOKE_USER_ROLE, ErrorCode.NO_PRI_REVOKE_USER_ROLE_MSG);
+      } else {
+        throw new BaseException(ErrorCode.REVOKE_ROLE, ErrorCode.REVOKE_ROLE_MSG);
       }
-      throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
-    } finally {
-      sessionPool.close();
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     }
   }
 
-  @Override
-  public void cancelGroupTtl(Connection connection, String groupName) throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    String sql = "unset ttl to " + groupName;
+  private void grantRole(SessionPool sessionPool, String userName, String roleName)
+      throws BaseException {
+    String sql = "grant " + roleName + " to " + userName;
     try {
       sessionPool.executeNonQueryStatement(sql);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_GRANT_USER_ROLE, ErrorCode.NO_PRI_GRANT_USER_ROLE_MSG);
+      } else {
+        throw new BaseException(ErrorCode.GRANT_ROLE, ErrorCode.GRANT_ROLE_MSG);
+      }
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
-    } finally {
-      sessionPool.close();
-    }
-  }
-
-  @Override
-  public Integer getDeviceCount(Connection connection, String groupName) throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    String sql = "count devices " + groupName;
-    String value = executeQueryOneValue(sessionPool, sql);
-    if (value == null) {
-      return 0;
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     }
-    Integer count = Integer.valueOf(value);
-    return count;
   }
 
   @Override
-  public List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames)
+  public Set<String> getUserAuthorityPrivilege(Connection connection, String userName)
       throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    List<Integer> lines = new ArrayList<>();
-    for (String deviceName : deviceNames) {
-      String sql = "count timeseries " + deviceName;
-      String value = executeQueryOneValue(sessionPool, sql);
-      if (value == null) {
-        lines.add(0);
-        continue;
-      }
-      Integer count = Integer.valueOf(value);
-      lines.add(count);
+    SessionPool sessionPool = null;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      if ("root".equals(userName)) {
+        return AUTHORITY_PRIVILEGES;
+      }
+      Set<String> privileges = new HashSet<>();
+      List<String> rowInfos = new ArrayList<>();
+      sessionPool = getSessionPool(connection);
+      String sql = "list user privileges " + userName;
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      while (sessionDataSetWrapper.hasNext()) {
+        RowRecord next = sessionDataSetWrapper.next();
+        List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+        for (int i = 0; i < fields.size(); i++) {
+          org.apache.iotdb.tsfile.read.common.Field field = fields.get(i);
+          if (i == 0) {
+            if (!"".equals(field.toString())) {
+              break;
+            }
+          } else {
+            rowInfos.add(field.toString());
+          }
+        }
+      }
+      privileges = switchRowInfosToAuthorityPrivileges(rowInfos);
+      return privileges;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_USER_PRIVILEGE_FAIL, ErrorCode.GET_USER_PRIVILEGE_FAIL_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
     }
-    sessionPool.close();
-    return lines;
   }
 
   @Override
-  public void deleteTimeseriesByDevice(Connection connection, String deviceName)
+  public Set<String> getAllAuthorityPrivilege(Connection connection, String userName)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      if ("root".equals(userName)) {
+        return AUTHORITY_PRIVILEGES;
+      }
+      Set<String> privileges = new HashSet<>();
+      List<String> rowInfos = new ArrayList<>();
+      sessionPool = getSessionPool(connection);
+      String sql = "list user privileges " + userName;
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      while (sessionDataSetWrapper.hasNext()) {
+        RowRecord next = sessionDataSetWrapper.next();
+        List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+        rowInfos.add(fields.get(1).toString());
+      }
+      privileges = switchRowInfosToAuthorityPrivileges(rowInfos);
+      return privileges;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_USER_PRIVILEGE_FAIL, ErrorCode.GET_USER_PRIVILEGE_FAIL_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public Set<String> getRoleAuthorityPrivilege(Connection connection, String roleName)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      Set<String> privileges = new HashSet<>();
+      sessionPool = getSessionPool(connection);
+      String sql = "list role privileges " + roleName;
+      List<String> rowInfos = executeQueryOneColumn(sessionPool, sql);
+      privileges = switchRowInfosToAuthorityPrivileges(rowInfos);
+      return privileges;
+    } catch (BaseException e) {
+      if (e.getErrorCode().equals(ErrorCode.NO_PRI_DO_THIS)) {
+        throw new BaseException(ErrorCode.NO_PRI_LIST_ROLE, ErrorCode.NO_PRI_LIST_ROLE_MSG);
+      } else {
+        throw new BaseException(
+            ErrorCode.GET_ROLE_PRIVILEGE_FAIL, ErrorCode.GET_ROLE_PRIVILEGE_FAIL_MSG);
+      }
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private Set<String> switchRowInfosToAuthorityPrivileges(List<String> rowInfos) {
+    Set<String> authorityPrivileges = new HashSet<>();
+    for (String rowInfo : rowInfos) {
+      String[] split = rowInfo.split("\\s:\\s");
+      String[] privileges = split[1].split("\\s");
+      for (String privilege : privileges) {
+        if (AUTHORITY_PRIVILEGES.contains(privilege)) {
+          authorityPrivileges.add(privilege);
+        }
+      }
+    }
+    return authorityPrivileges;
+  }
+
+  @Override
+  public void upsertAuthorityPrivilege(
+      Connection connection,
+      String userName,
+      AuthorityPrivilegeDTO authorityPrivilegeDTO,
+      String userOrRole)
       throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      List<String> cancelPrivileges = authorityPrivilegeDTO.getCancelPrivileges();
+      if (cancelPrivileges != null) {
+        checkAuthorityPrivilege(cancelPrivileges);
+        for (String cancelPrivilege : cancelPrivileges) {
+          upsertAuthorityPrivilege(sessionPool, "revoke", userOrRole, userName, cancelPrivilege);
+        }
+      }
+      List<String> privileges = authorityPrivilegeDTO.getPrivileges();
+      if (privileges != null) {
+        checkAuthorityPrivilege(privileges);
+        for (String privilege : privileges) {
+          upsertAuthorityPrivilege(sessionPool, "grant", userOrRole, userName, privilege);
+        }
+      }
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private void upsertAuthorityPrivilege(
+      SessionPool sessionPool,
+      String operationType,
+      String userOrRole,
+      String name,
+      String privilegesStr)
+      throws BaseException {
+    String sql =
+        operationType
+            + " "
+            + userOrRole
+            + " "
+            + name
+            + " privileges '"
+            + privilegesStr
+            + "' on root";
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_GRANT_PRIVILEGE, ErrorCode.NO_PRI_GRANT_PRIVILEGE_MSG);
+      }
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    }
+  }
+
+  private void checkAuthorityPrivilege(List<String> privileges) throws BaseException {
+    for (String privilege : privileges) {
+      if (!AUTHORITY_PRIVILEGES.contains(privilege)) {
+        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+      }
+    }
+  }
+
+  @Override
+  public List<DataPrivilegeVO> getUserDataPrivilege(Connection connection, String userName)
+      throws BaseException {
+    if ("root".equalsIgnoreCase(userName)) {
+      DataPrivilegeVO dataPrivilegeVO = new DataPrivilegeVO();
+      dataPrivilegeVO.setType(0);
+      dataPrivilegeVO.setPrivileges(new ArrayList<>(DATA_PRIVILEGES));
+      return Arrays.asList(dataPrivilegeVO);
+    }
+    SessionPool sessionPool = null;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      List<String> rowInfos = new ArrayList<>();
+      sessionPool = getSessionPool(connection);
+      String sql = "list user privileges " + userName;
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      while (sessionDataSetWrapper.hasNext()) {
+        RowRecord next = sessionDataSetWrapper.next();
+        List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+        for (int i = 0; i < fields.size(); i++) {
+          org.apache.iotdb.tsfile.read.common.Field field = fields.get(i);
+          if (i == 0) {
+            if (!"".equals(field.toString())) {
+              break;
+            }
+          } else {
+            rowInfos.add(field.toString());
+          }
+        }
+      }
+      // rowInfos form: "path : privilege1 privilege2 privilege3"
+      List<DataPrivilegeVO> dataPrivilegeList =
+          switchRowInfosToDataPrivileges(rowInfos, sessionPool);
+      return dataPrivilegeList;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_USER_PRIVILEGE_FAIL, ErrorCode.GET_USER_PRIVILEGE_FAIL_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<DataPrivilegeVO> getRoleDataPrivilege(Connection connection, String roleName)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String sql = "list role privileges " + roleName;
+      List<String> rowInfos = executeQueryOneColumn(sessionPool, sql);
+
+      // rowInfos form: "path : privilege1 privilege2 privilege3"
+      List<DataPrivilegeVO> dataPrivilegeList =
+          switchRowInfosToDataPrivileges(rowInfos, sessionPool);
+      return dataPrivilegeList;
+    } catch (BaseException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_ROLE_PRIVILEGE_FAIL, ErrorCode.GET_ROLE_PRIVILEGE_FAIL_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private List<DataPrivilegeVO> switchRowInfosToDataPrivileges(
+      List<String> rowInfos, SessionPool sessionPool) throws BaseException {
+    if (rowInfos == null || rowInfos.size() == 0) {
+      return null;
+    }
+    List<String> paths = new ArrayList<>();
+    List<List<String>> privilegesList = new ArrayList<>();
+    List<DataPrivilegeVO> dataPrivilegeList = new ArrayList<>();
+    for (String rowInfo : rowInfos) {
+      String[] split = rowInfo.split("\\s:\\s");
+      String[] allPrivileges = split[1].split("\\s");
+      String path = split[0];
+      if ("root".equals(path)) {
+        handleRootPrivileges(allPrivileges, dataPrivilegeList);
+        continue;
+      }
+
+      List<String> privileges = new ArrayList<>();
+      for (String privilege : allPrivileges) {
+        if (DATA_PRIVILEGES.contains(privilege)) {
+          privileges.add(privilege);
+        }
+      }
+      privilegesList.add(privileges);
+      paths.add(path);
+    }
+
+    // Map form: {"privilege1 privilege2 privilege3..." : ["path1","path2"]} path1,path2 have the
+    // same privileges.
+    Map<String, List<String>> privilegeOne = new HashMap<>();
+    Map<String, List<String>> privilegeTwo = new HashMap<>();
+    Map<String, List<String>> privilegeThree = new HashMap<>();
+    for (int i = 0; i < paths.size(); i++) {
+      String path = paths.get(i);
+      String privilegesStr = String.join(" ", privilegesList.get(i));
+      int type = findType(sessionPool, path);
+      if (type == 1) {
+        if (privilegeOne.containsKey(privilegesStr)) {
+          List<String> pathList = privilegeOne.get(privilegesStr);
+          pathList.add(path);
+          continue;
+        }
+        ArrayList<String> newPaths = new ArrayList();
+        newPaths.add(path);
+        privilegeOne.put(privilegesStr, newPaths);
+        continue;
+      }
+      if (type == 2) {
+        if (privilegeTwo.containsKey(privilegesStr)) {
+          List<String> pathList = privilegeTwo.get(privilegesStr);
+          pathList.add(path);
+          continue;
+        }
+        ArrayList<String> newStr = new ArrayList();
+        newStr.add(path);
+        privilegeTwo.put(privilegesStr, newStr);
+        continue;
+      }
+      if (type == 3) {
+        if (privilegeThree.containsKey(privilegesStr)) {
+          List<String> pathList = privilegeThree.get(privilegesStr);
+          pathList.add(path);
+          continue;
+        }
+        ArrayList<String> newStr = new ArrayList();
+        newStr.add(path);
+        privilegeThree.put(privilegesStr, newStr);
+      }
+    }
+
+    Set<String> oneKeys = privilegeOne.keySet();
+    Set<String> twoKeys = privilegeTwo.keySet();
+    Set<String> threeKeys = privilegeThree.keySet();
+    List<String> allGroupPaths = executeQueryOneColumn(sessionPool, "show storage group");
+    List<String> allDevicePaths = executeQueryOneColumn(sessionPool, "show devices");
+
+    for (String oneKey : oneKeys) {
+      DataPrivilegeVO dataPrivilegeVO = new DataPrivilegeVO();
+      List<String> groupPaths = privilegeOne.get(oneKey);
+      List<String> privilegesOne = Arrays.asList(oneKey.split(" "));
+
+      dataPrivilegeVO.setType(1);
+      dataPrivilegeVO.setPrivileges(privilegesOne);
+      dataPrivilegeVO.setGroupPaths(groupPaths);
+      dataPrivilegeVO.setAllGroupPaths(getGroupsNodeTree(sessionPool));
+      dataPrivilegeList.add(dataPrivilegeVO);
+    }
+    for (String twoKey : twoKeys) {
+      List<String> privilegesTwo = Arrays.asList(twoKey.split(" "));
+      List<String> pathsTwo = privilegeTwo.get(twoKey);
+
+      Map<String, List<String>> groupPathsToDevicePaths = new HashMap<>();
+      for (String path : pathsTwo) {
+        String groupPath = getSupPath(path, allGroupPaths);
+        if (!groupPathsToDevicePaths.containsKey(groupPath)) {
+          groupPathsToDevicePaths.put(groupPath, Stream.of(path).collect(Collectors.toList()));
+        } else {
+          groupPathsToDevicePaths.get(groupPath).add(path);
+        }
+      }
+      for (Map.Entry<String, List<String>> entry : groupPathsToDevicePaths.entrySet()) {
+        DataPrivilegeVO dataPrivilegeVO = new DataPrivilegeVO();
+        String groupName = entry.getKey();
+        dataPrivilegeVO.setType(2);
+        dataPrivilegeVO.setPrivileges(privilegesTwo);
+        dataPrivilegeVO.setGroupPaths(Arrays.asList(groupName));
+        dataPrivilegeVO.setDevicePaths(entry.getValue());
+        dataPrivilegeVO.setAllDevicePaths(getDeviceNodeTree(sessionPool, groupName));
+        dataPrivilegeVO.setAllGroupPaths(switchListToNodeList(allGroupPaths));
+        dataPrivilegeList.add(dataPrivilegeVO);
+      }
+    }
+    for (String threeKey : threeKeys) {
+      List<String> privilegesThree = Arrays.asList(threeKey.split(" "));
+      List<String> pathsThree = privilegeThree.get(threeKey);
+
+      Map<String, List<String>> devicePathsTotimeseriesPaths = new HashMap<>();
+      for (String path : pathsThree) {
+        String devicePath = getSupPath(path, allDevicePaths);
+        if (!devicePathsTotimeseriesPaths.containsKey(devicePath)) {
+          devicePathsTotimeseriesPaths.put(
+              devicePath, Stream.of(path).collect(Collectors.toList()));
+        } else {
+          devicePathsTotimeseriesPaths.get(devicePath).add(path);
+        }
+      }
+      for (Map.Entry<String, List<String>> entry : devicePathsTotimeseriesPaths.entrySet()) {
+        DataPrivilegeVO dataPrivilegeVO = new DataPrivilegeVO();
+        dataPrivilegeVO.setType(3);
+        dataPrivilegeVO.setPrivileges(privilegesThree);
+        String device = entry.getKey();
+        String group = getSupPath(device, allGroupPaths);
+        dataPrivilegeVO.setGroupPaths(Arrays.asList(group));
+        dataPrivilegeVO.setDevicePaths(Arrays.asList(device));
+        dataPrivilegeVO.setTimeseriesPaths(entry.getValue());
+        dataPrivilegeVO.setAllGroupPaths(switchListToNodeList(allGroupPaths));
+        String sql = "show devices " + group;
+        List<String> devicePathsOfGroup = executeQueryOneColumn(sessionPool, sql);
+        dataPrivilegeVO.setAllDevicePaths(switchListToNodeList(devicePathsOfGroup));
+        sql = "show timeseries " + device;
+        dataPrivilegeVO.setAllTimeseriesPaths(executeQueryOneColumn(sessionPool, sql));
+        dataPrivilegeList.add(dataPrivilegeVO);
+      }
+    }
+    return dataPrivilegeList;
+  }
+
+  private String getSupPath(String path, List<String> allSupPath) throws BaseException {
+    for (String supPath : allSupPath) {
+      String checkPath = StringUtils.removeStart(path, supPath);
+      if (path.contains(supPath) && checkPath.startsWith(".") || checkPath.equals("")) {
+        return supPath;
+      }
+    }
+    throw new BaseException(
+        ErrorCode.GET_DATA_PRIVILEGE_FAIL, ErrorCode.GET_DATA_PRIVILEGE_FAIL_MSG);
+  }
+
+  private List<NodeTreeVO> switchListToNodeList(List<String> list) {
+    List<NodeTreeVO> nodeList = new ArrayList<>();
+    for (String s : list) {
+      nodeList.add(new NodeTreeVO(s));
+    }
+    return nodeList;
+  }
+
+  private void handleRootPrivileges(
+      String[] allPrivileges, List<DataPrivilegeVO> dataPrivilegeList) {
+    Set<String> rootPrivilegesSet = new HashSet<>();
+    for (String privilege : allPrivileges) {
+      if (DATA_PRIVILEGES.contains(privilege)) {
+        rootPrivilegesSet.add(privilege);
+      }
+    }
+    if (rootPrivilegesSet.size() > 0) {
+      DataPrivilegeVO dataPrivilegeVO = new DataPrivilegeVO();
+      dataPrivilegeVO.setPrivileges(new ArrayList<String>(rootPrivilegesSet));
+      dataPrivilegeVO.setType(0);
+      dataPrivilegeList.add(dataPrivilegeVO);
+    }
+  }
+
+  @Override
+  public void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
-    String sql = "delete timeseries " + deviceName + ".*";
+    try {
+      sessionPool.deleteTimeseries(timeseriesName);
+    } catch (IoTDBConnectionException e) {
+      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+      }
+      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<Integer> getDevicesCount(Connection connection, List<String> groupNames)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<Integer> devicesCount = new ArrayList<>();
+    try {
+      for (String groupName : groupNames) {
+        String sql = "count devices " + groupName;
+        String value = executeQueryOneValue(sessionPool, sql);
+        if (value == null) {
+          devicesCount.add(0);
+          continue;
+        }
+        Integer count = Integer.valueOf(value);
+        devicesCount.add(count);
+      }
+      return devicesCount;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "set ttl to " + groupName + " " + l;
     try {
       sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_SET_TTL, ErrorCode.NO_PRI_SET_TTL_MSG);
+      }
+      throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public void cancelGroupTtl(Connection connection, String groupName) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "unset ttl to " + groupName;
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<Integer> lines = new ArrayList<>();
+    try {
+      for (String deviceName : deviceNames) {
+        String sql = "count timeseries " + deviceName;
+        String value = executeQueryOneValue(sessionPool, sql);
+        if (value == null) {
+          lines.add(0);
+          continue;
+        }
+        Integer count = Integer.valueOf(value);
+        lines.add(count);
+      }
+      return lines;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<String> deleteTimeseriesByDevice(Connection connection, String deviceName)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      List<String> timeseriesList = getTimeseries(connection, deviceName);
+      for (String timeseries : timeseriesList) {
+        String sql = "delete timeseries " + timeseries;
+        sessionPool.executeNonQueryStatement(sql);
+      }
+      return timeseriesList;
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
       if (e.getStatusCode() == 602) {
@@ -614,56 +1310,281 @@ public class IotDBServiceImpl implements IotDBService {
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
     }
   }
 
   @Override
-  public void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO)
+  public void upsertMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO)
       throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    List<String> typesStr = new ArrayList<>();
-    List<String> encodingsStr = new ArrayList<>();
-    List<String> measurements = new ArrayList<>();
-    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
-      typesStr.add(deviceDTO.getDataType());
-      encodingsStr.add(deviceDTO.getEncoding());
-      measurements.add(deviceDTO.getTimeseries());
-    }
-    List<TSDataType> types = handleTypeStr(typesStr);
-    List<TSEncoding> encodings = handleEncodingStr(encodingsStr);
-    List<CompressionType> compressionTypes = new ArrayList<>();
-    for (int i = 0; i < types.size(); i++) {
-      compressionTypes.add(CompressionType.SNAPPY);
-    }
-    try {
-      sessionPool.createMultiTimeseries(
-          measurements, types, encodings, compressionTypes, null, null, null, null);
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String deviceName = deviceInfoDTO.getDeviceName();
+      checkDevicePath(sessionPool, deviceName);
+      String sql = "show timeseries " + deviceName;
+      List<String> existMeasurements = executeQueryOneColumn(sessionPool, sql);
+      for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+        String timeseries = deviceDTO.getTimeseries();
+        checkTags(deviceDTO.getTags());
+        checkTags(deviceDTO.getAttributes());
+        if (existMeasurements.contains(timeseries)) {
+          upsertMeasurementAlias(sessionPool, timeseries, deviceDTO.getAlias());
+          upsertMeasurementTags(sessionPool, deviceDTO);
+          upsertMeasurementAttributes(sessionPool, deviceDTO);
+        } else {
+          createMeasurement(sessionPool, deviceDTO);
+        }
+      }
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private void createMeasurement(SessionPool sessionPool, DeviceDTO deviceDTO)
+      throws BaseException {
+    String measurement = deviceDTO.getTimeseries();
+    try {
+      TSDataType type = handleTypeStr(deviceDTO.getDataType());
+      TSEncoding encoding = handleEncodingStr(deviceDTO.getEncoding());
+      CompressionType compressionType = handleCompressionStr(deviceDTO.getCompression());
+      String alias = deviceDTO.getAlias();
+      if (alias == null || "null".equals(alias) || StringUtils.isBlank(alias)) {
+        alias = null;
+      }
+      Map<String, String> tags = handleTagsList(deviceDTO.getTags());
+      Map<String, String> attributes = handleTagsList(deviceDTO.getAttributes());
+      sessionPool.createTimeseries(
+          measurement, type, encoding, compressionType, null, tags, attributes, alias);
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
       if (e.getMessage().contains("No permissions")) {
         throw new BaseException(
             ErrorCode.NO_PRI_CREATE_TIMESERIES, ErrorCode.NO_PRI_CREATE_TIMESERIES_MSG);
       }
-      if (!e.getMessage().contains("PathAlreadyExistException")) {
-        logger.error(e.getMessage());
-        throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
+      if (e.getMessage().contains("already exist")) {
+        throw new BaseException(
+            ErrorCode.MEASUREMENT_ALREADY_EXIST,
+            measurement + ErrorCode.MEASUREMENT_ALREADY_EXIST_MSG);
       }
-    } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
+      throw new BaseException(ErrorCode.INSERT_TS_FAIL, measurement + ErrorCode.INSERT_TS_FAIL_MSG);
+    }
+  }
+
+  private Map<String, String> handleTagsList(List<List<String>> tags) throws BaseException {
+    if (tags != null && tags.size() > 0) {
+      Map<String, String> result = new HashMap<>();
+      for (List<String> tag : tags) {
+        result.put(tag.get(0), tag.get(1));
       }
+      return result;
+    } else {
+      return null;
+    }
+  }
+
+  private Map<String, String> handleTagsString(String tags) throws BaseException {
+    if (!"null".equals(tags)) {
+      String patternStr = "\"([^\"]+)\":\"([^\"]+)\"";
+      Pattern pattern = Pattern.compile(patternStr);
+      Matcher matcher = pattern.matcher(tags);
+      Map<String, String> result = new HashMap<>();
+      while (matcher.find()) {
+        result.put(matcher.group(1), matcher.group(2));
+      }
+      return result;
+    } else {
+      return null;
+    }
+  }
+
+  private void checkDevicePath(SessionPool sessionPool, String deviceName) throws BaseException {
+    String sql = "show timeseries " + deviceName;
+    List<String> measurements = executeQueryOneColumn(sessionPool, sql);
+    if (measurements.size() > 0 && measurements.get(0).equals(deviceName)) {
+      throw new BaseException(
+          ErrorCode.MEASUREMENT_NAME_EQUALS_DEVICE, ErrorCode.MEASUREMENT_NAME_EQUALS_DEVICE_MSG);
+    }
+  }
+
+  private void checkTags(List<List<String>> tags) throws BaseException {
+    if (tags != null && tags.size() > 0) {
+      for (List<String> tag : tags) {
+        if (tag.size() != 2) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        }
+        String key = tag.get(0);
+        String value = tag.get(1);
+        checkKey(key);
+        checkValue(value);
+      }
+    }
+  }
+
+  private void checkKey(String key) throws BaseException {
+    if (key != null) {
+      checkValue(key);
+      if (key.matches("^\\d+$")) {
+        throw new BaseException(ErrorCode.NO_SUP_ALL_DIGIT, ErrorCode.NO_SUP_ALL_DIGIT_MSG);
+      }
+    }
+  }
+
+  private void checkValue(String value) throws BaseException {
+    if (value != null) {
+      if (value.matches("^as$") || value.matches("^null$") || value.matches("^like$")) {
+        throw new BaseException(ErrorCode.NO_SUP_WORD, ErrorCode.NO_SUP_WORD_MSG);
+      }
+    }
+  }
+
+  private void upsertMeasurementAlias(SessionPool sessionPool, String timeseries, String alias)
+      throws BaseException {
+    if (alias == null || "null".equals(alias) || StringUtils.isBlank(alias)) {
+      return;
+    }
+    if (alias.matches("^as$") || alias.matches("^\\d+$") || alias.matches("^like$")) {
+      throw new BaseException(ErrorCode.NO_SUP_ALIAS_WORD, ErrorCode.NO_SUP_ALIAS_WORD_MSG);
+    }
+    String existAlias = executeQueryOneLine(sessionPool, "show timeseries " + timeseries, "alias");
+    if (alias.equals(existAlias)) {
+      return;
+    }
+    try {
+      String sql = "alter timeseries " + timeseries + " upsert alias=" + alias;
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getMessage().contains("No permissions")) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_ALTER_MEASUREMENT, ErrorCode.NO_PRI_ALTER_MEASUREMENT_MSG);
+      }
+      throw new BaseException(ErrorCode.UPSERT_ALIAS_FAIL, ErrorCode.UPSERT_ALIAS_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    }
+  }
+
+  private void upsertMeasurementTags(SessionPool sessionPool, DeviceDTO deviceDTO)
+      throws BaseException {
+    try {
+      String tags =
+          executeQueryOneLine(sessionPool, "show timeseries " + deviceDTO.getTimeseries(), "tags");
+      Map<String, String> existTags = handleTagsString(tags);
+      List<List<String>> newTags = deviceDTO.getTags();
+      Map<String, String> addTags = handleTagsList(newTags);
+
+      if (addTags == null && existTags == null) {
+        return;
+      }
+      if (addTags != null && addTags.equals(existTags)) {
+        return;
+      }
+
+      if (existTags != null) {
+        String sql =
+            "alter timeseries "
+                + deviceDTO.getTimeseries()
+                + " drop "
+                + String.join(",", existTags.keySet());
+        sessionPool.executeNonQueryStatement(sql);
+      }
+      if (newTags != null) {
+        for (List<String> newTag : newTags) {
+          String sql =
+              "alter timeseries "
+                  + deviceDTO.getTimeseries()
+                  + " add tags "
+                  + newTag.get(0)
+                  + "="
+                  + newTag.get(1);
+          sessionPool.executeNonQueryStatement(sql);
+        }
+      }
+    } catch (BaseException | StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getMessage().contains("No permissions")) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_ALTER_MEASUREMENT, ErrorCode.NO_PRI_ALTER_MEASUREMENT_MSG);
+      }
+      throw new BaseException(ErrorCode.UPSERT_TAGS_FAIL, ErrorCode.UPSERT_TAGS_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    }
+  }
+
+  private void upsertMeasurementAttributes(SessionPool sessionPool, DeviceDTO deviceDTO)
+      throws BaseException {
+    try {
+      String attributes =
+          executeQueryOneLine(
+              sessionPool, "show timeseries " + deviceDTO.getTimeseries(), "attributes");
+      Map<String, String> existAttributes = handleTagsString(attributes);
+      List<List<String>> newAttributes = deviceDTO.getAttributes();
+      Map<String, String> addAttributes = handleTagsList(newAttributes);
+
+      if (addAttributes == null && existAttributes == null) {
+        return;
+      }
+      if (addAttributes != null && addAttributes.equals(existAttributes)) {
+        return;
+      }
+
+      if (existAttributes != null) {
+        String sql =
+            "alter timeseries "
+                + deviceDTO.getTimeseries()
+                + " drop "
+                + String.join(",", existAttributes.keySet());
+        sessionPool.executeNonQueryStatement(sql);
+      }
+      if (newAttributes != null) {
+        for (List<String> newAttribute : newAttributes) {
+          String sql =
+              "alter timeseries "
+                  + deviceDTO.getTimeseries()
+                  + " add attributes "
+                  + newAttribute.get(0)
+                  + "="
+                  + newAttribute.get(1);
+          sessionPool.executeNonQueryStatement(sql);
+        }
+      }
+    } catch (BaseException | StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getMessage().contains("No permissions")) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_ALTER_MEASUREMENT, ErrorCode.NO_PRI_ALTER_MEASUREMENT_MSG);
+      }
+      throw new BaseException(
+          ErrorCode.UPSERT_ATTRIBUTES_FAIL, ErrorCode.UPSERT_ATTRIBUTES_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     }
   }
 
   @Override
-  public Integer getMeasurementsCount(Connection connection, String deviceName)
+  public Integer getOneDataCount(Connection connection, String deviceName, String measurementName)
       throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
-    String sql = "count timeseries " + deviceName;
-    String valueStr = executeQueryOneValue(sessionPool, sql);
-    return Integer.valueOf(valueStr);
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String sql = "select count(*) from " + deviceName;
+      String countStr = executeQueryOneLine(sessionPool, sql, "count(" + measurementName + ")");
+      return Integer.parseInt(countStr);
+    } catch (BaseException e) {
+      throw new BaseException(
+          ErrorCode.GET_MEASUREMENT_DATA_COUNT_FAIL, ErrorCode.GET_MEASUREMENT_DATA_COUNT_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
   }
 
   @Override
@@ -679,33 +1600,169 @@ public class IotDBServiceImpl implements IotDBService {
     String value;
     try {
       value = executeQueryOneValue(sessionPool, sql);
+      return value;
     } finally {
-      sessionPool.close();
+      closeSessionPool(sessionPool);
     }
-    return value;
   }
 
   @Override
   public String getGroupTTL(Connection connection, String groupName) throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
-    String sql = "show ttl on " + groupName;
-    String queryField = "ttl";
-    String ttl = executeQueryOneLine(sessionPool, sql, queryField);
-    return ttl;
+    try {
+      String sql = "show ttl on " + groupName;
+      String queryField = "ttl";
+      String ttl = executeQueryOneLine(sessionPool, sql, queryField);
+      return ttl;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
   }
 
   @Override
   public List<String> getDevices(Connection connection, String groupName) throws BaseException {
-    paramValid(groupName);
     SessionPool sessionPool = getSessionPool(connection);
-    String sql = "show devices " + groupName;
-    List<String> devicesName = executeQueryOneColumn(sessionPool, sql);
-    return devicesName;
+    try {
+      String sql = "show devices " + groupName;
+      List<String> devicesName = executeQueryOneColumn(sessionPool, sql);
+      return devicesName;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<NodeTreeVO> getDeviceNodeTree(Connection connection, String groupName)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      return getDeviceNodeTree(sessionPool, groupName);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private List<NodeTreeVO> getDeviceNodeTree(SessionPool sessionPool, String groupName)
+      throws BaseException {
+    Set<String> firstLevelNodes = getChildrenNode(groupName, "devices", sessionPool);
+    if (firstLevelNodes == null || firstLevelNodes.size() == 0) {
+      return null;
+    }
+    List<NodeTreeVO> groupNodeVOList = new ArrayList<>();
+    for (String firstLevelNodeName : firstLevelNodes) {
+      NodeTreeVO firstLevelNode = new NodeTreeVO(firstLevelNodeName);
+      groupNodeVOList.add(firstLevelNode);
+      assembleNodeTree(firstLevelNode, firstLevelNodeName, "devices", sessionPool);
+    }
+    return groupNodeVOList;
+  }
+
+  @Override
+  public NodeTreeVO getDeviceList(Connection connection, String groupName) throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String sql = "show devices " + groupName;
+      List<String> devices = executeQueryOneColumn(sessionPool, sql);
+      String ancestryName = null;
+      if (devices.size() == 0) {
+        return null;
+      } else if (groupName.equals(devices.get(0))) {
+        ancestryName = groupName;
+      }
+      NodeTreeVO ancestry = new NodeTreeVO(ancestryName);
+      assembleDeviceList(ancestry, groupName, sessionPool);
+      return ancestry;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public List<String> getDeviceParents(Connection connection, String groupName, String deviceName)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = getSessionPool(connection);
+      String sql = "show devices " + groupName;
+      List<String> devices = executeQueryOneColumn(sessionPool, sql);
+      List<String> parents =
+          devices.stream()
+              .filter(d -> deviceName.startsWith(d))
+              .filter(d -> StringUtils.removeStart(deviceName, d).startsWith("."))
+              .sorted()
+              .collect(Collectors.toList());
+      parents.add(deviceName);
+      return parents;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private void assembleDeviceList(NodeTreeVO node, String deviceName, SessionPool sessionPool)
+      throws BaseException {
+    List<String> descendants = findDescendants(deviceName, sessionPool);
+    if (descendants.size() == 0) {
+      return;
+    }
+    List<String> children = findChildren(descendants);
+    for (String child : children) {
+      NodeTreeVO childNode = new NodeTreeVO(child);
+      node.initChildren().add(childNode);
+      assembleDeviceList(childNode, child, sessionPool);
+    }
+  }
+
+  private List<String> findChildren(List<String> descendants) {
+    List<String> children = new ArrayList<>();
+    for (int i = 0; i < descendants.size(); i++) {
+      int tag = 0;
+      for (int j = 0; j < descendants.size(); j++) {
+        if (!descendants.get(i).equals(descendants.get(j))
+            && descendants.get(i).contains(descendants.get(j))
+            && StringUtils.removeStart(descendants.get(i), descendants.get(j)).startsWith(".")) {
+          tag++;
+        }
+      }
+      if (tag == 0) {
+        children.add(descendants.get(i));
+      }
+    }
+    return children;
+  }
+
+  private List<String> findDescendants(String deviceName, SessionPool sessionPool)
+      throws BaseException {
+    List<String> descendants = executeQueryOneColumn(sessionPool, "show devices " + deviceName);
+    if (descendants.size() != 0 && deviceName.equals(descendants.get(0))) {
+      descendants.remove(0);
+    }
+    return descendants;
+  }
+
+  @Override
+  public Boolean deviceExist(Connection connection, String groupName, String deviceName)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    try {
+      String sql = "show devices " + groupName;
+      List<String> devices = executeQueryOneColumn(sessionPool, sql);
+      Boolean isExist = false;
+      for (String device : devices) {
+        if (deviceName.equals(device)) {
+          isExist = true;
+          break;
+        }
+      }
+      return isExist;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
   }
 
   @Override
   public List<String> getTimeseries(Connection connection, String deviceName) throws BaseException {
-    paramValid(deviceName);
     SessionPool sessionPool = getSessionPool(connection);
     String sql = "show timeseries " + deviceName;
     SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, true);
@@ -725,32 +1782,358 @@ public class IotDBServiceImpl implements IotDBService {
     List<List<String>> valueList = sqlResultVO.getValueList();
     List<String> timeseries = new ArrayList<>();
     for (List<String> list : valueList) {
+      String measurementName = list.get(0);
+      if (StringUtils.removeStart(measurementName, deviceName + ".").contains(".")) {
+        continue;
+      }
       timeseries.add(list.get(index));
     }
     return timeseries;
   }
 
   @Override
-  public void setUserPrivileges(
-      Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO)
+  public DataVO getDataByDevice(
+      Connection connection,
+      String deviceName,
+      Integer pageSize,
+      Integer pageNum,
+      DataQueryDTO dataQueryDTO)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    List<String> measurementList = dataQueryDTO.getMeasurementList();
+    List<String> newMeasurementList = new ArrayList<>();
+    for (String measurement : measurementList) {
+      newMeasurementList.add(StringUtils.removeStart(measurement, deviceName + "."));
+    }
+
+    String basicSql = "select " + String.join(",", newMeasurementList) + " from " + deviceName;
+    String whereClause = getWhereClause(dataQueryDTO);
+    String limitClause = " limit " + pageSize + " offset " + (pageNum - 1) * pageSize;
+    String sql = basicSql + whereClause + limitClause;
+    try {
+      sessionPool = getSessionPool(connection);
+      DataVO dataVO = getDataBySql(sql, sessionPool);
+      Integer totalLine = getDataLineBySql(basicSql + whereClause, deviceName, sessionPool);
+      dataVO.setTotalCount(totalLine);
+      int totalPage = (totalLine + pageSize - 1) / pageSize;
+      dataVO.setTotalPage(totalPage);
+      return dataVO;
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private String getWhereClause(DataQueryDTO dataQueryDTO) {
+    Long startTime = null;
+    if (dataQueryDTO.getStartTime() != null) {
+      startTime = dataQueryDTO.getStartTime().getTime();
+    }
+    Long endTime = null;
+    if (dataQueryDTO.getEndTime() != null) {
+      endTime = dataQueryDTO.getEndTime().getTime();
+    }
+
+    String whereClause = "";
+    if (startTime != null && endTime != null) {
+      whereClause = " where time >= " + startTime + " and time <= " + endTime;
+    } else if (startTime == null && endTime != null) {
+      whereClause = " where time <= " + endTime;
+    } else if (startTime != null && endTime == null) {
+      whereClause = " where time >= " + startTime;
+    }
+    return whereClause;
+  }
+
+  private DataVO getDataBySql(String sql, SessionPool sessionPool) throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    DataVO dataVO = new DataVO();
+    List<List<String>> valueList = new ArrayList<>();
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      List<String> columnTypes = sessionDataSetWrapper.getColumnTypes();
+      dataVO.setTypeList(columnTypes);
+      List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+      dataVO.setMetaDataList(columnNames);
+      if ("Time".equals(columnNames.get(0))) {
+        while (sessionDataSetWrapper.hasNext()) {
+          List<String> lineValueList = new ArrayList<>();
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          long timestamp = rowRecord.getTimestamp();
+          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
+          Date date = new Date(timestamp);
+          String timeStr = simpleDateFormat.format(date);
+          lineValueList.add(timeStr);
+          for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
+            lineValueList.add(field.toString());
+          }
+          valueList.add(lineValueList);
+        }
+      } else {
+        while (sessionDataSetWrapper.hasNext()) {
+          List<String> lineValueList = new ArrayList<>();
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
+            lineValueList.add(field.toString());
+          }
+          valueList.add(lineValueList);
+        }
+      }
+      dataVO.setValueList(valueList);
+      return dataVO;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_TIMESERIES_DATA, ErrorCode.NO_PRI_TIMESERIES_DATA_MSG);
+      } else {
+        throw new BaseException(ErrorCode.GET_DATA_FAIL, ErrorCode.GET_DATA_FAIL_MSG);
+      }
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+    }
+  }
+
+  private Integer getDataLineBySql(String sql, String deviceName, SessionPool sessionPool)
+      throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      int lineCount = 0;
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      while (sessionDataSetWrapper.hasNext()) {
+        lineCount++;
+      }
+      return lineCount;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_TIMESERIES_DATA, ErrorCode.NO_PRI_TIMESERIES_DATA_MSG);
+      } else {
+        throw new BaseException(ErrorCode.GET_DATA_FAIL, ErrorCode.GET_DATA_FAIL_MSG);
+      }
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+    }
+  }
+
+  @Override
+  public void updateDataByDevice(
+      Connection connection, String deviceName, DataUpdateDTO dataUpdateDTO) throws BaseException {
+    SessionPool sessionPool = null;
+    long timestamp = dataUpdateDTO.getTimestamp().getTime();
+    List<String> measurementList = dataUpdateDTO.getMeasurementList();
+    List<String> valueList = dataUpdateDTO.getValueList();
+    List<String> newMeasurementList = new ArrayList<>();
+    for (String measurement : measurementList) {
+      newMeasurementList.add(StringUtils.removeStart(measurement, deviceName + "."));
+    }
+    try {
+      sessionPool = getSessionPool(connection);
+      sessionPool.insertRecord(deviceName, timestamp, newMeasurementList, valueList);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_INSERT_DATA, ErrorCode.NO_PRI_INSERT_DATA_MSG);
+      }
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.UPDATE_DATA_FAIL, ErrorCode.UPDATE_DATA_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public void deleteDataByDevice(
+      Connection connection, String deviceName, DataDeleteDTO dataDeleteDTO) throws BaseException {
+    SessionPool sessionPool = null;
+    List<Date> timestampList = dataDeleteDTO.getTimestampList();
+    List<String> timestampStrList = new ArrayList<>();
+    for (Date date : timestampList) {
+      timestampStrList.add(Long.toString(date.getTime()));
+    }
+    List<String> measurementList = dataDeleteDTO.getMeasurementList();
+    try {
+      sessionPool = getSessionPool(connection);
+      for (String measurement : measurementList) {
+        for (String timestamp : timestampStrList) {
+          String sql = "delete from " + measurement + " where time=" + timestamp;
+          sessionPool.executeNonQueryStatement(sql);
+        }
+      }
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+      }
+      throw new BaseException(ErrorCode.DELETE_DATA_FAIL, ErrorCode.DELETE_DATA_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  @Override
+  public void randomImport(
+      Connection connection, String deviceName, RandomImportDTO randomImportDTO)
+      throws BaseException {
+    SessionPool sessionPool = null;
+    int totalLine = randomImportDTO.getTotalLine();
+    int stepSize = randomImportDTO.getStepSize();
+    Long startTime = randomImportDTO.getStartTime().getTime();
+
+    List<Long> times = new ArrayList<>(totalLine);
+    List<List<String>> measurementsList = new ArrayList<>(totalLine);
+    List<List<Object>> valuesList = new ArrayList<>(totalLine);
+    List<List<TSDataType>> typesList = new ArrayList<>(totalLine);
+    try {
+      sessionPool = getSessionPool(connection);
+      SessionDataSetWrapper sessionDataSetWrapper =
+          sessionPool.executeQueryStatement("show timeseries " + deviceName);
+      List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+      sessionDataSetWrapper.getColumnTypes();
+      int timeseriesIndex = -1;
+      int dataTypeIndex = -1;
+      if (columnNames != null) {
+        for (int i = 0; i < columnNames.size(); i++) {
+          if ("timeseries".equalsIgnoreCase(columnNames.get(i))) {
+            timeseriesIndex = i;
+          }
+          if ("dataType".equalsIgnoreCase(columnNames.get(i))) {
+            dataTypeIndex = i;
+          }
+        }
+      }
+      if (timeseriesIndex == -1 || dataTypeIndex == -1) {
+        logger.error(ErrorCode.RANDOM_IMPORT_DATA_FAIL_MSG);
+        throw new BaseException(
+            ErrorCode.RANDOM_IMPORT_DATA_FAIL, ErrorCode.RANDOM_IMPORT_DATA_FAIL_MSG);
+      }
+
+      List<String> measurements = new ArrayList<>();
+      List<String> typesStr = new ArrayList<>();
+      while (sessionDataSetWrapper.hasNext()) {
+        RowRecord next = sessionDataSetWrapper.next();
+        String timeseries = next.getFields().get(timeseriesIndex).toString();
+        timeseries = StringUtils.removeStart(timeseries, deviceName + ".");
+        if (timeseries.contains(".")) {
+          continue;
+        }
+        measurements.add(timeseries);
+        String dataType = next.getFields().get(dataTypeIndex).toString();
+        typesStr.add(dataType);
+      }
+      if (measurements.size() == 0) {
+        logger.error(ErrorCode.NO_MEASUREMENT_MSG);
+        throw new BaseException(ErrorCode.NO_MEASUREMENT, ErrorCode.NO_MEASUREMENT_MSG);
+      }
+
+      List<TSDataType> types = handleTypeStr(typesStr);
+      List<String> devices = new ArrayList<>(totalLine);
+      for (int i = 0; i < totalLine; i++) {
+        typesList.add(types);
+        measurementsList.add(measurements);
+        devices.add(deviceName);
+
+        List<Object> values = createRandomData(typesStr);
+        valuesList.add(values);
+
+        times.add(stepSize * i + startTime);
+      }
+
+      sessionPool.insertRecords(devices, times, measurementsList, typesList, valuesList);
+
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      System.out.println(e.getStatusCode());
+      if (e.getMessage().contains("No permissions")) {
+        throw new BaseException(ErrorCode.NO_PRI_INSERT_DATA, ErrorCode.NO_PRI_INSERT_DATA_MSG);
+      }
+      throw new BaseException(
+          ErrorCode.RANDOM_IMPORT_DATA_FAIL, ErrorCode.RANDOM_IMPORT_DATA_FAIL_MSG);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+  }
+
+  private List<Object> createRandomData(List<String> types) throws BaseException {
+    Random random = new Random();
+    List<Object> values = new ArrayList<>();
+    for (String type : types) {
+      switch (type) {
+        case "BOOLEAN":
+          values.add(random.nextBoolean());
+          break;
+        case "INT32":
+          values.add(random.nextInt());
+          break;
+        case "INT64":
+          values.add(random.nextLong());
+          break;
+        case "FLOAT":
+          values.add(random.nextFloat());
+          break;
+        case "DOUBLE":
+          values.add(random.nextDouble());
+          break;
+        case "TEXT":
+          values.add(RandomStringUtils.randomAlphabetic(5));
+          break;
+        default:
+          throw new BaseException(ErrorCode.DB_DATATYPE_WRONG, ErrorCode.DB_DATATYPE_WRONG_MSG);
+      }
+    }
+    return values;
+  }
+
+  @Override
+  public String getSqlForExport(String deviceName, DataQueryDTO dataQueryDTO) throws BaseException {
+    List<String> measurementList = dataQueryDTO.getMeasurementList();
+    List<String> newMeasurementList = new ArrayList<>();
+    for (String measurement : measurementList) {
+      newMeasurementList.add(StringUtils.removeStart(measurement, deviceName + "."));
+    }
+    String whereClause = getWhereClause(dataQueryDTO);
+    String sql =
+        "select " + String.join(",", newMeasurementList) + " from " + deviceName + whereClause;
+    return sql;
+  }
+
+  @Override
+  public void upsertDataPrivileges(
+      Connection connection, String userOrRole, String name, PrivilegeInfoDTO privilegeInfoDTO)
       throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
-    // 授权
+    // grant
     List<String> privileges = privilegeInfoDTO.getPrivileges();
     if (notNullAndNotZero(privileges)) {
-      grantOrRevoke("grant", privileges, userName, privilegeInfoDTO, sessionPool);
+      grantOrRevoke("grant", userOrRole, privileges, name, privilegeInfoDTO, sessionPool);
     }
-    // 取消授权
+    // revoke
     List<String> cancelPrivileges = privilegeInfoDTO.getCancelPrivileges();
     if (notNullAndNotZero(cancelPrivileges)) {
-      grantOrRevoke("revoke", cancelPrivileges, userName, privilegeInfoDTO, sessionPool);
+      grantOrRevoke("revoke", userOrRole, cancelPrivileges, name, privilegeInfoDTO, sessionPool);
     }
-    cancelPathPrivileges(userName, privilegeInfoDTO, sessionPool);
+    cancelPathPrivileges(name, userOrRole, privilegeInfoDTO, sessionPool);
     sessionPool.close();
   }
 
   private void cancelPathPrivileges(
-      String userName, PrivilegeInfoDTO privilegeInfoDTO, SessionPool sessionPool) {
+      String name, String userOrRole, PrivilegeInfoDTO privilegeInfoDTO, SessionPool sessionPool)
+      throws BaseException {
     Integer type = privilegeInfoDTO.getType();
     List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
     List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
@@ -758,79 +2141,23 @@ public class IotDBServiceImpl implements IotDBService {
     switch (type) {
       case 1:
         if (notNullAndNotZero(delGroupPaths)) {
-          Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
-          for (String delGroupPath : delGroupPaths) {
-            for (String privilegesStr : privileges) {
-              String sql =
-                  "revoke user "
-                      + userName
-                      + " privileges '"
-                      + privilegesStr
-                      + "' on root."
-                      + delGroupPath;
-              try {
-                sessionPool.executeNonQueryStatement(sql);
-              } catch (StatementExecutionException e) {
-                logger.error(e.getMessage());
-              } catch (IoTDBConnectionException e) {
-                logger.error(e.getMessage());
-              }
-            }
+          for (String privilege : DATA_PRIVILEGES) {
+            grantOrRevokePaths("revoke", userOrRole, name, privilege, delGroupPaths, sessionPool);
           }
         }
         break;
       case 2:
         if (notNullAndNotZero(delDevicePaths)) {
-          Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
-          String onlyGroupPath = delGroupPaths.get(0);
-          for (String delDevicePath : delDevicePaths) {
-            for (String privilegesStr : privileges) {
-              String sql =
-                  "revoke user "
-                      + userName
-                      + " privileges '"
-                      + privilegesStr
-                      + "' on root."
-                      + onlyGroupPath
-                      + "."
-                      + delDevicePath;
-              try {
-                sessionPool.executeNonQueryStatement(sql);
-              } catch (StatementExecutionException e) {
-                logger.error(e.getMessage());
-              } catch (IoTDBConnectionException e) {
-                logger.error(e.getMessage());
-              }
-            }
+          for (String privilege : DATA_PRIVILEGES) {
+            grantOrRevokePaths("revoke", userOrRole, name, privilege, delDevicePaths, sessionPool);
           }
         }
         break;
       case 3:
         if (notNullAndNotZero(delTimeseriesPaths)) {
-          Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
-          String onlyGroupPath = delGroupPaths.get(0);
-          String onlyDevicePath = delDevicePaths.get(0);
-          for (String delTimeseriesPath : delTimeseriesPaths) {
-            for (String privilegesStr : privileges) {
-              String sql =
-                  "revoke user "
-                      + userName
-                      + " privileges '"
-                      + privilegesStr
-                      + "' on root."
-                      + onlyGroupPath
-                      + "."
-                      + onlyDevicePath
-                      + "."
-                      + delTimeseriesPath;
-              try {
-                sessionPool.executeNonQueryStatement(sql);
-              } catch (StatementExecutionException e) {
-                logger.error(e.getMessage());
-              } catch (IoTDBConnectionException e) {
-                logger.error(e.getMessage());
-              }
-            }
+          for (String privilege : DATA_PRIVILEGES) {
+            grantOrRevokePaths(
+                "revoke", userOrRole, name, privilege, delTimeseriesPaths, sessionPool);
           }
         }
         break;
@@ -838,41 +2165,58 @@ public class IotDBServiceImpl implements IotDBService {
   }
 
   @Override
-  public RecordVO getRecords(Connection connection, String deviceName, String timeseriesName)
+  public RecordVO getRecords(
+      Connection connection, String deviceName, String timeseriesName, String dataType)
       throws BaseException {
-    SessionPool sessionPool = getSessionPool(connection);
+    SessionPool sessionPool = null;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
     RecordVO recordVO = new RecordVO();
     List<Date> timeList = new ArrayList<>();
-    List<Long> valueList = new ArrayList<>();
+    List<String> valueList = new ArrayList<>();
+    Map<String, Integer> textCount = new HashMap<>();
     String sql =
-        "select time,"
-            + timeseriesName
+        "select "
+            + StringUtils.removeStart(timeseriesName, deviceName + ".")
             + " from "
             + deviceName
             + " order by time desc limit 200 offset 0";
     try {
-      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-      int batchSize = sessionDataSetWrapper.getBatchSize();
-      if (batchSize > 0) {
-        while (sessionDataSetWrapper.hasNext()) {
+      sessionPool = getSessionPool(connection);
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      while (sessionDataSetWrapper.hasNext()) {
+        if ("TEXT".equals(dataType)) {
+          RowRecord next = sessionDataSetWrapper.next();
+          String text = next.getFields().get(0).toString();
+          if (textCount.containsKey(text)) {
+            textCount.put(text, textCount.get(text) + 1);
+          } else {
+            textCount.put(text, 1);
+          }
+        } else if (StringUtils.equalsAny(
+            dataType, "INT32", "INT64", "BOOLEAN", "FLOAT", "DOUBLE")) {
           RowRecord next = sessionDataSetWrapper.next();
           Date date = new Date(next.getTimestamp());
           timeList.add(date);
           List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
-          Long value = Long.valueOf(fields.get(0).toString());
-          valueList.add(value);
+          valueList.add(fields.get(0).toString());
+        } else {
+          throw new BaseException(ErrorCode.DB_DATATYPE_WRONG, ErrorCode.DB_DATATYPE_WRONG_MSG);
         }
       }
+      recordVO.setTimeList(timeList);
+      recordVO.setValueList(valueList);
+      recordVO.setTextCount(textCount);
+      return recordVO;
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+      closeSessionPool(sessionPool);
     }
-    recordVO.setTimeList(timeList);
-    recordVO.setValueList(valueList);
-    return recordVO;
   }
 
   @Override
@@ -887,42 +2231,25 @@ public class IotDBServiceImpl implements IotDBService {
       id_plus_timestamp = id + ":" + timestamp;
       QUERY_STOP.put(id_plus_timestamp, true);
       for (String sql : sqls) {
-        int firstSpaceIndex = sql.indexOf(" ");
-        String judge = sql.substring(0, firstSpaceIndex);
-        if ("show".equalsIgnoreCase(judge)
-            || "count".equalsIgnoreCase(judge)
-            || "list".equalsIgnoreCase(judge)) {
-          SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, false);
-          results.add(sqlResultVO);
+        if (StringUtils.isBlank(sql)) {
           continue;
         }
-        if ("select".equalsIgnoreCase(judge)) {
-          SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, true);
+        String judge = sql.toLowerCase();
+        if (judge.startsWith("show")
+            || judge.startsWith("count")
+            || judge.startsWith("list")
+            || judge.startsWith("select")) {
+          SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, id_plus_timestamp);
           results.add(sqlResultVO);
           continue;
-        }
-        try {
-          if (QUERY_STOP.get(id_plus_timestamp)) {
-            String sqlCheck = sql.toLowerCase();
-            if (sqlCheck != null && sqlCheck.contains("insert")) {
-              String s = sqlCheck;
-              String[] split = s.split("\\.");
-              if (split.length <= 2) {
-                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
-              }
-            }
-            if (sqlCheck != null && sqlCheck.contains("create timeseries")) {
-              String s = sqlCheck;
-              String[] split = s.split("\\.");
-              if (split.length <= 3) {
-                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
-              }
-            }
+        }
+        try {
+          if (QUERY_STOP.get(id_plus_timestamp)) {
             long start = System.currentTimeMillis();
             sessionPool.executeNonQueryStatement(sql);
             long end = System.currentTimeMillis();
-            double time = (end - start + 0.0d) / 1000;
-            String queryTime = time + "s";
+            long time = end - start;
+            String queryTime = time + "ms";
             SqlResultVO sqlResultVO = new SqlResultVO();
             sqlResultVO.setQueryTime(queryTime);
             sqlResultVO.setLine(0L);
@@ -932,18 +2259,19 @@ public class IotDBServiceImpl implements IotDBService {
           logger.error(e.getMessage());
           throw new BaseException(
               ErrorCode.SQL_EP,
-              ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
+              ErrorCode.SQL_EP_MSG
+                  + ":["
+                  + sql
+                  + "]statement execution error, error message:["
+                  + e.getMessage()
+                  + "]");
         } catch (IoTDBConnectionException e) {
           logger.error(e.getMessage());
-          throw new BaseException(
-              ErrorCode.SQL_EP,
-              ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
+          throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
         }
       }
     } finally {
-      if (sessionPool != null) {
-        sessionPool.close();
-      }
+      closeSessionPool(sessionPool);
     }
     QUERY_STOP.remove(id_plus_timestamp);
     return results;
@@ -962,6 +2290,8 @@ public class IotDBServiceImpl implements IotDBService {
       throw new BaseException(ErrorCode.UPDATE_PWD_FAIL, ErrorCode.UPDATE_PWD_FAIL_MSG);
     } catch (IoTDBConnectionException e) {
       e.printStackTrace();
+    } finally {
+      closeSessionPool(sessionPool);
     }
   }
 
@@ -976,118 +2306,71 @@ public class IotDBServiceImpl implements IotDBService {
   }
 
   private void grantOrRevoke(
-      String word,
+      String grantOrRevoke,
+      String userOrRole,
       List<String> privileges,
-      String userName,
+      String name,
       PrivilegeInfoDTO privilegesInfo,
       SessionPool sessionPool)
       throws BaseException {
     Integer type = privilegesInfo.getType();
-    //        String privilegesStr = String.join("','", privileges); 一起存会有bug
-    for (String privilegesStr : privileges) {
+    for (String privilege : privileges) {
       if (type == 0) {
-        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root";
+        grantOrRevokePaths(
+            grantOrRevoke, userOrRole, name, privilege, Arrays.asList("root"), sessionPool);
+      } else if (type == 1) {
+        List<String> groupPaths = privilegesInfo.getGroupPaths();
+        grantOrRevokePaths(grantOrRevoke, userOrRole, name, privilege, groupPaths, sessionPool);
+      } else if (type == 2) {
+        List<String> devicePaths = privilegesInfo.getDevicePaths();
+        grantOrRevokePaths(grantOrRevoke, userOrRole, name, privilege, devicePaths, sessionPool);
+      } else if (type == 3) {
+        List<String> timeseriesPaths = privilegesInfo.getTimeseriesPaths();
+        grantOrRevokePaths(
+            grantOrRevoke, userOrRole, name, privilege, timeseriesPaths, sessionPool);
+      } else {
+        throw new BaseException(ErrorCode.NO_TYPE, ErrorCode.NO_TYPE_MSG);
+      }
+    }
+  }
+
+  private void grantOrRevokePaths(
+      String grantOrRevoke,
+      String userOrRole,
+      String name,
+      String privilege,
+      List<String> paths,
+      SessionPool sessionPool)
+      throws BaseException {
+    if (notNullAndNotZero(paths)) {
+      for (String groupPath : paths) {
+        String sql =
+            grantOrRevoke
+                + " "
+                + userOrRole
+                + " "
+                + name
+                + " privileges '"
+                + privilege
+                + "' on "
+                + groupPath;
         try {
           sessionPool.executeNonQueryStatement(sql);
         } catch (StatementExecutionException e) {
           logger.error(e.getMessage());
+          if (e.getStatusCode() == 602) {
+            throw new BaseException(
+                ErrorCode.NO_PRI_GRANT_PRIVILEGE, ErrorCode.NO_PRI_GRANT_PRIVILEGE_MSG);
+          }
         } catch (IoTDBConnectionException e) {
           logger.error(e.getMessage());
+          throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
         }
-        continue;
-      }
-      if (type == 1) {
-        List<String> groupPaths = privilegesInfo.getGroupPaths();
-        if (notNullAndNotZero(groupPaths)) {
-          for (String groupPath : groupPaths) {
-            String sql =
-                word
-                    + " user "
-                    + userName
-                    + " privileges '"
-                    + privilegesStr
-                    + "' on root."
-                    + groupPath;
-            try {
-              sessionPool.executeNonQueryStatement(sql);
-            } catch (StatementExecutionException e) {
-              logger.error(e.getMessage());
-            } catch (IoTDBConnectionException e) {
-              logger.error(e.getMessage());
-            }
-          }
-        }
-        continue;
-      }
-      if (type == 2) {
-        List<String> groupPaths = privilegesInfo.getGroupPaths();
-        List<String> devicePaths = privilegesInfo.getDevicePaths();
-        if (notNullAndNotZero(groupPaths)
-            && groupPaths.size() == 1
-            && notNullAndNotZero(devicePaths)) {
-          String onlyGroupPath = groupPaths.get(0);
-          for (String devicePath : devicePaths) {
-            String sql =
-                word
-                    + " user "
-                    + userName
-                    + " privileges '"
-                    + privilegesStr
-                    + "' on root."
-                    + onlyGroupPath
-                    + "."
-                    + devicePath;
-            try {
-              sessionPool.executeNonQueryStatement(sql);
-            } catch (StatementExecutionException e) {
-              logger.error(e.getMessage());
-            } catch (IoTDBConnectionException e) {
-              logger.error(e.getMessage());
-            }
-          }
-        }
-        continue;
-      }
-      if (type == 3) {
-        List<String> groupPaths = privilegesInfo.getGroupPaths();
-        List<String> devicePaths = privilegesInfo.getDevicePaths();
-        List<String> timeseriesPaths = privilegesInfo.getTimeseriesPaths();
-        if (notNullAndNotZero(groupPaths)
-            && groupPaths.size() == 1
-            && notNullAndNotZero(devicePaths)
-            && devicePaths.size() == 1
-            && notNullAndNotZero(timeseriesPaths)) {
-          String onlyGroupPath = groupPaths.get(0);
-          String onlyDevicePath = devicePaths.get(0);
-          for (String timeseriesPath : timeseriesPaths) {
-            String sql =
-                word
-                    + " user "
-                    + userName
-                    + " privileges '"
-                    + privilegesStr
-                    + "' on root."
-                    + onlyGroupPath
-                    + "."
-                    + onlyDevicePath
-                    + "."
-                    + timeseriesPath;
-            try {
-              sessionPool.executeNonQueryStatement(sql);
-            } catch (StatementExecutionException e) {
-              logger.error(e.getMessage());
-            } catch (IoTDBConnectionException e) {
-              logger.error(e.getMessage());
-            }
-          }
-        }
-        continue;
       }
-      throw new BaseException(ErrorCode.NO_TYPE, ErrorCode.NO_TYPE_MSG);
     }
   }
 
-  /** 判断集合不为空且长度大于0 */
+  /** Determines that the list is not empty and has a length greater than 0 */
   private boolean notNullAndNotZero(List list) {
     if (list != null && list.size() > 0) {
       return true;
@@ -1095,10 +2378,36 @@ public class IotDBServiceImpl implements IotDBService {
     return false;
   }
 
+  private List<String> executeQueryOneLine(SessionPool sessionPool, String sql)
+      throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      List<String> valueList = new ArrayList<>();
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      if (sessionDataSetWrapper.hasNext()) {
+        RowRecord rowRecord = sessionDataSetWrapper.next();
+        List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+        for (org.apache.iotdb.tsfile.read.common.Field field : fields) {
+          valueList.add(field.toString());
+        }
+      }
+      return valueList;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
+    }
+  }
+
   private String executeQueryOneLine(SessionPool sessionPool, String sql, String queryField)
       throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
     try {
-      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
       List<String> columnNames = sessionDataSetWrapper.getColumnNames();
       int index = -1;
       for (int i = 0; i < columnNames.size(); i++) {
@@ -1122,21 +2431,24 @@ public class IotDBServiceImpl implements IotDBService {
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } finally {
+      closeResultSet(sessionDataSetWrapper);
     }
-    throw new BaseException(ErrorCode.NO_GROUP, ErrorCode.NO_GROUP_MSG);
+    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
   }
 
   private SqlResultVO executeQuery(SessionPool sessionPool, String sql, Boolean closePool)
       throws BaseException {
     SqlResultVO sqlResultVO = new SqlResultVO();
     List<List<String>> valuelist = new ArrayList<>();
+    SessionDataSetWrapper sessionDataSetWrapper = null;
     try {
-      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
       long start = System.currentTimeMillis();
       List<String> columnNames = sessionDataSetWrapper.getColumnNames();
       sqlResultVO.setMetaDataList(columnNames);
       int batchSize = sessionDataSetWrapper.getBatchSize();
-      // 记录行数
+
       long count = 0;
       if (batchSize > 0) {
         while (sessionDataSetWrapper.hasNext()) {
@@ -1153,7 +2465,9 @@ public class IotDBServiceImpl implements IotDBService {
         String queryTime = time + "s";
         sqlResultVO.setQueryTime(queryTime);
         sqlResultVO.setLine(count);
+        sqlResultVO.setValueList(valuelist);
       }
+      return sqlResultVO;
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
@@ -1161,26 +2475,28 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
     } finally {
+      closeResultSet(sessionDataSetWrapper);
       if (sessionPool != null && closePool) {
         sessionPool.close();
       }
     }
-    sqlResultVO.setValueList(valuelist);
-    return sqlResultVO;
   }
 
-  private SqlResultVO executeQuery(
-      SessionPool sessionPool, String sql, Boolean closePool, String notStopKey, boolean timeFlag)
+  private SqlResultVO executeQuery(SessionPool sessionPool, String sql, String notStopKey)
       throws BaseException {
     SqlResultVO sqlResultVO = new SqlResultVO();
     List<List<String>> valuelist = new ArrayList<>();
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    boolean timeFlag = false;
     try {
-      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
       long start = System.currentTimeMillis();
       List<String> columnNames = sessionDataSetWrapper.getColumnNames();
       sqlResultVO.setMetaDataList(columnNames);
+      if ("Time".equals(columnNames.get(0))) {
+        timeFlag = true;
+      }
       int batchSize = sessionDataSetWrapper.getBatchSize();
-      // 记录行数
       long count = 0;
       if (batchSize > 0) {
         while (sessionDataSetWrapper.hasNext() && QUERY_STOP.get(notStopKey)) {
@@ -1200,25 +2516,26 @@ public class IotDBServiceImpl implements IotDBService {
           valuelist.add(strList);
         }
         long end = System.currentTimeMillis();
-        double time = (end - start + 0.0d) / 1000;
-        String queryTime = time + "s";
+        long time = end - start;
+        String queryTime = time + "ms";
         sqlResultVO.setQueryTime(queryTime);
         sqlResultVO.setLine(count);
       }
-    } catch (IoTDBConnectionException e) {
-      logger.error(e.getMessage());
-      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
-      if (e.getStatusCode() == 602) {
-        throw new BaseException(
-            ErrorCode.NO_PRI_TIMESERIES_DATA, ErrorCode.NO_PRI_TIMESERIES_DATA_MSG);
-      }
-      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+      throw new BaseException(
+          ErrorCode.SQL_EP,
+          ErrorCode.SQL_EP_MSG
+              + ":["
+              + sql
+              + "]statement execution error, error message:["
+              + e.getMessage()
+              + "]");
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     } finally {
-      if (sessionPool != null && closePool) {
-        sessionPool.close();
-      }
+      closeResultSet(sessionDataSetWrapper);
     }
     sqlResultVO.setValueList(valuelist);
     return sqlResultVO;
@@ -1271,9 +2588,7 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
     } finally {
-      if (sessionDataSetWrapper != null) {
-        sessionDataSetWrapper.close();
-      }
+      closeResultSet(sessionDataSetWrapper);
     }
   }
 
@@ -1305,9 +2620,7 @@ public class IotDBServiceImpl implements IotDBService {
       throw new BaseException(
           ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
     } finally {
-      if (sessionDataSetWrapper != null) {
-        sessionDataSetWrapper.close();
-      }
+      closeResultSet(sessionDataSetWrapper);
     }
   }
 
@@ -1344,18 +2657,17 @@ public class IotDBServiceImpl implements IotDBService {
       throw new BaseException(
           ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
     } finally {
-      if (sessionDataSetWrapper != null) {
-        sessionDataSetWrapper.close();
-      }
+      closeResultSet(sessionDataSetWrapper);
     }
   }
 
   private List<String> executeQueryOneColumn(SessionPool sessionPool, String sql)
       throws BaseException {
     SessionDataSetWrapper sessionDataSetWrapper = null;
+    ExecutorService service = null;
     try {
       Callable call = () -> sessionPool.executeQueryStatement(sql);
-      ExecutorService service = Executors.newFixedThreadPool(1);
+      service = Executors.newFixedThreadPool(1);
       Future submit = service.submit(call);
       sessionDataSetWrapper = (SessionDataSetWrapper) submit.get(60, TimeUnit.SECONDS);
       int batchSize = sessionDataSetWrapper.getBatchSize();
@@ -1370,12 +2682,15 @@ public class IotDBServiceImpl implements IotDBService {
       return values;
     } catch (IoTDBConnectionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(
-          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
     } catch (StatementExecutionException e) {
       logger.error(e.getMessage());
-      throw new BaseException(
-          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_DO_THIS, ErrorCode.NO_PRI_DO_THIS_MSG);
+      } else {
+        throw new BaseException(
+            ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+      }
     } catch (InterruptedException e) {
       e.printStackTrace();
       throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
@@ -1389,303 +2704,14 @@ public class IotDBServiceImpl implements IotDBService {
       logger.error(e.getMessage());
       throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
     } finally {
-      if (sessionDataSetWrapper != null) {
-        sessionDataSetWrapper.close();
-      }
-    }
-  }
-
-  private List<PrivilegeInfo> privilegesStrSwitchToObject(
-      SessionPool sessionPool, List<String> privileges) throws BaseException {
-    List<PrivilegeInfo> results = new ArrayList<>();
-    List<String> pathStr = new ArrayList<>();
-    List<List<String>> privilegeStr = new ArrayList<>();
-    HashMap<String, Boolean> rootPrivileges = new HashMap();
-    // 遍历集合 将路径和权限集合分别装 过程中 将root相关内容处理
-    for (int i = 0; i < privileges.size(); i++) {
-      String[] split = privileges.get(i).split(":");
-      String[] s = split[1].trim().split(" ");
-      String path = split[0].trim();
-      // 为root特殊处理
-      if ("root".equals(path)) {
-        for (String s1 : s) {
-          if (rootPrivileges.containsKey(s1)) {
-            continue;
-          }
-          rootPrivileges.put(s1, true);
-        }
-        continue;
-      }
-      List<String> list = new ArrayList<>();
-      pathStr.add(path);
-      // 其他粒度下 只需要存储SPECIAL_PRIVILEGES四种权限
-      for (String s1 : s) {
-        if (SPECIAL_PRIVILEGES.containsKey(s1)) {
-          list.add(s1);
-          continue;
-        }
-        // 除了root这一层级 其他此权限不生效 不添加进root权限集合
-        if (NO_NEED_PRIVILEGES.equals(s1)) {
-          continue;
-        }
-        if (rootPrivileges.containsKey(s1)) {
-          continue;
-        }
-        rootPrivileges.put(s1, true);
-      }
-      privilegeStr.add(list);
-    }
-    // 先处理root 生成对象
-    Set<String> strings = rootPrivileges.keySet();
-    List<String> rootPrivilege = Arrays.asList(strings.toArray(new String[0]));
-    if (rootPrivilege != null && rootPrivilege.size() > 0) {
-      PrivilegeInfo privilegeInfo = new PrivilegeInfo();
-      privilegeInfo.setType(0);
-      privilegeInfo.setPrivileges(rootPrivilege);
-      results.add(privilegeInfo);
-    }
-    // 处理非root  String存储形式 "权限1 权限2 权限3.." List存储相同并集下的path路径
-    Map<String, List<String>> privilegeOne = new HashMap<>();
-    Map<String, List<String>> privilegeTwo = new HashMap<>();
-    Map<String, List<String>> privilegeThree = new HashMap<>();
-    for (int i = 0; i < pathStr.size(); i++) {
-      String s = pathStr.get(i);
-      List<String> list = privilegeStr.get(i);
-      String str = String.join(" ", list);
-      // 通过路径获取所属粒度
-      int type = findType(sessionPool, s);
-      if (type == 1) {
-        // 判断相同的权限集合 放入同一list
-        if (privilegeOne.containsKey(str)) {
-          List<String> typeList = privilegeOne.get(str);
-          typeList.add(s);
-          continue;
-        }
-        ArrayList<String> newStr = new ArrayList();
-        newStr.add(s);
-        privilegeOne.put(str, newStr);
-        continue;
-      }
-      if (type == 2) {
-        // 判断相同的权限集合 放入同一list
-        if (privilegeTwo.containsKey(str)) {
-          List<String> typeList = privilegeTwo.get(str);
-          // 相同粒度 同一范围下做前缀判断 相同则为一个并集
-          int existEnd = typeList.get(0).lastIndexOf(".");
-          int end = s.lastIndexOf(".");
-          if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
-            typeList.add(s);
-            continue;
-          }
-        }
-        ArrayList<String> newStr = new ArrayList();
-        newStr.add(s);
-        privilegeTwo.put(str, newStr);
-        continue;
-      }
-      if (type == 3) {
-        if (privilegeThree.containsKey(str)) {
-          List<String> typeList = privilegeThree.get(str);
-          int existEnd = typeList.get(0).lastIndexOf(".");
-          int end = s.lastIndexOf(".");
-          if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
-            typeList.add(s);
-            continue;
-          }
-        }
-        ArrayList<String> newStr = new ArrayList();
-        newStr.add(s);
-        privilegeThree.put(str, newStr);
-      }
-    }
-    Set<String> oneKeys = privilegeOne.keySet();
-    Set<String> twoKeys = privilegeTwo.keySet();
-    Set<String> threeKeys = privilegeThree.keySet();
-    // 封装成PrivilegeInfo返回 字符串处理
-    for (String oneKey : oneKeys) {
-      PrivilegeInfo oneInfo = new PrivilegeInfo();
-      List<String> groupPath = new ArrayList<>();
-      List<String> list = privilegeOne.get(oneKey);
-      for (String s : list) {
-        String groupName = s.replaceFirst("root.", "");
-        groupPath.add(groupName);
-      }
-      List<String> privilegesOne = Arrays.asList(oneKey.split(" "));
-      String sql = "show storage group";
-      List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
-      List<String> allGroupPaths = new ArrayList<>();
-      for (String s : allGroupPathsStr) {
-        String field = s.replaceFirst("root.", "");
-        allGroupPaths.add(field);
-      }
-      // 展示数据
-      oneInfo.setType(1);
-      oneInfo.setPrivileges(privilegesOne);
-      // allxxx内容为前端编辑修改时需要的数据
-      oneInfo.setGroupPaths(groupPath);
-      oneInfo.setAllGroupPaths(allGroupPaths);
-      results.add(oneInfo);
-    }
-    for (String twoKey : twoKeys) {
-      PrivilegeInfo twoInfo = new PrivilegeInfo();
-      List<String> groupPath = new ArrayList<>();
-      List<String> devicePath = new ArrayList<>();
-      List<String> list = privilegeTwo.get(twoKey);
-      // 得到 组名、设备名、测点名  便于后续字符串操作
-      PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
-      groupPath.add(pathVO.getGroupName());
-      for (String s : list) {
-        String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
-        devicePath.add(deviceName);
-      }
-      List<String> privilegesTwo = Arrays.asList(twoKey.split(" "));
-      String sql = "show storage group";
-      List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
-      List<String> allGroupPaths = new ArrayList<>();
-      for (String s : allGroupPathsStr) {
-        String field = s.replaceFirst("root.", "");
-        allGroupPaths.add(field);
-      }
-      int end = list.get(0).lastIndexOf(".");
-      sql = "show devices " + list.get(0).substring(0, end) + ".*";
-      List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
-      List<String> allDevicePaths = new ArrayList<>();
-      for (String s : allDevicePathsStr) {
-        String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
-        allDevicePaths.add(field);
-      }
-      // 展示数据
-      twoInfo.setType(2);
-      twoInfo.setPrivileges(privilegesTwo);
-      twoInfo.setGroupPaths(groupPath);
-      twoInfo.setDevicePaths(devicePath);
-      // allxxx内容为前端编辑修改时需要的数据
-      twoInfo.setAllGroupPaths(allGroupPaths);
-      twoInfo.setAllDevicePaths(allDevicePaths);
-      results.add(twoInfo);
-    }
-    for (String threeKey : threeKeys) {
-      PrivilegeInfo threeInfo = new PrivilegeInfo();
-      List<String> groupPath = new ArrayList<>();
-      List<String> devicePath = new ArrayList<>();
-      List<String> timeseriesPath = new ArrayList<>();
-      List<String> list = privilegeThree.get(threeKey);
-      // 得到 组名、设备名、测点名  便于后续字符串操作
-      PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
-      groupPath.add(pathVO.getGroupName());
-      devicePath.add(pathVO.getDeviceName());
-      for (String s : list) {
-        String timeseriesName =
-            s.replaceFirst(
-                "root." + pathVO.getGroupName() + "." + pathVO.getDeviceName() + ".", "");
-        timeseriesPath.add(timeseriesName);
-      }
-      List<String> privilegesOne = Arrays.asList(threeKey.split(" "));
-      String sql = "show storage group";
-      List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
-      List<String> allGroupPaths = new ArrayList<>();
-      for (String s : allGroupPathsStr) {
-        String field = s.replaceFirst("root.", "");
-        allGroupPaths.add(field);
-      }
-      sql = "show devices root." + pathVO.getGroupName() + ".*";
-      List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
-      List<String> allDevicePaths = new ArrayList<>();
-      for (String s : allDevicePathsStr) {
-        String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
-        allDevicePaths.add(deviceName);
-      }
-      int end = list.get(0).lastIndexOf(".");
-      sql = "show timeseries " + list.get(0).substring(0, end) + ".*";
-      List<String> allTimeseriesPathsStr = executeQueryOneColumn(sessionPool, sql);
-      List<String> allTimeseriesPaths = new ArrayList<>();
-      for (String s : allTimeseriesPathsStr) {
-        String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
-        allTimeseriesPaths.add(field);
-      }
-      // 展示数据
-      threeInfo.setType(3);
-      threeInfo.setPrivileges(privilegesOne);
-      threeInfo.setGroupPaths(groupPath);
-      threeInfo.setDevicePaths(devicePath);
-      threeInfo.setTimeseriesPaths(timeseriesPath);
-      // allxxx内容为前端编辑修改时需要的数据
-      threeInfo.setAllGroupPaths(allGroupPaths);
-      threeInfo.setAllDevicePaths(allDevicePaths);
-      threeInfo.setAllTimeseriesPaths(allTimeseriesPaths);
-      results.add(threeInfo);
-    }
-    return results;
-  }
-
-  private PathVO splitPathToPathVO(SessionPool sessionPool, String s) throws BaseException {
-    PathVO pathVO = new PathVO();
-    while (!"root".equals(s)) {
-      String sql = "count devices " + s;
-      Integer isDevice = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-      sql = "count storage group " + s;
-      Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-      // 为测点
-      if (isDevice == 0 && isGroup == 0) {
-        int mid = s.lastIndexOf(".");
-        String timeseriesName = s.substring(mid + 1);
-        pathVO.setTimeseriesName(timeseriesName);
-        s = s.substring(0, mid);
-        continue;
-      }
-      // 既是存储组也是实体
-      if (isDevice == 1 && isGroup == 1) {
-        String deviceName = s.replaceFirst("root.", "");
-        String groupName = s.replaceFirst("root.", "");
-        pathVO.setGroupName(groupName);
-        pathVO.setDeviceName(deviceName);
-        break;
-      }
-      // 是存储组 判断是否还为实体
-      if (isDevice > 1 && isGroup == 1) {
-        sql = "show devices " + s;
-        List<String> list = executeQueryOneColumn(sessionPool, sql);
-        if (list.contains(s)) {
-          String deviceName = s.replaceFirst("root.", "");
-          String groupName = s.replaceFirst("root.", "");
-          pathVO.setGroupName(groupName);
-          pathVO.setDeviceName(deviceName);
-          break;
-        }
-        String groupName = s.replaceFirst("root.", "");
-        pathVO.setGroupName(groupName);
-      }
-      // 为存储组
-      if (isDevice == 0 && isGroup == 1) {
-        String groupName = s.replaceFirst("root.", "");
-        pathVO.setGroupName(groupName);
-        break;
-      }
-      // 实体 实体之下还可以有实体 需要遍历有多少层级
-      if (isDevice >= 1 && isGroup == 0) {
-        String oldS = s;
-        while (true) {
-          int mid = s.lastIndexOf(".");
-          s = s.substring(0, mid);
-          sql = "count storage group " + s;
-          isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-          if (isGroup > 0) {
-            String deviceName = oldS.replaceFirst(s + ".", "");
-            String groupName = s.replaceFirst("root.", "");
-            pathVO.setGroupName(groupName);
-            pathVO.setDeviceName(deviceName);
-            break;
-          }
-        }
-        break;
-      }
+      service.shutdown();
+      closeResultSet(sessionDataSetWrapper);
     }
-    return pathVO;
   }
 
-  private int findType(SessionPool sessionPool, String s) throws BaseException {
-    // 主要用于判断s路径是否已经不存在 iotdb存在已删除路径的权限还会展示出来的问题
-    String sql = "count timeseries " + s;
+  private int findType(SessionPool sessionPool, String path) throws BaseException {
+    // Check whether the path does not exist
+    String sql = "count timeseries " + path;
     SessionDataSetWrapper sessionDataSetWrapper = null;
     try {
       sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
@@ -1700,24 +2726,20 @@ public class IotDBServiceImpl implements IotDBService {
         sessionDataSetWrapper.close();
       }
     }
-    sql = "count storage group " + s;
+    sql = "count storage group " + path;
     Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-    if (isGroup == 1) {
+    if (isGroup >= 1) {
       return 1;
     }
-    // 无效路径 既不是root 也不是存储组 不展示到页面
-    if (isGroup > 1) {
-      return -1;
-    }
-    sql = "count devices " + s;
+    sql = "count devices " + path;
     Integer isDevices = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-    if (isDevices == 1) {
+    if (isDevices >= 1) {
       return 2;
     }
     return 3;
   }
 
-  private List<TSEncoding> handleEncodingStr(List<String> encoding) {
+  private List<TSEncoding> handleEncodingStr(List<String> encoding) throws BaseException {
     List<TSEncoding> list = new ArrayList<>();
     for (String s : encoding) {
       switch (s) {
@@ -1748,51 +2770,119 @@ public class IotDBServiceImpl implements IotDBService {
         case "GORILLA":
           list.add(TSEncoding.GORILLA);
           break;
+        default:
+          throw new BaseException(ErrorCode.DB_ENCODING_WRONG, ErrorCode.DB_ENCODING_WRONG_MSG);
       }
     }
     return list;
   }
 
-  private List<Object> handleValueStr(List<String> values, List<TSDataType> types)
+  private TSEncoding handleEncodingStr(String encoding) throws BaseException {
+    TSEncoding tsEncoding;
+    switch (encoding) {
+      case "PLAIN":
+        tsEncoding = TSEncoding.PLAIN;
+        break;
+      case "PLAIN_DICTIONARY":
+        tsEncoding = TSEncoding.PLAIN_DICTIONARY;
+        break;
+      case "RLE":
+        tsEncoding = TSEncoding.RLE;
+        break;
+      case "DIFF":
+        tsEncoding = TSEncoding.DIFF;
+        break;
+      case "TS_2DIFF":
+        tsEncoding = TSEncoding.TS_2DIFF;
+        break;
+      case "BITMAP":
+        tsEncoding = TSEncoding.BITMAP;
+        break;
+      case "GORILLA_V1":
+        tsEncoding = TSEncoding.GORILLA_V1;
+        break;
+      case "REGULAR":
+        tsEncoding = TSEncoding.REGULAR;
+        break;
+      case "GORILLA":
+        tsEncoding = TSEncoding.GORILLA;
+        break;
+      default:
+        throw new BaseException(ErrorCode.DB_ENCODING_WRONG, ErrorCode.DB_ENCODING_WRONG_MSG);
+    }
+    return tsEncoding;
+  }
+
+  private List<CompressionType> handleCompressionStr(List<String> compression)
       throws BaseException {
-    List<Object> list = new ArrayList<>();
-    for (int i = 0; i < types.size(); i++) {
-      TSDataType type = types.get(i);
-      if (type == TSDataType.BOOLEAN) {
-        Integer booleanNum = Integer.valueOf(values.get(i));
-        Boolean flag = null;
-        if (booleanNum == 0) {
-          flag = false;
-        }
-        if (booleanNum == 1) {
-          flag = true;
-        }
-        if (flag != null) {
-          list.add(flag);
-          continue;
-        }
-        throw new BaseException(ErrorCode.DB_BOOL_WRONG, ErrorCode.DB_BOOL_WRONG_MSG);
-      }
-      if (type == TSDataType.INT32 || type == TSDataType.INT64) {
-        Integer intNum = Integer.valueOf(values.get(i));
-        list.add(intNum);
-        continue;
-      }
-      if (type == TSDataType.FLOAT) {
-        Float floatNum = Float.valueOf(values.get(i));
-        list.add(floatNum);
-        continue;
-      }
-      if (type == TSDataType.DOUBLE) {
-        Double doubleNum = Double.valueOf(values.get(i));
-        list.add(doubleNum);
-        continue;
+    List<CompressionType> list = new ArrayList<>();
+    for (String s : compression) {
+      switch (s) {
+        case "UNCOMPRESSED":
+          list.add(CompressionType.UNCOMPRESSED);
+          break;
+        case "SNAPPY":
+          list.add(CompressionType.SNAPPY);
+          break;
+        case "GZIP":
+          list.add(CompressionType.GZIP);
+          break;
+        case "LZ4":
+          list.add(CompressionType.LZ4);
+          break;
+        case "LZO":
+          list.add(CompressionType.LZO);
+          break;
+        case "PLA":
+          list.add(CompressionType.PLA);
+          break;
+        case "PAA":
+          list.add(CompressionType.PAA);
+          break;
+        case "SDT":
+          list.add(CompressionType.SDT);
+          break;
+        default:
+          throw new BaseException(
+              ErrorCode.DB_COMPRESSION_WRONG, ErrorCode.DB_COMPRESSION_WRONG_MSG);
       }
-      list.add(values.get(i));
     }
     return list;
   }
 
+  private CompressionType handleCompressionStr(String compression) throws BaseException {
+    CompressionType compressionType;
+    switch (compression) {
+      case "UNCOMPRESSED":
+        compressionType = CompressionType.UNCOMPRESSED;
+        break;
+      case "SNAPPY":
+        compressionType = CompressionType.SNAPPY;
+        break;
+      case "GZIP":
+        compressionType = CompressionType.GZIP;
+        break;
+      case "LZ4":
+        compressionType = CompressionType.LZ4;
+        break;
+      case "LZO":
+        compressionType = CompressionType.LZO;
+        break;
+      case "PLA":
+        compressionType = CompressionType.PLA;
+        break;
+      case "PAA":
+        compressionType = CompressionType.PAA;
+        break;
+      case "SDT":
+        compressionType = CompressionType.SDT;
+        break;
+      default:
+        throw new BaseException(ErrorCode.DB_COMPRESSION_WRONG, ErrorCode.DB_COMPRESSION_WRONG_MSG);
+    }
+    return compressionType;
+  }
+
   private List<TSDataType> handleTypeStr(List<String> types) throws BaseException {
     List<TSDataType> list = new ArrayList<>();
     for (String type : types) {
@@ -1824,21 +2914,31 @@ public class IotDBServiceImpl implements IotDBService {
     return list;
   }
 
-  public static java.sql.Connection getConnection(Connection connection) throws BaseException {
-    String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
-    String url = "jdbc:iotdb://" + connection.getHost() + ":" + connection.getPort() + "/";
-    String username = connection.getUsername();
-    String password = connection.getPassword();
-    java.sql.Connection conn;
-    try {
-      Class.forName(driver);
-      conn = DriverManager.getConnection(url, username, password);
-    } catch (ClassNotFoundException e) {
-      throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
-    } catch (SQLException e) {
-      throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
+  private TSDataType handleTypeStr(String type) throws BaseException {
+    TSDataType tsDataType;
+    switch (type) {
+      case "BOOLEAN":
+        tsDataType = TSDataType.BOOLEAN;
+        break;
+      case "INT32":
+        tsDataType = TSDataType.INT32;
+        break;
+      case "INT64":
+        tsDataType = TSDataType.INT64;
+        break;
+      case "FLOAT":
+        tsDataType = TSDataType.FLOAT;
+        break;
+      case "DOUBLE":
+        tsDataType = TSDataType.DOUBLE;
+        break;
+      case "TEXT":
+        tsDataType = TSDataType.TEXT;
+        break;
+      default:
+        throw new BaseException(ErrorCode.DB_DATATYPE_WRONG, ErrorCode.DB_DATATYPE_WRONG_MSG);
     }
-    return conn;
+    return tsDataType;
   }
 
   public static SessionPool getSessionPool(Connection connection) throws BaseException {
@@ -1854,114 +2954,16 @@ public class IotDBServiceImpl implements IotDBService {
     }
     return sessionPool;
   }
-  //    public static SessionPool getSession(Connection connection) throws BaseException {
-  //        if(sessionPool == null){
-  //            host = connection.getHost();
-  //            port = connection.getPort();
-  //            username = connection.getUsername();
-  //            password = connection.getPassword();
-  //            sessionPool = new SessionPool(host,port,username,password,3);
-  //            return sessionPool;
-  //        }
-  //        if(host == connection.getHost() && port.equals(connection.getPort()) && username ==
-  // connection.getUsername() && password == connection.getPassword()){
-  //            return sessionPool;
-  //        }
-  //        sessionPool.close();
-  //        host = connection.getHost();
-  //        port = connection.getPort();
-  //        username = connection.getUsername();
-  //        password = connection.getPassword();
-  //        sessionPool = new SessionPool(host,port,username,password,3);
-  //        return sessionPool;
-  //    }
-
-  private void closeConnection(java.sql.Connection conn) throws BaseException {
-    try {
-      if (conn != null) {
-        conn.close();
-      }
-    } catch (SQLException e) {
-      throw new BaseException(ErrorCode.CLOSE_DBCONN_FAIL, ErrorCode.CLOSE_DBCONN_FAIL_MSG);
-    }
-  }
-
-  private String handlerPrivilegeStrToSql(String privilege, String userName, String roleName) {
-    int i = privilege.indexOf(":");
-    String path = privilege.substring(0, i).trim();
-    String[] privileges = privilege.substring(i + 1).trim().split(" ");
-    int len = privileges.length;
-    if (len == 0) {
-      return null;
-    }
-    StringBuilder str = new StringBuilder();
-    if (userName != null) {
-      str.append("grant user " + userName + " privileges ");
-    } else {
-      str.append("grant role " + roleName + " privileges ");
-    }
-    for (int j = 0; i < len - 1; j++) {
-      str.append("'" + privileges[j] + "',");
-    }
-    str.append("'" + privileges[len - 1] + "' on " + path);
-    return str.toString();
-  }
-
-  private SqlResultVO sqlQuery(java.sql.Connection conn, String sql) throws BaseException {
-    PreparedStatement statement = null;
-    ResultSet resultSet = null;
-    try {
-      statement = conn.prepareStatement(sql);
-      resultSet = statement.executeQuery();
-      ResultSetMetaData metaData = resultSet.getMetaData();
-      int columnCount = metaData.getColumnCount();
-      SqlResultVO sqlResultVO = new SqlResultVO();
-      List<String> metaDataList = new ArrayList<>();
-      for (int i = 0; i < columnCount; i++) {
-        metaDataList.add(metaData.getColumnLabel(i + 1));
-      }
-      sqlResultVO.setMetaDataList(metaDataList);
-      List<List<String>> valuelist = new ArrayList<>();
-      while (resultSet.next()) {
-        List<String> strList = new ArrayList<>();
-        for (int i = 0; i < columnCount; i++) {
-          strList.add(resultSet.getString(i + 1));
-        }
-        valuelist.add(strList);
-      }
-      sqlResultVO.setValueList(valuelist);
-      return sqlResultVO;
-    } catch (SQLException e) {
-      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-    } finally {
-      if (resultSet != null) {
-        try {
-          resultSet.close();
-        } catch (SQLException e) {
-          throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        }
-      }
-      if (statement != null) {
-        try {
-          statement.close();
-        } catch (SQLException e) {
-          throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        }
-      }
-      closeConnection(conn);
+
+  private void closeSessionPool(SessionPool sessionPool) {
+    if (sessionPool != null) {
+      sessionPool.close();
     }
   }
 
-  /**
-   * 防止sql注入对参数进行校验不能有空格
-   *
-   * @param field 拼接sql的字段
-   */
-  private void paramValid(String field) throws BaseException {
-    if (field != null) {
-      if (!field.matches("^[^ ]+$")) {
-        throw new BaseException(ErrorCode.SQL_PARAM_WRONG, ErrorCode.SQL_PARAM_WRONG_MSG);
-      }
+  private void closeResultSet(SessionDataSetWrapper sessionDataSetWrapper) {
+    if (sessionDataSetWrapper != null) {
+      sessionDataSetWrapper.close();
     }
   }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
index 4cc0ba2..1a4a252 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
@@ -125,7 +125,7 @@ public class MeasurementServiceImpl extends ServiceImpl<MeasurementMapper, Measu
       queryWrapper.eq("host", host);
       queryWrapper.eq("measurement_name", measurements.get(i));
       Measurement existMeasurement = measurementMapper.selectOne(queryWrapper);
-      // 未创建的测点
+      // Uncreated measurement
       if (existMeasurement == null) {
         Measurement mea = new Measurement();
         mea.setDescription(descriptions.get(i));
@@ -138,7 +138,7 @@ public class MeasurementServiceImpl extends ServiceImpl<MeasurementMapper, Measu
         }
         continue;
       }
-      // 已创建的测点更新描述
+      // Updated description of created measurement
       existMeasurement.setDescription(descriptions.get(i));
       int flag = measurementMapper.updateById(existMeasurement);
       if (flag <= 0) {
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
index a8b9490..ad09160 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
@@ -41,7 +41,7 @@ public class QueryServiceImpl extends ServiceImpl<QueryMapper, Query> implements
   @Autowired private QueryMapper queryMapper;
 
   @Override
-  public void save(Integer serverId, Query inputQuery) throws BaseException {
+  public Integer save(Integer serverId, Query inputQuery) throws BaseException {
     QueryWrapper queryWrapper = new QueryWrapper();
     queryWrapper.eq("connection_id", serverId);
     queryWrapper.eq("query_name", inputQuery.getQueryName());
@@ -52,7 +52,7 @@ public class QueryServiceImpl extends ServiceImpl<QueryMapper, Query> implements
       newQuery.setQueryName(inputQuery.getQueryName());
       newQuery.setSqls(inputQuery.getSqls());
       queryMapper.insert(newQuery);
-      return;
+      return queryMapper.selectOne(queryWrapper).getId();
     }
     throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
   }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/RoleServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/RoleServiceImpl.java
new file mode 100644
index 0000000..bca73bd
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/RoleServiceImpl.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.service.impl;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.mapper.RoleMapper;
+import org.apache.iotdb.admin.model.dto.IotDBRole;
+import org.apache.iotdb.admin.model.entity.Role;
+import org.apache.iotdb.admin.service.RoleService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
+
+  @Autowired private RoleMapper roleMapper;
+
+  @Override
+  public void upsertRoleInfo(String host, Integer port, IotDBRole iotDBRole) throws BaseException {
+    QueryWrapper<Role> wrapper = new QueryWrapper<>();
+    wrapper.eq("host", host);
+    wrapper.eq("port", port);
+    wrapper.eq("name", iotDBRole.getRoleName());
+    try {
+      Role role = roleMapper.selectOne(wrapper);
+      int flag = 0;
+      if (role == null) {
+        role = new Role();
+        role.setDescription(iotDBRole.getDescription());
+        role.setHost(host);
+        role.setPort(port);
+        role.setName(iotDBRole.getRoleName());
+        flag = roleMapper.insert(role);
+      } else {
+        role.setDescription(iotDBRole.getDescription());
+        flag = roleMapper.updateById(role);
+      }
+      if (flag == 0) {
+        throw new BaseException(
+            ErrorCode.UPSERT_ROLE_INFO_FAIL, ErrorCode.UPSERT_ROLE_INFO_FAIL_MSG);
+      }
+    } catch (Exception e) {
+      log.error(e.getMessage());
+      throw new BaseException(ErrorCode.UPSERT_ROLE_INFO_FAIL, ErrorCode.UPSERT_ROLE_INFO_FAIL_MSG);
+    }
+  }
+
+  @Override
+  public void deleteRoleInfo(String host, Integer port, String roleName) throws BaseException {
+    QueryWrapper<Role> wrapper = new QueryWrapper<>();
+    wrapper.eq("host", host);
+    wrapper.eq("port", port);
+    wrapper.eq("name", roleName);
+    try {
+      roleMapper.delete(wrapper);
+    } catch (Exception e) {
+      log.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_ROLE_INFO_FAIL, ErrorCode.DELETE_ROLE_INFO_FAIL_MSG);
+    }
+  }
+
+  @Override
+  public Role getRoleInfo(String host, Integer port, String roleName) throws BaseException {
+    QueryWrapper<Role> wrapper = new QueryWrapper<>();
+    wrapper.eq("host", host);
+    wrapper.eq("port", port);
+    wrapper.eq("name", roleName);
+    try {
+      Role role = roleMapper.selectOne(wrapper);
+      return role;
+    } catch (Exception e) {
+      log.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_ROLE_INFO_FAIL, ErrorCode.GET_ROLE_INFO_FAIL_MSG);
+    }
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/tool/ExportCsv.java b/backend/src/main/java/org/apache/iotdb/admin/tool/ExportCsv.java
new file mode 100644
index 0000000..a31431f
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/tool/ExportCsv.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.tool;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.config.FileProperties;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.RpcUtils;
+import org.apache.iotdb.rpc.StatementExecutionException;
+import org.apache.iotdb.session.Session;
+import org.apache.iotdb.session.SessionDataSet;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.common.Field;
+import org.apache.iotdb.tsfile.read.common.RowRecord;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Slf4j
+@Component
+public class ExportCsv {
+
+  private final Path fileStorageLocation;
+
+  @Autowired
+  public ExportCsv(FileProperties fileProperties) {
+    this.fileStorageLocation = Paths.get(fileProperties.getTempDir()).toAbsolutePath().normalize();
+  }
+
+  private static final String TARGET_FILE = "dump";
+
+  public String exportCsv(
+      String host, Integer port, String username, String password, String sql, String timeZone)
+      throws BaseException {
+    Session session = null;
+    try {
+      session = new Session(host, port, username, password);
+      session.open(false);
+
+      if (timeZone != null) {
+        session.setTimeZone(timeZone);
+      }
+      ZoneId zoneId = ZoneId.of(session.getTimeZone());
+
+      return dumpResult(sql, session, zoneId);
+    } catch (IoTDBConnectionException e) {
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      throw new BaseException(
+          ErrorCode.IMPORT_CSV_FAIL, ErrorCode.IMPORT_CSV_FAIL_MSG + e.getMessage());
+    } finally {
+      if (session != null) {
+        try {
+          session.close();
+        } catch (IoTDBConnectionException e) {
+          throw new BaseException(ErrorCode.CLOSE_DBCONN_FAIL, ErrorCode.CLOSE_DBCONN_FAIL_MSG);
+        }
+      }
+    }
+  }
+
+  private String dumpResult(String sql, Session session, ZoneId zoneId) throws BaseException {
+    final String fileName = TARGET_FILE + System.currentTimeMillis() + ".csv";
+    final String path = fileStorageLocation.resolve(fileName).toString();
+    File tf = new File(path);
+    try {
+      if (!tf.exists() && !tf.createNewFile()) {
+        throw new BaseException(ErrorCode.CREATE_FILE_FAIL, ErrorCode.CREATE_FILE_FAIL_MSG);
+      }
+    } catch (IOException | BaseException e) {
+      throw new BaseException(ErrorCode.CREATE_FILE_FAIL, ErrorCode.CREATE_FILE_FAIL_MSG);
+    }
+    log.info("Start exporting data from SQL statement:" + sql);
+    try (BufferedWriter bw = new BufferedWriter(new FileWriter(tf))) {
+      SessionDataSet sessionDataSet = session.executeQueryStatement(sql);
+      long startTime = System.currentTimeMillis();
+      // write data in csv file
+      List<String> columnNames = sessionDataSet.getColumnNames();
+      writeMetadata(bw, columnNames);
+      boolean isDataType = false;
+      if ("Time".equals(columnNames.get(0))) {
+        isDataType = true;
+      }
+      int line = writeResultSet(sessionDataSet, bw, zoneId, isDataType);
+      String runTime = System.currentTimeMillis() - startTime + "ms";
+      log.info("Export " + line + " line data from SQL:" + sql + ". Time consuming:" + runTime);
+      return fileName;
+    } catch (IoTDBConnectionException e) {
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (IOException e) {
+      throw new BaseException(ErrorCode.FILE_IO_FAIL, ErrorCode.FILE_IO_FAIL_MSG + e.getMessage());
+    } catch (StatementExecutionException e) {
+      throw new BaseException(
+          ErrorCode.EXPORT_CSV_FAIL, ErrorCode.EXPORT_CSV_FAIL_MSG + e.getMessage());
+    }
+  }
+
+  private void writeMetadata(BufferedWriter bw, List<String> columnNames) throws IOException {
+    for (int i = 0; i < columnNames.size() - 1; i++) {
+      bw.write(columnNames.get(i) + ",");
+    }
+    bw.write(columnNames.get(columnNames.size() - 1) + "\n");
+  }
+
+  private int writeResultSet(
+      SessionDataSet rs, BufferedWriter bw, ZoneId zoneId, boolean isDataType)
+      throws IOException, StatementExecutionException, IoTDBConnectionException {
+    int line = 0;
+    if (isDataType) {
+      while (rs.hasNext()) {
+        RowRecord rowRecord = rs.next();
+        List<Field> fields = rowRecord.getFields();
+        writeTime(rowRecord.getTimestamp(), bw, zoneId);
+        writeValue(fields, bw);
+        line++;
+      }
+    } else {
+      while (rs.hasNext()) {
+        RowRecord rowRecord = rs.next();
+        List<Field> fields = rowRecord.getFields();
+        writeValue(fields, bw);
+        line++;
+      }
+    }
+    return line;
+  }
+
+  private void writeTime(Long time, BufferedWriter bw, ZoneId zoneId) throws IOException {
+    ZonedDateTime dateTime;
+    String timestampPrecision = "ms";
+    String str =
+        RpcUtils.parseLongToDateWithPrecision(
+            DateTimeFormatter.ISO_OFFSET_DATE_TIME, time, zoneId, timestampPrecision);
+    bw.write(str + ",");
+  }
+
+  @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
+  private void writeValue(List<Field> fields, BufferedWriter bw) throws IOException {
+    for (int j = 0; j < fields.size() - 1; j++) {
+      String value = fields.get(j).getStringValue();
+      if ("null".equalsIgnoreCase(value)) {
+        bw.write(",");
+      } else {
+        if (fields.get(j).getDataType() == TSDataType.TEXT) {
+          int location = value.indexOf("\"");
+          if (location > -1) {
+            if (location == 0 || value.charAt(location - 1) != '\\') {
+              bw.write("\"" + value.replace("\"", "\\\"") + "\",");
+            } else {
+              bw.write("\"" + value + "\",");
+            }
+          } else if (value.contains(",")) {
+            bw.write("\"" + value + "\",");
+          } else {
+            bw.write(value + ",");
+          }
+        } else {
+          bw.write(value + ",");
+        }
+      }
+    }
+    String lastValue = fields.get(fields.size() - 1).getStringValue();
+    if ("null".equalsIgnoreCase(lastValue)) {
+      bw.write("\n");
+    } else {
+      if (fields.get(fields.size() - 1).getDataType() == TSDataType.TEXT) {
+        int location = lastValue.indexOf("\"");
+        if (location > -1) {
+          if (location == 0 || lastValue.charAt(location - 1) != '\\') {
+            bw.write("\"" + lastValue.replace("\"", "\\\"") + "\"\n");
+          } else {
+            bw.write("\"" + lastValue + "\"\n");
+          }
+        } else if (lastValue.contains(",")) {
+          bw.write("\"" + lastValue + "\"\n");
+        } else {
+          bw.write(lastValue + "\n");
+        }
+      } else {
+        bw.write(lastValue + "\n");
+      }
+    }
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/tool/ImportCsv.java b/backend/src/main/java/org/apache/iotdb/admin/tool/ImportCsv.java
new file mode 100644
index 0000000..368e49e
--- /dev/null
+++ b/backend/src/main/java/org/apache/iotdb/admin/tool/ImportCsv.java
@@ -0,0 +1,388 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.admin.tool;
+
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+import org.apache.iotdb.admin.config.FileProperties;
+import org.apache.iotdb.admin.model.vo.ImportDataVO;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.StatementExecutionException;
+import org.apache.iotdb.session.Session;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Slf4j
+@Component
+public class ImportCsv {
+
+  private static final String[] STRING_TIME_FORMAT =
+      new String[] {
+        "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
+        "yyyy/MM/dd HH:mm:ss.SSS",
+        "yyyy-MM-dd HH:mm:ss.SSS",
+        "yyyy.MM.dd HH:mm:ss.SSS",
+        "yyyy/MM/dd'T'HH:mm:ss.SSS",
+        "yyyy-MM-dd'T'HH:mm:ss.SSS",
+        "yyyy-MM-dd'T'HH:mm:ss.SSS",
+        "yyyy.MM.dd'T'HH:mm:ss.SSS",
+        "yyyy-MM-dd HH:mm:ss.SSSZZ",
+        "yyyy/MM/dd HH:mm:ss.SSSZZ",
+        "yyyy.MM.dd HH:mm:ss.SSSZZ",
+        "yyyy-MM-dd'T'HH:mm:ss.SSSZZ",
+        "yyyy/MM/dd'T'HH:mm:ss.SSSZZ",
+        "yyyy-MM-dd HH:mm:ss",
+        "yyyy/MM/dd HH:mm:ss",
+        "yyyy.MM.dd HH:mm:ss",
+        "yyyy-MM-dd'T'HH:mm:ss",
+        "yyyy/MM/dd'T'HH:mm:ss",
+        "yyyy.MM.dd'T'HH:mm:ss",
+        "yyyy-MM-dd HH:mm:ssZZ",
+        "yyyy/MM/dd HH:mm:ssZZ",
+        "yyyy.MM.dd HH:mm:ssZZ",
+        "yyyy-MM-dd'T'HH:mm:ssZZ",
+        "yyyy/MM/dd'T'HH:mm:ssZZ",
+        "yyyy.MM.dd'T'HH:mm:ssZZ",
+      };
+
+  private final Path fileStorageLocation;
+
+  @Autowired
+  public ImportCsv(FileProperties fileProperties) {
+    this.fileStorageLocation = Paths.get(fileProperties.getTempDir()).toAbsolutePath().normalize();
+  }
+
+  public ImportDataVO importCsv(
+      String host, Integer port, String username, String password, String filename, String timeZone)
+      throws BaseException {
+    Session session = null;
+    try {
+      session = new Session(host, port, username, password, false);
+      session.open(false);
+      if (timeZone != null) {
+        session.setTimeZone(timeZone);
+      }
+
+      File file = new File(filename);
+      if (file.isFile()) {
+        return loadDataFromCSV(file, session);
+      } else {
+        throw new BaseException(ErrorCode.UPLOAD_FILE_FAIL, ErrorCode.UPLOAD_FILE_FAIL_MSG);
+      }
+    } catch (IoTDBConnectionException e) {
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      throw new BaseException(
+          ErrorCode.IMPORT_CSV_FAIL, ErrorCode.IMPORT_CSV_FAIL_MSG + e.getMessage());
+    } finally {
+      if (session != null) {
+        try {
+          session.close();
+        } catch (IoTDBConnectionException e) {
+          throw new BaseException(ErrorCode.CLOSE_DBCONN_FAIL, ErrorCode.CLOSE_DBCONN_FAIL_MSG);
+        }
+      }
+    }
+  }
+
+  @SuppressWarnings("squid:S1135")
+  private ImportDataVO loadDataFromCSV(File file, Session session) throws BaseException {
+    log.info("Start import data from file:" + file.getName());
+    String errorFileName = "error" + System.currentTimeMillis() + ".txt";
+    File errorFile = new File(this.fileStorageLocation.resolve(errorFileName).toString());
+
+    try (BufferedReader br =
+            new BufferedReader(
+                new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
+        BufferedWriter bw = new BufferedWriter(new FileWriter(errorFile))) {
+      String header = br.readLine();
+      String[] cols = splitCsvLine(header);
+      if (cols.length <= 1) {
+        throw new BaseException(
+            ErrorCode.FILE_FIRST_LINE_ILLEGAL, ErrorCode.FILE_FIRST_LINE_ILLEGAL_MSG);
+      }
+      for (int i = 1; i < cols.length; i++) {
+        if (!cols[i].startsWith("root.") || StringUtils.countMatches(cols[i], ".") < 2) {
+          throw new BaseException(
+              ErrorCode.FILE_FIRST_LINE_ILLEGAL, ErrorCode.FILE_FIRST_LINE_ILLEGAL_MSG);
+        }
+      }
+
+      List<String> devices = new ArrayList<>();
+      List<Long> times = new ArrayList<>();
+      List<List<String>> measurementsList = new ArrayList<>();
+      List<List<String>> valuesList = new ArrayList<>();
+      Map<String, List<Integer>> devicesToPositions = new HashMap<>();
+      Map<String, List<String>> devicesToMeasurements = new HashMap<>();
+
+      for (int i = 1; i < cols.length; i++) {
+        splitColToDeviceAndMeasurement(cols[i], devicesToPositions, devicesToMeasurements, i);
+      }
+
+      SimpleDateFormat timeFormatter = null;
+      boolean useFormatter = false;
+
+      int lineNumber = 0;
+      List<String> insertErrorInfo = new ArrayList<>();
+      String line;
+      while ((line = br.readLine()) != null) {
+        cols = splitCsvLine(line);
+        lineNumber++;
+        if (lineNumber == 1) {
+          timeFormatter = formatterInit(cols[0]);
+          useFormatter = (timeFormatter != null);
+        }
+        for (Map.Entry<String, List<Integer>> deviceToPositions : devicesToPositions.entrySet()) {
+          List<String> values = new ArrayList<>();
+          for (int position : deviceToPositions.getValue()) {
+            values.add(cols[position]);
+          }
+          boolean isAllBlank = true;
+          for (String value : values) {
+            if (value != null && !"".equals(value)) {
+              isAllBlank = false;
+              break;
+            }
+          }
+          if (isAllBlank) {
+            continue;
+          }
+          valuesList.add(values);
+
+          String device = deviceToPositions.getKey();
+          devices.add(device);
+
+          times.add(parseTime(cols[0], useFormatter, timeFormatter));
+
+          measurementsList.add(devicesToMeasurements.get(device));
+        }
+        if (lineNumber % 10000 == 0) {
+          try {
+            session.insertRecords(devices, times, measurementsList, valuesList);
+          } catch (StatementExecutionException e) {
+            if (e.getMessage().contains("failed to insert measurements")) {
+              insertErrorInfo.addAll(
+                  Arrays.asList(
+                      StringUtils.splitByWholeSeparator(
+                          e.getMessage(),
+                          "org.apache.iotdb.db.exception.StorageEngineException: ")));
+            } else {
+              throw new BaseException(
+                  ErrorCode.IMPORT_CSV_FAIL, ErrorCode.IMPORT_CSV_FAIL_MSG + e.getMessage());
+            }
+          } catch (IoTDBConnectionException e) {
+            throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+          }
+          devices = new ArrayList<>();
+          times = new ArrayList<>();
+          measurementsList = new ArrayList<>();
+          valuesList = new ArrayList<>();
+        }
+      }
+      try {
+        if (lineNumber % 10000 != 0) {
+          session.insertRecords(devices, times, measurementsList, valuesList);
+        }
+      } catch (StatementExecutionException e) {
+        if (e.getMessage().contains("failed to insert measurements")) {
+          insertErrorInfo.addAll(
+              Arrays.asList(
+                  StringUtils.splitByWholeSeparator(
+                      e.getMessage(), "org.apache.iotdb.db.exception.StorageEngineException: ")));
+        } else {
+          throw new BaseException(
+              ErrorCode.IMPORT_CSV_FAIL, ErrorCode.IMPORT_CSV_FAIL_MSG + e.getMessage());
+        }
+      } catch (IoTDBConnectionException e) {
+        throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+      }
+
+      for (String s : insertErrorInfo) {
+        bw.write(s + "\n");
+      }
+      int errorCount = insertErrorInfo.size();
+      String fileDownloadUri = null;
+      if (errorCount > 0) {
+        fileDownloadUri = "/downloadFile/" + errorFileName;
+      }
+      Integer totalCount = lineNumber * (cols.length - 1);
+      return new ImportDataVO(totalCount, errorCount, fileDownloadUri);
+    } catch (FileNotFoundException e) {
+      throw new BaseException(ErrorCode.UPLOAD_FILE_FAIL, ErrorCode.UPLOAD_FILE_FAIL_MSG);
+    } catch (IOException e) {
+      throw new BaseException(ErrorCode.FILE_IO_FAIL, ErrorCode.FILE_IO_FAIL_MSG + e.getMessage());
+    } catch (ArrayIndexOutOfBoundsException e) {
+      throw new BaseException(ErrorCode.FILE_FORMAT_ILLEGAL, ErrorCode.FILE_FORMAT_ILLEGAL_MSG);
+    }
+  }
+
+  private long parseTime(String str, boolean useFormatter, SimpleDateFormat timeFormatter)
+      throws BaseException {
+    try {
+      if (useFormatter) {
+        return timeFormatter.parse(str).getTime();
+      } else {
+        return Long.parseLong(str);
+      }
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.FILE_TIME_ILLEGAL, ErrorCode.FILE_TIME_ILLEGAL_MSG);
+    }
+  }
+
+  private SimpleDateFormat formatterInit(String time) {
+
+    try {
+      Long.parseLong(time);
+      return null;
+    } catch (Exception ignored) {
+      // do nothing
+    }
+
+    for (String timeFormat : STRING_TIME_FORMAT) {
+      SimpleDateFormat format = new SimpleDateFormat(timeFormat);
+      try {
+        format.parse(time).getTime();
+        return format;
+      } catch (java.text.ParseException ignored) {
+        // do nothing
+      }
+    }
+    return null;
+  }
+
+  private void splitColToDeviceAndMeasurement(
+      String col,
+      Map<String, List<Integer>> devicesToPositions,
+      Map<String, List<String>> devicesToMeasurements,
+      int position)
+      throws BaseException {
+    if (col.length() > 0) {
+      if (col.charAt(col.length() - 1) == TsFileConstant.DOUBLE_QUOTE) {
+        int endIndex = col.lastIndexOf('"', col.length() - 2);
+        // if a double quotes with escape character
+        while (endIndex != -1 && col.charAt(endIndex - 1) == '\\') {
+          endIndex = col.lastIndexOf('"', endIndex - 2);
+        }
+        if (endIndex != -1 && (endIndex == 0 || col.charAt(endIndex - 1) == '.')) {
+          putDeviceAndMeasurement(
+              col.substring(0, endIndex - 1),
+              col.substring(endIndex),
+              devicesToPositions,
+              devicesToMeasurements,
+              position);
+        } else {
+          throw new BaseException(
+              ErrorCode.FILE_FIRST_LINE_ILLEGAL, ErrorCode.FILE_FIRST_LINE_ILLEGAL_MSG);
+        }
+      } else if (col.charAt(col.length() - 1) != TsFileConstant.DOUBLE_QUOTE
+          && col.charAt(col.length() - 1) != TsFileConstant.PATH_SEPARATOR_CHAR) {
+        int endIndex = col.lastIndexOf(TsFileConstant.PATH_SEPARATOR_CHAR);
+        if (endIndex < 0) {
+          putDeviceAndMeasurement("", col, devicesToPositions, devicesToMeasurements, position);
+        } else {
+          putDeviceAndMeasurement(
+              col.substring(0, endIndex),
+              col.substring(endIndex + 1),
+              devicesToPositions,
+              devicesToMeasurements,
+              position);
+        }
+      } else {
+        throw new BaseException(
+            ErrorCode.FILE_FIRST_LINE_ILLEGAL, ErrorCode.FILE_FIRST_LINE_ILLEGAL_MSG);
+      }
+    } else {
+      putDeviceAndMeasurement("", col, devicesToPositions, devicesToMeasurements, position);
+    }
+  }
+
+  private void putDeviceAndMeasurement(
+      String device,
+      String measurement,
+      Map<String, List<Integer>> devicesToPositions,
+      Map<String, List<String>> devicesToMeasurements,
+      int position) {
+    if (devicesToMeasurements.get(device) == null && devicesToPositions.get(device) == null) {
+      List<String> measurements = new ArrayList<>();
+      measurements.add(measurement);
+      devicesToMeasurements.put(device, measurements);
+      List<Integer> positions = new ArrayList<>();
+      positions.add(position);
+      devicesToPositions.put(device, positions);
+    } else {
+      devicesToMeasurements.get(device).add(measurement);
+      devicesToPositions.get(device).add(position);
+    }
+  }
+
+  private String[] splitCsvLine(String path) throws BaseException {
+    List<String> nodes = new ArrayList<>();
+    int startIndex = 0;
+    for (int i = 0; i < path.length(); i++) {
+      if (path.charAt(i) == ',') {
+        nodes.add(path.substring(startIndex, i));
+        startIndex = i + 1;
+      } else if (path.charAt(i) == '"') {
+        int[] result = nextNode(path, nodes, '"', startIndex, i);
+        startIndex = result[0];
+        i = result[1];
+      } else if (path.charAt(i) == '\'') {
+        int[] result = nextNode(path, nodes, '\'', startIndex, i);
+        startIndex = result[0];
+        i = result[1];
+      }
+    }
+    if (path.charAt(path.length() - 1) == ',') {
+      nodes.add("");
+    }
+    if (startIndex <= path.length() - 1) {
+      nodes.add(path.substring(startIndex));
+    }
+    return nodes.toArray(new String[0]);
+  }
+
+  private int[] nextNode(String path, List<String> nodes, char enclose, int startIndex, int i)
+      throws BaseException {
+    int endIndex = path.indexOf(enclose, i + 1);
+    // if a double quotes with escape character
+    while (endIndex != -1 && path.charAt(endIndex - 1) == '\\') {
+      endIndex = path.indexOf(enclose, endIndex + 1);
+    }
+    if (endIndex != -1 && (endIndex == path.length() - 1 || path.charAt(endIndex + 1) == ',')) {
+      nodes.add(path.substring(startIndex + 1, endIndex));
+      i = endIndex + 1;
+      startIndex = endIndex + 2;
+      return new int[] {startIndex, i};
+    } else {
+      throw new BaseException(ErrorCode.FILE_LINE_ILLEGAL, ErrorCode.FILE_LINE_ILLEGAL_MSG + path);
+    }
+  }
+}
diff --git a/backend/src/main/resources/application-dev.properties b/backend/src/main/resources/application-dev.properties
index 4a14685..b547fb9 100644
--- a/backend/src/main/resources/application-dev.properties
+++ b/backend/src/main/resources/application-dev.properties
@@ -17,14 +17,23 @@
 # under the License.
 #
 
-# 指定日志配置文件的位置
+# Designate the log configuration file
 logging.config=classpath:log4j2.xml
 
-# 配置端口号和上下文根
+# Set port and context path
 server.port=8080
 server.servlet.context-path=/api
 
-# 指定数据源和连接驱动
-# 如下配置数据源的方式会导致项目重新打包后数据丢失,仅为了开发时方便测试,实际部署项目时请参考application-prod.properties文件配置
+# The following data source configuration method will cause data loss after the project is repackaged.
+# To facilitate testing during development, refer to the application-prod.properties file for configuration during actual project deployment
 spring.datasource.url=jdbc:sqlite::resource:sqlite/iotdb.db
-spring.datasource.driver-class-name=org.sqlite.JDBC
\ No newline at end of file
+spring.datasource.driver-class-name=org.sqlite.JDBC
+
+# Enable the multipart uploading function
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.file-size-threshold=2KB
+spring.servlet.multipart.max-file-size=200MB
+spring.servlet.multipart.max-request-size=215MB
+
+# All files generated during CSV import and export are stored in this folder
+file.temp-dir=./tempFile
\ No newline at end of file
diff --git a/backend/src/main/resources/application-prod.properties b/backend/src/main/resources/application-prod.properties
index b6b57f8..e830534 100644
--- a/backend/src/main/resources/application-prod.properties
+++ b/backend/src/main/resources/application-prod.properties
@@ -17,14 +17,19 @@
 # under the License.
 #
 
-# 指定日志配置文件的位置
 logging.config=classpath:log4j2-prod.xml
 
-# 配置端口号和上下文根
-server.port=8081
+server.port=9089
 server.servlet.context-path=/api
 
-# 指定数据源和连接驱动
-# 请将backend/src/main/resources/sqlite下的iotdb.db文件复制一份到你的服务器上,并将以下路径修改为你的iotdb.db文件路径
+# Please make a copy of the iotdb.db file in the backend/src/main/resources/sqlite folder to your server and change the path below to your iotdb.db file path
 spring.datasource.url=jdbc:sqlite:/usr/local/iotdb/data/iotdb1.db
-spring.datasource.driver-class-name=org.sqlite.JDBC
\ No newline at end of file
+spring.datasource.driver-class-name=org.sqlite.JDBC
+
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.file-size-threshold=2KB
+spring.servlet.multipart.max-file-size=200MB
+spring.servlet.multipart.max-request-size=215MB
+
+# All files generated during CSV import and export are stored in this folder
+file.temp-dir=./tempFile
\ No newline at end of file
diff --git a/backend/src/main/resources/application-test.properties b/backend/src/main/resources/application-test.properties
index 2d959b0..7cd752d 100644
--- a/backend/src/main/resources/application-test.properties
+++ b/backend/src/main/resources/application-test.properties
@@ -23,4 +23,11 @@ server.port=8079
 server.servlet.context-path=/api
 
 spring.datasource.url=jdbc:sqlite:/usr/local/iotdb/data/iotdb.db
-spring.datasource.driver-class-name=org.sqlite.JDBC
\ No newline at end of file
+spring.datasource.driver-class-name=org.sqlite.JDBC
+
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.file-size-threshold=2KB
+spring.servlet.multipart.max-file-size=200MB
+spring.servlet.multipart.max-request-size=215MB
+
+file.temp-dir=./tempFile
\ No newline at end of file
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 5aa2fca..e9e7335 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -17,5 +17,5 @@
 # under the License.
 #
 
-# 指定配置文件。dev、prod、test分别表示开发、生产、测试环境
+# Designate the configuration file
 spring.profiles.active=dev
\ No newline at end of file
diff --git a/backend/src/main/resources/banner.txt b/backend/src/main/resources/banner.txt
new file mode 100644
index 0000000..14108eb
--- /dev/null
+++ b/backend/src/main/resources/banner.txt
@@ -0,0 +1,8 @@
+ ██          ██████████ ███████   ██████         ██       ██                 ██     ██                               ██
+░██         ░░░░░██░░░ ░██░░░░██ ░█░░░░██       ░██      ░██                ░██    ░██                              ░██
+░██  ██████     ░██    ░██    ░██░█   ░██       ░██   █  ░██  ██████  ██████░██  ██░██       █████  ███████   █████ ░██
+░██ ██░░░░██    ░██    ░██    ░██░██████   █████░██  ███ ░██ ██░░░░██░░██░░█░██ ██ ░██████  ██░░░██░░██░░░██ ██░░░██░██████
+░██░██   ░██    ░██    ░██    ░██░█░░░░ ██░░░░░ ░██ ██░██░██░██   ░██ ░██ ░ ░████  ░██░░░██░███████ ░██  ░██░██  ░░ ░██░░░██
+░██░██   ░██    ░██    ░██    ██ ░█    ░██      ░████ ░░████░██   ░██ ░██   ░██░██ ░██  ░██░██░░░░  ░██  ░██░██   ██░██  ░██
+░██░░██████     ░██    ░███████  ░███████       ░██░   ░░░██░░██████ ░███   ░██░░██░██████ ░░██████ ███  ░██░░█████ ░██  ░██
+░░  ░░░░░░      ░░     ░░░░░░░   ░░░░░░░        ░░       ░░  ░░░░░░  ░░░    ░░  ░░ ░░░░░    ░░░░░░ ░░░   ░░  ░░░░░  ░░   ░░
diff --git a/backend/src/main/resources/file/template.csv b/backend/src/main/resources/file/template.csv
new file mode 100644
index 0000000..19f0233
--- /dev/null
+++ b/backend/src/main/resources/file/template.csv
@@ -0,0 +1,34 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+Time,root.group1.dev.s1,root.group1.dev.s2,root.group2.dev.s
+1,100,150,300
+3,200,300,320
+10,300,,400
+(Before importing data from this file, delete the license comments and the following contents.)
+CSV file format:
+    The file is split with ",", and the first column is "Time" on the first line, followed by the measurement name.
+    The first column from the second row is the timestamp, followed by the imported data.
+    If you do not need to import data for certain measurement at certain timestamps, do not enter them. Refer to line 4 of this file.
+    The timestamp format can be number, yyyy-MM-dd'T'HH:mm:ss, yyyy-MM-dd HH:mm:ss, yyyy-MM-dd'T'HH:mm:ss.SSS and so on.
+    The timestamp format and column number of each row must be the same.
+    Note:fields containing , should be escaped by \.
+You can use the export CSV tool to export data to get more templates.
\ No newline at end of file
diff --git a/backend/src/main/resources/log4j2-prod.xml b/backend/src/main/resources/log4j2-prod.xml
index 3a0f519..9bea303 100644
--- a/backend/src/main/resources/log4j2-prod.xml
+++ b/backend/src/main/resources/log4j2-prod.xml
@@ -21,7 +21,6 @@
 <configuration status="ERROR">
 
     <Properties>
-        <!--应用名-->
         <property name="app">IoTDB-Workbench</property>
         <property name="log.root.level">INFO</property>
         <property name="log.home">/data/applogs/app-prod</property>
@@ -101,7 +100,7 @@
     </appenders>
 
     <loggers>
-        <!--level日志级别: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
+        <!--level: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
         <Root level="${log.root.level}">
             <AppenderRef ref="STDOUT"/>
             <AppenderRef ref="ROLLING_INFO"/>
diff --git a/backend/src/main/resources/log4j2.xml b/backend/src/main/resources/log4j2.xml
index 21772ee..c4660f6 100644
--- a/backend/src/main/resources/log4j2.xml
+++ b/backend/src/main/resources/log4j2.xml
@@ -21,7 +21,6 @@
 <configuration status="ERROR">
 
     <Properties>
-        <!--应用名-->
         <property name="app">IoTDB-Workbench</property>
         <property name="log.root.level">INFO</property>
         <property name="log.home">/data/applogs/app-test</property>
@@ -101,7 +100,7 @@
     </appenders>
 
     <loggers>
-        <!--level日志级别: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
+        <!--level: ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF -->
         <Root level="${log.root.level}">
             <AppenderRef ref="STDOUT"/>
             <AppenderRef ref="ROLLING_INFO"/>
diff --git a/backend/src/main/resources/sqlite/iotdb.db b/backend/src/main/resources/sqlite/iotdb.db
index 5a23664..9700849 100644
Binary files a/backend/src/main/resources/sqlite/iotdb.db and b/backend/src/main/resources/sqlite/iotdb.db differ
diff --git a/backend/src/test/java/org/apache/iotdb/admin/DemoJDBC.java b/backend/src/test/java/org/apache/iotdb/admin/DemoJDBC.java
deleted file mode 100644
index 882ff68..0000000
--- a/backend/src/test/java/org/apache/iotdb/admin/DemoJDBC.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.iotdb.admin;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-/**
- * ${DESCRIPTION}
- *
- * @author fanli
- */
-@RunWith(SpringRunner.class)
-@SpringBootTest
-public class DemoJDBC {
-
-  @Test
-  public void testSelect() {}
-}
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
index adb49fa..cd9d2e8 100644
--- a/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
@@ -38,7 +38,6 @@ import java.util.Calendar;
 
 @SpringBootTest
 class ConnectionControllerTest {
-
   private MockMvc mvc;
 
   @Autowired private WebApplicationContext wac;
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java
index adb51de..2686573 100644
--- a/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/IotDBControllerTest.java
@@ -40,7 +40,6 @@ import java.util.Calendar;
 @SpringBootTest
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 class IotDBControllerTest {
-
   private MockMvc mvc;
   @Autowired private WebApplicationContext wac;
 
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java
index f392b35..7b1ba85 100644
--- a/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/QueryControllerTest.java
@@ -36,8 +36,6 @@ import org.springframework.web.context.WebApplicationContext;
 import java.net.InetAddress;
 import java.util.Calendar;
 
-import static org.junit.jupiter.api.Assertions.*;
-
 @SpringBootTest
 class QueryControllerTest {
 
diff --git a/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java b/backend/src/test/java/org/apache/iotdb/admin/controller/UserControllerTest.java
similarity index 59%
copy from backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
copy to backend/src/test/java/org/apache/iotdb/admin/controller/UserControllerTest.java
index adb49fa..574aa0c 100644
--- a/backend/src/test/java/org/apache/iotdb/admin/controller/ConnectionControllerTest.java
+++ b/backend/src/test/java/org/apache/iotdb/admin/controller/UserControllerTest.java
@@ -24,20 +24,18 @@ import com.auth0.jwt.algorithms.Algorithm;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.annotation.Rollback;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.RequestBuilder;
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.context.WebApplicationContext;
 
 import java.net.InetAddress;
 import java.util.Calendar;
 
 @SpringBootTest
-class ConnectionControllerTest {
+class UserControllerTest {
 
   private MockMvc mvc;
 
@@ -45,57 +43,23 @@ class ConnectionControllerTest {
 
   private String token = getToken();
 
-  @Transactional
-  @Rollback
   @Test
-  void saveOrUpdateConnection() throws Exception {
+  void login() throws Exception {
     mvc = MockMvcBuilders.webAppContextSetup(wac).build();
     RequestBuilder request =
-        MockMvcRequestBuilders.post("http://127.0.0.1:8080/api/servers")
-            .contextPath("/api")
-            .content(
-                "{\n"
-                    + "  \"alias\": \"tttt\",\n"
-                    + "  \"host\": \"localhost\",\n"
-                    + "  \"password\": \"root\",\n"
-                    + "  \"port\": 6667,\n"
-                    + "  \"userId\": 1,\n"
-                    + "  \"username\": \"root\"\n"
-                    + "}")
-            .header("Authorization", token)
-            .header("Content-Type", "application/json");
-    mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
-  }
-
-  @Transactional
-  @Rollback
-  @Test
-  void deleteConnection() throws Exception {
-    mvc = MockMvcBuilders.webAppContextSetup(wac).build();
-    RequestBuilder request =
-        MockMvcRequestBuilders.delete("http://127.0.0.1:8080/api/servers/1")
-            .contextPath("/api")
-            .header("Authorization", token);
-    mvc.perform(request).andExpect(MockMvcResultMatchers.status().isOk());
-  }
... 16287 lines suppressed ...


[iotdb-web-workbench] 30/34: hotfix:add the licenses

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 29a70910a87b2adfa4c4f992904b8e5340baf381
Author: ljn <>
AuthorDate: Wed Jun 1 11:07:47 2022 +0800

    hotfix:add the licenses
---
 .../iotdb/admin/controller/MetricsController.java  |  4 ----
 .../apache/iotdb/admin/mapper/ViewModeMapper.java  | 23 ++++++++++++++++++----
 .../iotdb/admin/model/dto/DataModelDetailDTO.java  | 18 +++++++++++++++++
 .../apache/iotdb/admin/model/dto/QueryInfoDTO.java | 23 ++++++++++++++++++----
 .../apache/iotdb/admin/model/entity/ViewMode.java  | 22 +++++++++++++++++----
 .../iotdb/admin/model/metricsDo/QueryDataDo.java   | 22 +++++++++++++++++----
 .../org/apache/iotdb/admin/model/vo/GroupInfo.java | 18 +++++++++++++++++
 .../iotdb/admin/model/vo/JVMMetricsListDataVO.java | 22 +++++++++++++++++----
 .../model/vo/MetircsQueryClassificationVO.java     | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/MetricsChartDataVO.java   | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/MetricsConnectionVO.java  | 23 ++++++++++++++++++----
 .../iotdb/admin/model/vo/MetricsDataCountVO.java   | 22 +++++++++++++++++----
 .../admin/model/vo/MetricsDataForDiagramVO.java    | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/MetricsDataForListVO.java | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/MetricsListDataVO.java    | 23 ++++++++++++++++++----
 .../admin/model/vo/QueryClassificationVO.java      | 23 ++++++++++++++++++----
 .../apache/iotdb/admin/model/vo/QueryData1VO.java  | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/QueryDataForListVO.java   | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/QueryDataStrVO.java       | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/QueryDataStrVO1.java      | 22 +++++++++++++++++----
 .../apache/iotdb/admin/model/vo/QueryDataVO.java   | 22 +++++++++++++++++----
 .../apache/iotdb/admin/model/vo/QueryInfoVO.java   | 22 +++++++++++++++++----
 .../iotdb/admin/model/vo/QueryMetricsVO.java       | 22 +++++++++++++++++----
 .../iotdb/admin/service/MetricsResultService.java  | 22 +++++++++++++++++----
 .../apache/iotdb/admin/service/MetricsService.java | 22 +++++++++++++++++----
 .../service/impl/MetricsResultServiceImpl.java     | 22 +++++++++++++++++----
 .../admin/service/impl/MetricsServiceImpl.java     | 22 +++++++++++++++++----
 27 files changed, 473 insertions(+), 100 deletions(-)

diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java
index 5c5a968..30fda57 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/MetricsController.java
@@ -38,10 +38,6 @@ import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-22-上午 9:55
- */
 @RestController
 @Api(value = "metrics related")
 public class MetricsController {
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java
index 66f9ea3..dd3bc58 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/ViewModeMapper.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.mapper;
 
 import org.apache.iotdb.admin.model.entity.ViewMode;
@@ -5,9 +23,6 @@ import org.apache.iotdb.admin.model.entity.ViewMode;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
-/**
- * @author Erickin
- * @create 2022-04-22-上午 10:32
- */
+
 @Component
 public interface ViewModeMapper extends BaseMapper<ViewMode> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
index 58463b0..e60abea 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.dto;
 
 import org.apache.iotdb.admin.model.vo.DataModelVO;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java
index 7f3210b..e69ad38 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryInfoDTO.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.dto;
 
 import org.apache.iotdb.admin.model.vo.QueryDataStrVO;
@@ -6,10 +24,7 @@ import lombok.Data;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-25-下午 5:12
- */
+
 @Data
 public class QueryInfoDTO {
   private Long latestRunningTime;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java
index 56c9ae6..bc0b450 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/ViewMode.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
@@ -11,10 +29,6 @@ import javax.validation.constraints.Pattern;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-22-上午 10:35
- */
 @Data
 @TableName("view_mode")
 public class ViewMode implements Serializable {
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java b/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java
index 2be1e09..81e8bde 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/metricsDo/QueryDataDo.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.metricsDo;
 
 import org.apache.iotdb.admin.model.vo.QueryDataVO;
@@ -6,10 +24,6 @@ import lombok.Data;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-上午 9:28
- */
 @Data
 public class QueryDataDo {
   private List<QueryDataVO> QueryDataVOs;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java
index 62e3cb2..f95fd50 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfo.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.AllArgsConstructor;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java
index 3661555..146635d 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/JVMMetricsListDataVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 5:26
- */
 @Data
 public class JVMMetricsListDataVO extends MetricsListDataVO implements Serializable {
   private String metricType;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java
index 851c833..26a2bed 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetircsQueryClassificationVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-25-上午 10:00
- */
 @Data
 public class MetircsQueryClassificationVO {
   private Integer serverId;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java
index 9bfa81f..f211b54 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsChartDataVO.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
@@ -6,10 +24,6 @@ import java.io.Serializable;
 import java.util.HashMap;
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-上午 10:15
- */
 @Data
 public class MetricsChartDataVO implements Serializable {
   private List<String> timeList;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java
index 8045fdb..e433ff9 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsConnectionVO.java
@@ -1,13 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-25-上午 9:12
- */
+
 @Data
 public class MetricsConnectionVO implements Serializable {
   Integer id;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java
index 82f6337..9849648 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataCountVO.java
@@ -1,11 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
-/**
- * @author Erickin
- * @create 2022-04-25-上午 9:38
- */
 @Data
 public class MetricsDataCountVO {
   private Integer serverId;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java
index 08135e3..0a27d00 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForDiagramVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-26-上午 10:12
- */
 @Data
 public class MetricsDataForDiagramVO implements Serializable {
   private Integer serverId;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java
index 269cde1..7a763fb 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsDataForListVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 8:12
- */
 @Data
 public class MetricsDataForListVO {
   private Integer serverId;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java
index 7bde7ca..bb62171 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MetricsListDataVO.java
@@ -1,13 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 5:24
- */
+
 @Data
 public class MetricsListDataVO implements Serializable {
   private String name;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java
index 17993c0..1864a0a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryClassificationVO.java
@@ -1,11 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
-/**
- * @author Erickin
- * @create 2022-04-25-上午 10:02
- */
+
 @Data
 public class QueryClassificationVO {
   private Integer id;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java
index b14e3c4..1e5102c 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryData1VO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-25-下午 3:56
- */
 @Data
 public class QueryData1VO extends QueryDataVO implements Serializable {
   private Integer precompiledTime;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java
index b200a0d..1f86fc3 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataForListVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 9:22
- */
 @Data
 public class QueryDataForListVO {
   private Integer serverId;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java
index 5aecf44..f9511b4 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-28-下午 10:02
- */
 @Data
 public class QueryDataStrVO implements Serializable {
   private Integer id;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java
index a14537a..b74408e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataStrVO1.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-29-下午 2:10
- */
 @Data
 public class QueryDataStrVO1 extends QueryDataStrVO implements Serializable {
   private Integer precompiledTime;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java
index 081be81..ca62db3 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryDataVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * @author Erickin
- * @create 2022-04-25-下午 8:36
- */
 @Data
 public class QueryDataVO implements Serializable {
   private Integer id;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java
index e2b3529..007f9aa 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryInfoVO.java
@@ -1,13 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-25-下午 5:13
- */
 @Data
 public class QueryInfoVO {
   private Integer queryClassificationId;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java
index cdf3e12..fba6a4f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryMetricsVO.java
@@ -1,11 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 9:20
- */
 @Data
 public class QueryMetricsVO {
   private String SQLStatement;
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java
index 1180f23..811c8ec 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsResultService.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.service;
 
 import org.apache.iotdb.admin.common.exception.BaseException;
@@ -6,10 +24,6 @@ import org.apache.iotdb.admin.model.vo.MetricsListDataVO;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 4:07
- */
 public interface MetricsResultService {
   List<MetricsListDataVO> getJVMMetricsDataList(Connection connection) throws BaseException;
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java
index 50f8663..0acd5b7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MetricsService.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.service;
 
 import org.apache.iotdb.admin.common.exception.BaseException;
@@ -6,10 +24,6 @@ import org.apache.iotdb.admin.model.vo.*;
 
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 4:07
- */
 public interface MetricsService {
   List<MetricsListDataVO> getJVMMetricsDataList(Connection connection) throws BaseException;
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java
index de26ba5..4137090 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsResultServiceImpl.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.service.impl;
 
 import org.apache.iotdb.admin.common.exception.BaseException;
@@ -12,10 +30,6 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 4:41
- */
 @Service
 public class MetricsResultServiceImpl implements MetricsResultService {
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java
index 5dd025d..47ef9cb 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MetricsServiceImpl.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.iotdb.admin.service.impl;
 
 import org.apache.iotdb.admin.common.exception.BaseException;
@@ -27,10 +45,6 @@ import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * @author Erickin
- * @create 2022-04-26-下午 4:41
- */
 @Service
 public class MetricsServiceImpl implements MetricsService {
 


[iotdb-web-workbench] 04/34: fix(docs)vue文件Apache注释格式化

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit a046c4521739b00ce23b9fb4e41bffb56cec61e3
Author: huangrui <hu...@163.com>
AuthorDate: Thu Sep 9 17:20:13 2021 +0800

    fix(docs)vue文件Apache注释格式化
---
 frontend/README.md                                 | 25 +++++++++++++++++++---
 frontend/public/index.html                         | 19 ++++++++++++++++
 frontend/src/App.vue                               | 22 +++++++++++++++----
 frontend/src/components/Echarts.vue                | 22 +++++++++++++++----
 frontend/src/components/FormTable.vue              | 22 +++++++++++++++----
 frontend/src/components/HelloWorld.vue             | 22 +++++++++++++++----
 frontend/src/components/StandTable.vue             | 22 +++++++++++++++----
 frontend/src/views/About/index.vue                 | 22 +++++++++++++++----
 .../views/DataBaseM/components/dataListTree.vue    | 22 +++++++++++++++----
 .../src/views/DataBaseM/components/iconTypes.vue   | 22 +++++++++++++++----
 frontend/src/views/DataBaseM/index.vue             | 22 +++++++++++++++----
 frontend/src/views/Device/index.vue                | 22 +++++++++++++++----
 .../src/views/DeviceMessage/components/action.vue  | 22 +++++++++++++++----
 frontend/src/views/DeviceMessage/index.vue         | 22 +++++++++++++++----
 frontend/src/views/Home.vue                        | 22 +++++++++++++++----
 frontend/src/views/Login/index.vue                 | 22 +++++++++++++++----
 frontend/src/views/Root/index.vue                  | 22 +++++++++++++++----
 frontend/src/views/Source/components/empty.vue     | 22 +++++++++++++++----
 frontend/src/views/Source/components/newSource.vue | 22 +++++++++++++++----
 frontend/src/views/Source/index.vue                | 22 +++++++++++++++----
 .../src/views/SqlSerch/components/codemirror.vue   | 22 +++++++++++++++----
 .../src/views/SqlSerch/components/eltooltip.vue    | 22 +++++++++++++++----
 .../src/views/SqlSerch/components/formserch.vue    | 22 +++++++++++++++----
 .../views/SqlSerch/components/formserchData.vue    | 22 +++++++++++++++----
 .../src/views/SqlSerch/components/sqlDrawer.vue    | 22 +++++++++++++++----
 frontend/src/views/SqlSerch/index.vue              | 22 +++++++++++++++----
 frontend/src/views/storage/index.vue               | 22 +++++++++++++++----
 frontend/src/views/storage/newStorage.vue          | 22 +++++++++++++++----
 28 files changed, 509 insertions(+), 107 deletions(-)

diff --git a/frontend/README.md b/frontend/README.md
index b3c6978..260c866 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -1,3 +1,22 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
 # iotdb-fe
 
 ## 开发环境
@@ -5,8 +24,8 @@
 目前支持的开发环境如下:
 
 - node 10.0.0 及以上
-- npm 6.0.0及以上
-- 推荐使用visual studio code
+- npm 6.0.0 及以上
+- 推荐使用 visual studio code
 
 ## 安装依赖
 
@@ -80,4 +99,4 @@ src 源码目录
 
 #### git commit 规范
 
-原则上基于 `<type>(<scope>): <subject>` 格式提交代码,详见https://zhuanlan.zhihu.com/p/182553920
\ No newline at end of file
+原则上基于 `<type>(<scope>): <subject>` 格式提交代码,详见https://zhuanlan.zhihu.com/p/182553920
diff --git a/frontend/public/index.html b/frontend/public/index.html
index 81ad929..bfb0338 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -1,3 +1,22 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
 <!DOCTYPE html>
 <html lang="">
   <head>
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index bd6b8d3..a5ba243 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
   <router-view />
diff --git a/frontend/src/components/Echarts.vue b/frontend/src/components/Echarts.vue
index d6ab738..f9855b6 100644
--- a/frontend/src/components/Echarts.vue
+++ b/frontend/src/components/Echarts.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="myChart" class="echartsBox"></div>
diff --git a/frontend/src/components/FormTable.vue b/frontend/src/components/FormTable.vue
index 7c07c8b..efd8c44 100644
--- a/frontend/src/components/FormTable.vue
+++ b/frontend/src/components/FormTable.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 :model="formData" :rules="rules" :inline="inline" :label-position="labelPosition" :class="(inline ? 'demo-form-inline' : '', 'form_style')">
diff --git a/frontend/src/components/HelloWorld.vue b/frontend/src/components/HelloWorld.vue
index b498bda..197a6f1 100644
--- a/frontend/src/components/HelloWorld.vue
+++ b/frontend/src/components/HelloWorld.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="hello">欢迎加入IoTDB前端开发</div>
diff --git a/frontend/src/components/StandTable.vue b/frontend/src/components/StandTable.vue
index 4a02caf..479d3ef 100644
--- a/frontend/src/components/StandTable.vue
+++ b/frontend/src/components/StandTable.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
diff --git a/frontend/src/views/About/index.vue b/frontend/src/views/About/index.vue
index 73ab67e..44039a2 100644
--- a/frontend/src/views/About/index.vue
+++ b/frontend/src/views/About/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="about">
diff --git a/frontend/src/views/DataBaseM/components/dataListTree.vue b/frontend/src/views/DataBaseM/components/dataListTree.vue
index 426b66b..5d2bced 100644
--- a/frontend/src/views/DataBaseM/components/dataListTree.vue
+++ b/frontend/src/views/DataBaseM/components/dataListTree.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="data-list-tree">
diff --git a/frontend/src/views/DataBaseM/components/iconTypes.vue b/frontend/src/views/DataBaseM/components/iconTypes.vue
index 04feac8..3922abd 100644
--- a/frontend/src/views/DataBaseM/components/iconTypes.vue
+++ b/frontend/src/views/DataBaseM/components/iconTypes.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
   <span class="iconTypes">
diff --git a/frontend/src/views/DataBaseM/index.vue b/frontend/src/views/DataBaseM/index.vue
index 128f12b..8749b2c 100644
--- a/frontend/src/views/DataBaseM/index.vue
+++ b/frontend/src/views/DataBaseM/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="databasem">
diff --git a/frontend/src/views/Device/index.vue b/frontend/src/views/Device/index.vue
index 67d58a6..0a96df4 100644
--- a/frontend/src/views/Device/index.vue
+++ b/frontend/src/views/Device/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="padding: 20px">
diff --git a/frontend/src/views/DeviceMessage/components/action.vue b/frontend/src/views/DeviceMessage/components/action.vue
index 0c835c8..d31db76 100644
--- a/frontend/src/views/DeviceMessage/components/action.vue
+++ b/frontend/src/views/DeviceMessage/components/action.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="id" class="echartsBox"></div>
diff --git a/frontend/src/views/DeviceMessage/index.vue b/frontend/src/views/DeviceMessage/index.vue
index 2db9cc8..8ea44c6 100644
--- a/frontend/src/views/DeviceMessage/index.vue
+++ b/frontend/src/views/DeviceMessage/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index 4d79cbb..8305887 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="home">
diff --git a/frontend/src/views/Login/index.vue b/frontend/src/views/Login/index.vue
index a634bc2..174019e 100644
--- a/frontend/src/views/Login/index.vue
+++ b/frontend/src/views/Login/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="login">
diff --git a/frontend/src/views/Root/index.vue b/frontend/src/views/Root/index.vue
index e5a5194..5becb33 100644
--- a/frontend/src/views/Root/index.vue
+++ b/frontend/src/views/Root/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="root">
diff --git a/frontend/src/views/Source/components/empty.vue b/frontend/src/views/Source/components/empty.vue
index 3bdcb5e..cb7a0f2 100644
--- a/frontend/src/views/Source/components/empty.vue
+++ b/frontend/src/views/Source/components/empty.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="empty-page">
diff --git a/frontend/src/views/Source/components/newSource.vue b/frontend/src/views/Source/components/newSource.vue
index 2c0f070..1096971 100644
--- a/frontend/src/views/Source/components/newSource.vue
+++ b/frontend/src/views/Source/components/newSource.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="new-source">
diff --git a/frontend/src/views/Source/index.vue b/frontend/src/views/Source/index.vue
index 90230aa..237fd7c 100644
--- a/frontend/src/views/Source/index.vue
+++ b/frontend/src/views/Source/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="source-detail-container">
diff --git a/frontend/src/views/SqlSerch/components/codemirror.vue b/frontend/src/views/SqlSerch/components/codemirror.vue
index 816fa28..a933303 100644
--- a/frontend/src/views/SqlSerch/components/codemirror.vue
+++ b/frontend/src/views/SqlSerch/components/codemirror.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="font_fmiy">
diff --git a/frontend/src/views/SqlSerch/components/eltooltip.vue b/frontend/src/views/SqlSerch/components/eltooltip.vue
index e2fa8fc..83e5d2a 100644
--- a/frontend/src/views/SqlSerch/components/eltooltip.vue
+++ b/frontend/src/views/SqlSerch/components/eltooltip.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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-tooltip class="item" effect="light" :content="$t(label)" placement="top">
diff --git a/frontend/src/views/SqlSerch/components/formserch.vue b/frontend/src/views/SqlSerch/components/formserch.vue
index 7fb275e..2ed9972 100644
--- a/frontend/src/views/SqlSerch/components/formserch.vue
+++ b/frontend/src/views/SqlSerch/components/formserch.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
diff --git a/frontend/src/views/SqlSerch/components/formserchData.vue b/frontend/src/views/SqlSerch/components/formserchData.vue
index ba528fd..0cf2597 100644
--- a/frontend/src/views/SqlSerch/components/formserchData.vue
+++ b/frontend/src/views/SqlSerch/components/formserchData.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
diff --git a/frontend/src/views/SqlSerch/components/sqlDrawer.vue b/frontend/src/views/SqlSerch/components/sqlDrawer.vue
index a44e509..bddb6ac 100644
--- a/frontend/src/views/SqlSerch/components/sqlDrawer.vue
+++ b/frontend/src/views/SqlSerch/components/sqlDrawer.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="drawer">
diff --git a/frontend/src/views/SqlSerch/index.vue b/frontend/src/views/SqlSerch/index.vue
index 9b962e7..8baba7b 100644
--- a/frontend/src/views/SqlSerch/index.vue
+++ b/frontend/src/views/SqlSerch/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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-container>
diff --git a/frontend/src/views/storage/index.vue b/frontend/src/views/storage/index.vue
index a3b31e9..da7faec 100644
--- a/frontend/src/views/storage/index.vue
+++ b/frontend/src/views/storage/index.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="storage-container">
diff --git a/frontend/src/views/storage/newStorage.vue b/frontend/src/views/storage/newStorage.vue
index a651807..6efdc90 100644
--- a/frontend/src/views/storage/newStorage.vue
+++ b/frontend/src/views/storage/newStorage.vue
@@ -1,7 +1,21 @@
-/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding
-copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a
-copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS
-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="new-storage-container">


[iotdb-web-workbench] 16/34: Allow css to fail (#3)

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 361c11e4d110d9ef977dad28792f21ff02263dea
Author: Niklas Merz <ni...@linux.com>
AuthorDate: Mon Sep 20 16:43:12 2021 +0200

    Allow css to fail (#3)
---
 .github/workflows/frontend.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 58a3b31..ffd2581 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -30,6 +30,7 @@ jobs:
       - name: lint
         run: cd frontend && npm run lint
       - name: lint-css
+        continue-on-error: true
         run: cd frontend && npm run lint-css
     
   test:


[iotdb-web-workbench] 09/34: Added Spotless, fixed Spotless violations

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 12feef09c33a650869def86beec0ab8f66f5c25c
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 14:33:12 2021 +0200

    Added Spotless, fixed Spotless violations
---
 backend/pom.xml                                    |   30 +-
 .../org/apache/iotdb/admin/AdminApplication.java   |   11 +-
 .../iotdb/admin/aop/BaseExceptionAdvice.java       |   22 +-
 .../apache/iotdb/admin/aop/ParamValidAspect.java   |   60 +-
 .../admin/common/exception/BaseException.java      |   30 +-
 .../iotdb/admin/common/exception/ErrorCode.java    |  355 +-
 .../admin/common/utils/AuthenticationUtils.java    |   36 +-
 .../apache/iotdb/admin/config/FilterConfig.java    |   22 +-
 .../iotdb/admin/config/MybatisPlusConfig.java      |   37 +-
 .../apache/iotdb/admin/config/SecurityConfig.java  |   33 +-
 .../apache/iotdb/admin/config/SwaggerConfig.java   |   62 +-
 .../iotdb/admin/config/ValidatorConfiguration.java |   18 +-
 .../admin/controller/ConnectionController.java     |  147 +-
 .../iotdb/admin/controller/HealthController.java   |   39 +-
 .../iotdb/admin/controller/IotDBController.java    | 1590 ++++-----
 .../iotdb/admin/controller/QueryController.java    |  167 +-
 .../iotdb/admin/controller/UserController.java     |  134 +-
 .../java/org/apache/iotdb/admin/demo/JDBC.java     |  249 +-
 .../org/apache/iotdb/admin/demo/NativeAPI.java     |  158 +-
 .../org/apache/iotdb/admin/filter/TokenFilter.java |   47 +-
 .../iotdb/admin/mapper/ConnectionMapper.java       |    7 +-
 .../apache/iotdb/admin/mapper/DeviceMapper.java    |    6 +-
 .../org/apache/iotdb/admin/mapper/GroupMapper.java |    6 +-
 .../iotdb/admin/mapper/MeasurementMapper.java      |    7 +-
 .../org/apache/iotdb/admin/mapper/QueryMapper.java |    7 +-
 .../org/apache/iotdb/admin/mapper/UserMapper.java  |    7 +-
 .../iotdb/admin/model/dto/ConnectionDTO.java       |   40 +-
 .../org/apache/iotdb/admin/model/dto/CountDTO.java |    6 +-
 .../apache/iotdb/admin/model/dto/DeviceDTO.java    |    8 +-
 .../iotdb/admin/model/dto/DeviceInfoDTO.java       |   13 +-
 .../org/apache/iotdb/admin/model/dto/GroupDTO.java |   17 +-
 .../apache/iotdb/admin/model/dto/IotDBRole.java    |   11 +-
 .../apache/iotdb/admin/model/dto/IotDBUser.java    |   23 +-
 .../apache/iotdb/admin/model/dto/IotDBUserDTO.java |    2 +-
 .../iotdb/admin/model/dto/MeasurementDTO.java      |   16 +-
 .../iotdb/admin/model/dto/PrivilegeInfoDTO.java    |   20 +-
 .../org/apache/iotdb/admin/model/dto/QueryDTO.java |    8 +-
 .../apache/iotdb/admin/model/dto/SearchDTO.java    |    8 +-
 .../apache/iotdb/admin/model/dto/Timeseries.java   |   13 +-
 .../iotdb/admin/model/entity/Connection.java       |   49 +-
 .../apache/iotdb/admin/model/entity/Device.java    |   29 +-
 .../iotdb/admin/model/entity/Measurement.java      |   16 +-
 .../org/apache/iotdb/admin/model/entity/Query.java |   15 +-
 .../iotdb/admin/model/entity/StorageGroup.java     |   27 +-
 .../org/apache/iotdb/admin/model/entity/User.java  |   24 +-
 .../org/apache/iotdb/admin/model/vo/BaseVO.java    |   42 +-
 .../org/apache/iotdb/admin/model/vo/ConnVO.java    |    8 +-
 .../apache/iotdb/admin/model/vo/ConnectionVO.java  |   10 +-
 .../apache/iotdb/admin/model/vo/DeviceInfo.java    |   10 +-
 .../apache/iotdb/admin/model/vo/DeviceInfoVO.java  |    6 +-
 .../org/apache/iotdb/admin/model/vo/DeviceVO.java  |    8 +-
 .../apache/iotdb/admin/model/vo/GroupInfoVO.java   |    7 +-
 .../org/apache/iotdb/admin/model/vo/GroupVO.java   |   14 +-
 .../apache/iotdb/admin/model/vo/IotDBUserVO.java   |    8 +-
 .../apache/iotdb/admin/model/vo/MeasurementVO.java |   10 +-
 .../iotdb/admin/model/vo/MeasuremtnInfoVO.java     |    6 +-
 .../org/apache/iotdb/admin/model/vo/PathVO.java    |    6 +-
 .../apache/iotdb/admin/model/vo/PrivilegeInfo.java |   18 +-
 .../org/apache/iotdb/admin/model/vo/QueryVO.java   |    4 +-
 .../org/apache/iotdb/admin/model/vo/RecordVO.java  |    4 +-
 .../iotdb/admin/model/vo/RoleWithPrivilegesVO.java |    8 +-
 .../apache/iotdb/admin/model/vo/SqlResultVO.java   |   12 +-
 .../iotdb/admin/model/vo/StorageGroupVO.java       |    6 +-
 .../iotdb/admin/service/ConnectionService.java     |   12 +-
 .../apache/iotdb/admin/service/DeviceService.java  |   12 +-
 .../apache/iotdb/admin/service/GroupService.java   |   14 +-
 .../apache/iotdb/admin/service/IotDBService.java   |   75 +-
 .../iotdb/admin/service/MeasurementService.java    |   10 +-
 .../apache/iotdb/admin/service/QueryService.java   |   10 +-
 .../apache/iotdb/admin/service/UserService.java    |    6 +-
 .../admin/service/impl/ConnectionServiceImpl.java  |  160 +-
 .../admin/service/impl/DeviceServiceImpl.java      |  184 +-
 .../iotdb/admin/service/impl/GroupServiceImpl.java |  216 +-
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 3604 ++++++++++----------
 .../admin/service/impl/MeasurementServiceImpl.java |  190 +-
 .../iotdb/admin/service/impl/QueryServiceImpl.java |  121 +-
 .../iotdb/admin/service/impl/UserServiceImpl.java  |   84 +-
 .../test/java/org/apache/iotdb/admin/DemoJDBC.java |    7 +-
 .../admin/controller/ConnectionControllerTest.java |  119 +-
 .../admin/controller/IotDBControllerTest.java      |  515 +--
 .../admin/controller/QueryControllerTest.java      |  142 +-
 .../iotdb/admin/controller/TestSystemInfo.java     |   30 +-
 82 files changed, 4747 insertions(+), 4583 deletions(-)

diff --git a/backend/pom.xml b/backend/pom.xml
index 6413aba..63f9921 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -38,6 +38,7 @@
     <!-- 对应java 1.8,如果编译错误,可能需要调整 -->
     <java.version>1.8</java.version>
     <skipTests>true</skipTests>
+    <spotless.version>2.4.2</spotless.version>
   </properties>
 
 
@@ -208,6 +209,7 @@
       <plugin>
         <groupId>org.apache.rat</groupId>
         <artifactId>apache-rat-plugin</artifactId>
+        <version>0.13</version>
         <executions>
           <execution>
             <id>license-check</id>
@@ -218,7 +220,33 @@
           </execution>
         </executions>
       </plugin>
-
+      <plugin>
+        <groupId>com.diffplug.spotless</groupId>
+        <artifactId>spotless-maven-plugin</artifactId>
+        <version>${spotless.version}</version>
+        <configuration>
+          <java>
+            <googleJavaFormat>
+              <version>1.7</version>
+              <style>GOOGLE</style>
+            </googleJavaFormat>
+            <importOrder>
+              <order>org.apache.iotdb,,javax,java,\#</order>
+            </importOrder>
+            <removeUnusedImports/>
+          </java>
+          <lineEndings>UNIX</lineEndings>
+        </configuration>
+        <executions>
+          <execution>
+            <id>spotless-check</id>
+            <phase>validate</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
 
   </build>
diff --git a/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java b/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
index 55adaf8..9ac6ffd 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/AdminApplication.java
@@ -24,16 +24,13 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 
-/**
- * 后端代码启动类
- * 1. MapperScan需要配置为mapper所在的包,自动扫描mapper,MapperScan是用于数据库组件自动扫描使用的。
- */
+/** 后端代码启动类 1. MapperScan需要配置为mapper所在的包,自动扫描mapper,MapperScan是用于数据库组件自动扫描使用的。 */
 @SpringBootApplication
 @MapperScan("org.apache.iotdb.admin.mapper")
 @EnableWebSecurity
 public class AdminApplication {
 
-    public static void main(String[] args) {
-        SpringApplication.run(AdminApplication.class, args);
-    }
+  public static void main(String[] args) {
+    SpringApplication.run(AdminApplication.class, args);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java b/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
index da38b49..0f76a83 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/aop/BaseExceptionAdvice.java
@@ -19,26 +19,24 @@
 
 package org.apache.iotdb.admin.aop;
 
-import lombok.extern.slf4j.Slf4j;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.model.vo.BaseVO;
+
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseBody;
 
-/**
- * 通用异常处理拦截器
- */
+/** 通用异常处理拦截器 */
 @Slf4j
 @ControllerAdvice
 public class BaseExceptionAdvice {
 
-    @ExceptionHandler(BaseException.class)
-    @ResponseBody
-    public BaseVO handleBaseException(BaseException e) {
-        log.error("调用接口异常", e);
-        BaseVO result = new BaseVO(e.getErrorCode(), e.getMessage(), null);
-        return result;
-    }
-
+  @ExceptionHandler(BaseException.class)
+  @ResponseBody
+  public BaseVO handleBaseException(BaseException e) {
+    log.error("调用接口异常", e);
+    BaseVO result = new BaseVO(e.getErrorCode(), e.getMessage(), null);
+    return result;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java b/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
index 5b9cb07..f58767f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/aop/ParamValidAspect.java
@@ -19,9 +19,10 @@
 
 package org.apache.iotdb.admin.aop;
 
-import lombok.extern.slf4j.Slf4j;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
+
+import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -32,47 +33,40 @@ import org.springframework.stereotype.Component;
 import javax.validation.ConstraintViolation;
 import javax.validation.Path;
 import javax.validation.Validator;
+
 import java.util.Set;
 
-/**
- * 参数验证
- */
+/** 参数验证 */
 @Aspect
 @Slf4j
 @Component
 public class ParamValidAspect {
 
-    @Autowired
-    private Validator validator;
-
+  @Autowired private Validator validator;
 
-    /**
-     * 定义校验包的未知
-     */
-    @Pointcut("execution(* org.apache.iotdb.admin.controller..*.*(..))")
-    public void pointcut() {
-    }
+  /** 定义校验包的未知 */
+  @Pointcut("execution(* org.apache.iotdb.admin.controller..*.*(..))")
+  public void pointcut() {}
 
-    /**
-     * 处理参数校验错误的具体方法,抛出异常组件中的异常,遵循异常规范
-     */
-    @Around("pointcut()")
-    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
-        Object[] args = pjp.getArgs();
-        for (Object arg : args) {
-            if (arg != null) {
-                Set<ConstraintViolation<Object>> constraintViolations = validator.validate(arg);
-                if (constraintViolations.size() > 0) {
-                    for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
-                        Path property = constraintViolation.getPropertyPath();
-                        String name = property.iterator().next().getName();
-                        //打印具体异常信息,对应校验框架注解中的message
-                        log.error("[" + name + "]" + constraintViolation.getMessage());
-                        throw new BaseException(ErrorCode.WRONG_PARAM, "参数错误:" + constraintViolation.getMessage());
-                    }
-                }
-            }
+  /** 处理参数校验错误的具体方法,抛出异常组件中的异常,遵循异常规范 */
+  @Around("pointcut()")
+  public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+    Object[] args = pjp.getArgs();
+    for (Object arg : args) {
+      if (arg != null) {
+        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(arg);
+        if (constraintViolations.size() > 0) {
+          for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
+            Path property = constraintViolation.getPropertyPath();
+            String name = property.iterator().next().getName();
+            // 打印具体异常信息,对应校验框架注解中的message
+            log.error("[" + name + "]" + constraintViolation.getMessage());
+            throw new BaseException(
+                ErrorCode.WRONG_PARAM, "参数错误:" + constraintViolation.getMessage());
+          }
         }
-        return pjp.proceed();
+      }
     }
+    return pjp.proceed();
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
index 41eaa70..38c4a20 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/BaseException.java
@@ -19,25 +19,23 @@
 
 package org.apache.iotdb.admin.common.exception;
 
-/**
- * 异常类
- */
+/** 异常类 */
 public class BaseException extends Exception {
 
-    private String errorCode;
-    private String message;
+  private String errorCode;
+  private String message;
 
-    public BaseException(String errorCode, String message) {
-        this.errorCode = errorCode;
-        this.message = message;
-    }
+  public BaseException(String errorCode, String message) {
+    this.errorCode = errorCode;
+    this.message = message;
+  }
 
-    public String getErrorCode() {
-        return errorCode;
-    }
+  public String getErrorCode() {
+    return errorCode;
+  }
 
-    @Override
-    public String getMessage() {
-        return message;
-    }
+  @Override
+  public String getMessage() {
+    return message;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
index 1fa47da..499ab83 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/exception/ErrorCode.java
@@ -19,268 +19,265 @@
 
 package org.apache.iotdb.admin.common.exception;
 
-/**
- * 错误码类
- */
+/** 错误码类 */
 public class ErrorCode {
 
-    // 连接相关
-    public static final String ALIAS_REPEAT = "CONN-0001";
-    public static final String ALIAS_REPEAT_MSG = "别名重复";
-
-    public static final String INSERT_CONN_FAIL = "CONN-0002";
-    public static final String INSERT_CONN_FAIL_MSG = "添加或更新连接失败";
+  // 连接相关
+  public static final String ALIAS_REPEAT = "CONN-0001";
+  public static final String ALIAS_REPEAT_MSG = "别名重复";
 
-    public static final String DELETE_CONN_FAIL = "CONN-0003";
-    public static final String DELETE_CONN_FAIL_MSG = "删除连接失败";
+  public static final String INSERT_CONN_FAIL = "CONN-0002";
+  public static final String INSERT_CONN_FAIL_MSG = "添加或更新连接失败";
 
-    public static final String NO_CONN = "CONN-0004";
-    public static final String NO_CONN_MSG = "连接不存在";
+  public static final String DELETE_CONN_FAIL = "CONN-0003";
+  public static final String DELETE_CONN_FAIL_MSG = "删除连接失败";
 
-    public static final String GET_CONN_FAIL = "CONN-0005";
-    public static final String GET_CONN_FAIL_MSG = "获取连接失败";
+  public static final String NO_CONN = "CONN-0004";
+  public static final String NO_CONN_MSG = "连接不存在";
 
-    public static final String CHECK_FAIL = "CONN-0006";
-    public static final String CHECK_FAIL_MSG = "没有权限或连接不存在";
+  public static final String GET_CONN_FAIL = "CONN-0005";
+  public static final String GET_CONN_FAIL_MSG = "获取连接失败";
 
-    public static final String TEST_CONN_FAIL = "CONN-0007";
-    public static final String TEST_CONN_FAIL_MSG = "连接不可达或连接超时";
+  public static final String CHECK_FAIL = "CONN-0006";
+  public static final String CHECK_FAIL_MSG = "没有权限或连接不存在";
 
-    public static final String TEST_CONN_WRONG = "CONN-0008";
-    public static final String TEST_CONN_WRONG_MSG = "连接失败,主机输入不合法";
+  public static final String TEST_CONN_FAIL = "CONN-0007";
+  public static final String TEST_CONN_FAIL_MSG = "连接不可达或连接超时";
 
-    public static final String TIME_OUT = "CONN-0009";
-    public static final String TIME_OUT_MSG = "连接超时";
+  public static final String TEST_CONN_WRONG = "CONN-0008";
+  public static final String TEST_CONN_WRONG_MSG = "连接失败,主机输入不合法";
 
-    public static final String TEST_CONN_FAIL_PWD = "CONN-0010";
-    public static final String TEST_CONN_FAIL_PWD_MSG = "连接失败,用户名或密码错误";
+  public static final String TIME_OUT = "CONN-0009";
+  public static final String TIME_OUT_MSG = "连接超时";
 
-    // 登录相关
-    public static final String LOGIN_FAIL_USER = "USER-0001";
-    public static final String LOGIN_FAIL_USER_MSG = "登录失败,用户不存在";
+  public static final String TEST_CONN_FAIL_PWD = "CONN-0010";
+  public static final String TEST_CONN_FAIL_PWD_MSG = "连接失败,用户名或密码错误";
 
-    public static final String USER_EXIST = "USER-0002";
-    public static final String USER_EXIST_MSG = "用户已存在";
+  // 登录相关
+  public static final String LOGIN_FAIL_USER = "USER-0001";
+  public static final String LOGIN_FAIL_USER_MSG = "登录失败,用户不存在";
 
-    public static final String LOGIN_FAIL_PWD = "USER-0003";
-    public static final String LOGIN_FAIL_PWD_MSG = "登录失败,密码错误";
+  public static final String USER_EXIST = "USER-0002";
+  public static final String USER_EXIST_MSG = "用户已存在";
 
-    public static final String INSERT_USER_FAIL = "USER-0004";
-    public static final String INSERT_USER_FAIL_MSG = "插入失败";
+  public static final String LOGIN_FAIL_PWD = "USER-0003";
+  public static final String LOGIN_FAIL_PWD_MSG = "登录失败,密码错误";
 
-    public static final String WRONG_USER_PARAM = "USER-0005";
-    public static final String WRONG_USER_PARAM_MSG = "请输入合法的用户名和密码";
+  public static final String INSERT_USER_FAIL = "USER-0004";
+  public static final String INSERT_USER_FAIL_MSG = "插入失败";
 
-    public static final String DELETE_USER_FAIL = "USER-0006";
-    public static final String DELETE_USER_FAIL_MSG = "删除用户失败";
+  public static final String WRONG_USER_PARAM = "USER-0005";
+  public static final String WRONG_USER_PARAM_MSG = "请输入合法的用户名和密码";
 
-    public static final String NO_USER = "USER-0007";
-    public static final String NO_USER_MSG = "用户未指定";
+  public static final String DELETE_USER_FAIL = "USER-0006";
+  public static final String DELETE_USER_FAIL_MSG = "删除用户失败";
 
-    public static final String USER_AUTH_FAIL = "USER-0008";
-    public static final String USER_AUTH_FAIL_MSG = "用户不一致,不能进行操作";
+  public static final String NO_USER = "USER-0007";
+  public static final String NO_USER_MSG = "用户未指定";
 
-    public static final String TOKEN_ERR = "USER-0009";
-    public static final String TOKEN_ERR_MSG = "请登录或token失效";
+  public static final String USER_AUTH_FAIL = "USER-0008";
+  public static final String USER_AUTH_FAIL_MSG = "用户不一致,不能进行操作";
 
-    public static final String GET_TOKEN_FAIL = "USER-0010";
-    public static final String GET_TOKEN_FAIL_MSG = "获取token失败";
+  public static final String TOKEN_ERR = "USER-0009";
+  public static final String TOKEN_ERR_MSG = "请登录或token失效";
 
-    public static final String SET_JWT_FAIL = "USER-0011";
-    public static final String SET_JWT_FAIL_MSG = "JWT编解码失败";
+  public static final String GET_TOKEN_FAIL = "USER-0010";
+  public static final String GET_TOKEN_FAIL_MSG = "获取token失败";
 
-    // iotDB相关
-    public static final String INSERT_TS_FAIL = "IOTDB-0001";
-    public static final String INSERT_TS_FAIL_MSG = "插入时间序列失败";
+  public static final String SET_JWT_FAIL = "USER-0011";
+  public static final String SET_JWT_FAIL_MSG = "JWT编解码失败";
 
-    public static final String DELETE_TS_FAIL = "IOTDB-0002";
-    public static final String DELETE_TS_FAIL_MSG = "删除时间序列失败";
+  // iotDB相关
+  public static final String INSERT_TS_FAIL = "IOTDB-0001";
+  public static final String INSERT_TS_FAIL_MSG = "插入时间序列失败";
 
-    public static final String DB_BOOL_WRONG = "IOTDB-0003";
-    public static final String DB_BOOL_WRONG_MSG = "Boolean值输入错误,0为false,1为true";
+  public static final String DELETE_TS_FAIL = "IOTDB-0002";
+  public static final String DELETE_TS_FAIL_MSG = "删除时间序列失败";
 
-    public static final String DB_DATATYPE_WRONG = "IOTDB-0004";
-    public static final String DB_DATATYPE_WRONG_MSG = "TSDataType类型传入错误";
+  public static final String DB_BOOL_WRONG = "IOTDB-0003";
+  public static final String DB_BOOL_WRONG_MSG = "Boolean值输入错误,0为false,1为true";
 
-    public static final String GET_DBCONN_FAIL = "IOTDB-005";
-    public static final String GET_DBCONN_FAIL_MSG = "获取数据库连接失败";
+  public static final String DB_DATATYPE_WRONG = "IOTDB-0004";
+  public static final String DB_DATATYPE_WRONG_MSG = "TSDataType类型传入错误";
 
-    public static final String GET_SESSION_FAIL = "IOTDB-0006";
-    public static final String GET_SESSION_FAIL_MSG = "获取session失败";
+  public static final String GET_DBCONN_FAIL = "IOTDB-005";
+  public static final String GET_DBCONN_FAIL_MSG = "获取数据库连接失败";
 
-    public static final String CLOSE_DBCONN_FAIL = "IOTDB-0007";
-    public static final String CLOSE_DBCONN_FAIL_MSG = "关闭连接失败";
+  public static final String GET_SESSION_FAIL = "IOTDB-0006";
+  public static final String GET_SESSION_FAIL_MSG = "获取session失败";
 
-    public static final String SQL_EP = "IOTDB-0008";
-    public static final String SQL_EP_MSG = "没有权限或sql异常";
+  public static final String CLOSE_DBCONN_FAIL = "IOTDB-0007";
+  public static final String CLOSE_DBCONN_FAIL_MSG = "关闭连接失败";
 
-    public static final String QUERY_FAIL = "IOTDB-0009";
-    public static final String QUERY_FAIL_MSG = "sql查询失败";
+  public static final String SQL_EP = "IOTDB-0008";
+  public static final String SQL_EP_MSG = "没有权限或sql异常";
 
-    public static final String SQL_PARAM_WRONG = "IOTDB-0010";
-    public static final String SQL_PARAM_WRONG_MSG = "sql参数不合法";
+  public static final String QUERY_FAIL = "IOTDB-0009";
+  public static final String QUERY_FAIL_MSG = "sql查询失败";
 
-    public static final String WRONG_DB_PARAM = "IOTDB-0011";
-    public static final String WRONG_DB_PARAM_MSG = "输入参数不合法";
+  public static final String SQL_PARAM_WRONG = "IOTDB-0010";
+  public static final String SQL_PARAM_WRONG_MSG = "sql参数不合法";
 
-    public static final String GET_USER_FAIL = "IOTDB-0012";
-    public static final String GET_USER_FAIL_MSG = "获取用户信息失败";
+  public static final String WRONG_DB_PARAM = "IOTDB-0011";
+  public static final String WRONG_DB_PARAM_MSG = "输入参数不合法";
 
-    public static final String GET_SQL_ONE_VALUE_FAIL = "IOTDB-0013";
-    public static final String GET_SQL_ONE_VALUE_FAIL_MSG = "获取值失败";
+  public static final String GET_USER_FAIL = "IOTDB-0012";
+  public static final String GET_USER_FAIL_MSG = "获取用户信息失败";
 
-    public static final String SET_TTL_FAIL = "IOTDB-0014";
-    public static final String SET_TTL_FAIL_MSG = "设置存活时间失败";
+  public static final String GET_SQL_ONE_VALUE_FAIL = "IOTDB-0013";
+  public static final String GET_SQL_ONE_VALUE_FAIL_MSG = "获取值失败";
 
-    public static final String DEL_TTL_FAIL = "IOTDB-0015";
-    public static final String DEL_TTL_FAIL_MSG = "删除存活时间失败";
+  public static final String SET_TTL_FAIL = "IOTDB-0014";
+  public static final String SET_TTL_FAIL_MSG = "设置存活时间失败";
 
-    public static final String GET_SQL_ONE_COLUMN_FAIL = "IOTDB-0016";
-    public static final String GET_SQL_ONE_COLUMN_FAIL_MSG = "获取列表失败";
+  public static final String DEL_TTL_FAIL = "IOTDB-0015";
+  public static final String DEL_TTL_FAIL_MSG = "删除存活时间失败";
 
-    public static final String GET_SQL_SET_FAIL = "IOTDB-0017";
-    public static final String GET_SQL_SET_FAIL_MSG = "获取列表集合失败";
+  public static final String GET_SQL_ONE_COLUMN_FAIL = "IOTDB-0016";
+  public static final String GET_SQL_ONE_COLUMN_FAIL_MSG = "获取列表失败";
 
-    public static final String INSERT_DEV_FAIL = "IOTDB-0018";
-    public static final String INSERT_DEV_FAIL_MSG = "插入实体失败";
+  public static final String GET_SQL_SET_FAIL = "IOTDB-0017";
+  public static final String GET_SQL_SET_FAIL_MSG = "获取列表集合失败";
 
-    public static final String GET_MSM_FAIL = "IOTDB-0019";
-    public static final String GET_MSM_FAIL_MSG = "获取物理量数据信息失败";
+  public static final String INSERT_DEV_FAIL = "IOTDB-0018";
+  public static final String INSERT_DEV_FAIL_MSG = "插入实体失败";
 
-    public static final String NO_SUCH_FIELD = "IOTDB-0020";
-    public static final String NO_SUCH_FIELD_MSG = "返回集没此属性";
+  public static final String GET_MSM_FAIL = "IOTDB-0019";
+  public static final String GET_MSM_FAIL_MSG = "获取物理量数据信息失败";
 
-    public static final String GET_LAST_VALUE_FAIL = "IOTDB-0021";
-    public static final String GET_LAST_VALUE_FAIL_MSG = "获取物理量最新值失败";
+  public static final String NO_SUCH_FIELD = "IOTDB-0020";
+  public static final String NO_SUCH_FIELD_MSG = "返回集没此属性";
 
-    public static final String SET_GROUP_FAIL = "IOTDB-0022";
-    public static final String SET_GROUP_FAIL_MSG = "创建存储组失败";
+  public static final String GET_LAST_VALUE_FAIL = "IOTDB-0021";
+  public static final String GET_LAST_VALUE_FAIL_MSG = "获取物理量最新值失败";
 
-    public static final String DELETE_GROUP_FAIL = "IOTDB-0023";
-    public static final String DELETE_GROUP_FAIL_MSG = "删除存储组失败";
+  public static final String SET_GROUP_FAIL = "IOTDB-0022";
+  public static final String SET_GROUP_FAIL_MSG = "创建存储组失败";
 
-    public static final String DELETE_DB_USER_FAIL = "IOTDB-0024";
-    public static final String DELETE_DB_USER_FAIL_MSG = "删除数据库用户失败";
+  public static final String DELETE_GROUP_FAIL = "IOTDB-0023";
+  public static final String DELETE_GROUP_FAIL_MSG = "删除存储组失败";
 
-    public static final String DELETE_DB_ROLE_FAIL = "IOTDB-0025";
-    public static final String DELETE_DB_ROLE_FAIL_MSG = "删除数据库角色失败";
+  public static final String DELETE_DB_USER_FAIL = "IOTDB-0024";
+  public static final String DELETE_DB_USER_FAIL_MSG = "删除数据库用户失败";
 
-    public static final String SET_DB_USER_FAIL = "IOTDB-0026";
-    public static final String SET_DB_USER_FAIL_MSG = "创建数据库用户失败";
+  public static final String DELETE_DB_ROLE_FAIL = "IOTDB-0025";
+  public static final String DELETE_DB_ROLE_FAIL_MSG = "删除数据库角色失败";
 
-    public static final String SET_DB_ROLE_FAIL = "IOTDB-0027";
-    public static final String SET_DB_ROLE_FAIL_MSG = "创建数据库角色或对应权限时失败";
+  public static final String SET_DB_USER_FAIL = "IOTDB-0026";
+  public static final String SET_DB_USER_FAIL_MSG = "创建数据库用户失败";
 
-    public static final String NO_TYPE = "IOTDB-0028";
-    public static final String NO_TYPE_MSG = "粒度类型不存在";
+  public static final String SET_DB_ROLE_FAIL = "IOTDB-0027";
+  public static final String SET_DB_ROLE_FAIL_MSG = "创建数据库角色或对应权限时失败";
 
-    public static final String PRIV_ROOT_FAIL = "IOTDB-0029";
-    public static final String PRIV_ROOT_FAIL_MSG = "根路径权限操作失败";
+  public static final String NO_TYPE = "IOTDB-0028";
+  public static final String NO_TYPE_MSG = "粒度类型不存在";
 
-    public static final String PRIV_GROUP_FAIL = "IOTDB-0030";
-    public static final String PRIV_GROUP_FAIL_MSG = "组路径权限操作失败";
+  public static final String PRIV_ROOT_FAIL = "IOTDB-0029";
+  public static final String PRIV_ROOT_FAIL_MSG = "根路径权限操作失败";
 
-    public static final String PRIV_DEVICE_FAIL = "IOTDB-0031";
-    public static final String PRIV_DEVICE_FAIL_MSG = "实体路径权限操作失败";
+  public static final String PRIV_GROUP_FAIL = "IOTDB-0030";
+  public static final String PRIV_GROUP_FAIL_MSG = "组路径权限操作失败";
 
-    public static final String PRIV_TIMESERIES_FAIL = "IOTDB-0032";
-    public static final String PRIV_TIMESERIES_FAIL_MSG = "物理量路径权限操作失败";
+  public static final String PRIV_DEVICE_FAIL = "IOTDB-0031";
+  public static final String PRIV_DEVICE_FAIL_MSG = "实体路径权限操作失败";
 
-    public static final String GET_RECORD_FAIL = "IOTDB-0033";
-    public static final String GET_RECORD_FAIL_MSG = "获取物理量记录失败";
+  public static final String PRIV_TIMESERIES_FAIL = "IOTDB-0032";
+  public static final String PRIV_TIMESERIES_FAIL_MSG = "物理量路径权限操作失败";
 
-    public static final String NO_SQL = "IOTDB-0034";
-    public static final String NO_SQL_MSG = "没有sql执行语句";
+  public static final String GET_RECORD_FAIL = "IOTDB-0033";
+  public static final String GET_RECORD_FAIL_MSG = "获取物理量记录失败";
 
-    public static final String UPDATE_GROUP_INFO_FAIL = "IOTDB-0035";
-    public static final String UPDATE_GROUP_INFO_FAIL_MSG = "更新组信息失败";
+  public static final String NO_SQL = "IOTDB-0034";
+  public static final String NO_SQL_MSG = "没有sql执行语句";
 
-    public static final String NO_GROUP_INFO = "IOTDB-0036";
-    public static final String NO_GROUP_INFO_MSG = "不存在存储组信息";
+  public static final String UPDATE_GROUP_INFO_FAIL = "IOTDB-0035";
+  public static final String UPDATE_GROUP_INFO_FAIL_MSG = "更新组信息失败";
 
-    public static final String NO_GROUP = "IOTDB-0037";
-    public static final String NO_GROUP_MSG = "不存在存储组";
+  public static final String NO_GROUP_INFO = "IOTDB-0036";
+  public static final String NO_GROUP_INFO_MSG = "不存在存储组信息";
 
-    public static final String NO_DEVICE_INFO = "IOTDB-0038";
-    public static final String NO_DEVICE_INFO_MSG = "不存在设备信息";
+  public static final String NO_GROUP = "IOTDB-0037";
+  public static final String NO_GROUP_MSG = "不存在存储组";
 
-    public static final String UPDATE_PWD_FAIL = "IOTDB-0039";
-    public static final String UPDATE_PWD_FAIL_MSG = "修改账号密码失败";
+  public static final String NO_DEVICE_INFO = "IOTDB-0038";
+  public static final String NO_DEVICE_INFO_MSG = "不存在设备信息";
 
-    public static final String NO_QUERY = "IOTDB-0040";
-    public static final String NO_QUERY_MSG = "不存在此查询";
+  public static final String UPDATE_PWD_FAIL = "IOTDB-0039";
+  public static final String UPDATE_PWD_FAIL_MSG = "修改账号密码失败";
 
-    public static final String NO_ALL_NUM_SEARCH = "IOTDB-0041";
-    public static final String NO_ALL_NUM_SEARCH_MSG = "不支持纯数字查询";
+  public static final String NO_QUERY = "IOTDB-0040";
+  public static final String NO_QUERY_MSG = "不存在此查询";
 
-    public static final String NO_PRI_SET_TTL = "IOTDB-0042";
-    public static final String NO_PRI_SET_TTL_MSG = "没有权限设置存活时间";
+  public static final String NO_ALL_NUM_SEARCH = "IOTDB-0041";
+  public static final String NO_ALL_NUM_SEARCH_MSG = "不支持纯数字查询";
 
-    public static final String NO_PRI_CREATE_TIMESERIES = "IOTDB-0043";
-    public static final String NO_PRI_CREATE_TIMESERIES_MSG = "没有权限创建物理量";
+  public static final String NO_PRI_SET_TTL = "IOTDB-0042";
+  public static final String NO_PRI_SET_TTL_MSG = "没有权限设置存活时间";
 
-    public static final String NO_PRI_READ_TIMESERIES = "IOTDB-0044";
-    public static final String NO_PRI_READ_TIMESERIES_MSG = "没有权限查看物理量";
+  public static final String NO_PRI_CREATE_TIMESERIES = "IOTDB-0043";
+  public static final String NO_PRI_CREATE_TIMESERIES_MSG = "没有权限创建物理量";
 
-    public static final String NO_PRI_DELETE_TIMESERIES = "IOTDB-0045";
-    public static final String NO_PRI_DELETE_TIMESERIES_MSG = "没有权限删除物理量";
+  public static final String NO_PRI_READ_TIMESERIES = "IOTDB-0044";
+  public static final String NO_PRI_READ_TIMESERIES_MSG = "没有权限查看物理量";
 
-    public static final String CONN_REFUSED = "IOTDB-0046";
-    public static final String CONN_REFUSED_MSG = "连接错误,检查输入";
+  public static final String NO_PRI_DELETE_TIMESERIES = "IOTDB-0045";
+  public static final String NO_PRI_DELETE_TIMESERIES_MSG = "没有权限删除物理量";
 
-    public static final String WRONG_USER = "IOTDB-0047";
-    public static final String WRONG_USER_MSG = "连接用户名或密码错误";
+  public static final String CONN_REFUSED = "IOTDB-0046";
+  public static final String CONN_REFUSED_MSG = "连接错误,检查输入";
 
-    public static final String NO_PRI_SET_GROUP = "IOTDB-0048";
-    public static final String NO_PRI_SET_GROUP_MSG = "没有权限操作存储组";
+  public static final String WRONG_USER = "IOTDB-0047";
+  public static final String WRONG_USER_MSG = "连接用户名或密码错误";
 
-    public static final String NO_PRI_DELETE_GROUP = "IOTDB-0048";
-    public static final String NO_PRI_DELETE_GROUP_MSG = "没有权限删除存储组";
+  public static final String NO_PRI_SET_GROUP = "IOTDB-0048";
+  public static final String NO_PRI_SET_GROUP_MSG = "没有权限操作存储组";
 
-    public static final String NO_SUPPORT_SQL = "IOTDB-0049";
-    public static final String NO_SUPPORT_SQL_MSG = "不支持此sql执行";
+  public static final String NO_PRI_DELETE_GROUP = "IOTDB-0048";
+  public static final String NO_PRI_DELETE_GROUP_MSG = "没有权限删除存储组";
 
-    public static final String TTL_WRONG = "IOTDB-0050";
-    public static final String TTL_WRONG_MSG = "存活时间必须大于等于0";
+  public static final String NO_SUPPORT_SQL = "IOTDB-0049";
+  public static final String NO_SUPPORT_SQL_MSG = "不支持此sql执行";
 
-    public static final String NO_PRI_TIMESERIES_DATA = "IOTDB-0051";
-    public static final String NO_PRI_TIMESERIES_DATA_MSG = "没有权限查看测点数据";
+  public static final String TTL_WRONG = "IOTDB-0050";
+  public static final String TTL_WRONG_MSG = "存活时间必须大于等于0";
 
-    public static final String NO_SUP_CONTAIN_ROOT = "IOTDB-0052";
-    public static final String NO_SUP_CONTAIN_ROOT_MSG = "不支持包含\"root\"的输入";
+  public static final String NO_PRI_TIMESERIES_DATA = "IOTDB-0051";
+  public static final String NO_PRI_TIMESERIES_DATA_MSG = "没有权限查看测点数据";
 
-    // 存储组表相关
-    public static final String INSERT_GROUP_INFO_FAIL = "GROUP-0001";
-    public static final String INSERT_GROUP_INFO_FAIL_MSG = "插入存储组信息失败";
+  public static final String NO_SUP_CONTAIN_ROOT = "IOTDB-0052";
+  public static final String NO_SUP_CONTAIN_ROOT_MSG = "不支持包含\"root\"的输入";
 
-    public static final String DELETE_GROUP_INFO_FAIL = "GROUP-0002";
-    public static final String DELETE_GROUP_INFO_FAIL_MSG = "删除存储组信息失败";
+  // 存储组表相关
+  public static final String INSERT_GROUP_INFO_FAIL = "GROUP-0001";
+  public static final String INSERT_GROUP_INFO_FAIL_MSG = "插入存储组信息失败";
 
-    // 实体表相关
-    public static final String DELETE_DEVICE_INFO_FAIL = "DEV-0001";
-    public static final String DELETE_DEVICE_INFO_FAIL_MSG = "删除实体信息失败";
+  public static final String DELETE_GROUP_INFO_FAIL = "GROUP-0002";
+  public static final String DELETE_GROUP_INFO_FAIL_MSG = "删除存储组信息失败";
 
-    public static final String SET_DEVICE_INFO_FAIL = "DEV-0002";
-    public static final String SET_DEVICE_INFO_FAIL_MSG = "插入实体信息失败";
+  // 实体表相关
+  public static final String DELETE_DEVICE_INFO_FAIL = "DEV-0001";
+  public static final String DELETE_DEVICE_INFO_FAIL_MSG = "删除实体信息失败";
 
-    // 物理量表相关
-    public static final String DELETE_MEASUREMENT_INFO_FAIL = "MEASU-0001";
-    public static final String DELETE_MEASUREMENT_INFO_FAIL_MSG = "删除物理量信息失败";
+  public static final String SET_DEVICE_INFO_FAIL = "DEV-0002";
+  public static final String SET_DEVICE_INFO_FAIL_MSG = "插入实体信息失败";
 
-    public static final String SET_MEASUREMENT_INFO_FAIL = "MEASU-0002";
-    public static final String SET_MEASUREMENT_INFO_FAIL_MSG = "插入物理量信息失败";
+  // 物理量表相关
+  public static final String DELETE_MEASUREMENT_INFO_FAIL = "MEASU-0001";
+  public static final String DELETE_MEASUREMENT_INFO_FAIL_MSG = "删除物理量信息失败";
 
-    public static final String GET_MSM_DES_FAIL = "MEASU-0003";
-    public static final String GET_MSM_DES_FAIL_MSG = "获取物理量描述信息失败";
+  public static final String SET_MEASUREMENT_INFO_FAIL = "MEASU-0002";
+  public static final String SET_MEASUREMENT_INFO_FAIL_MSG = "插入物理量信息失败";
 
-    // 查询表相关
-    public static final String QUERY_EXIST = "QUERY-0001";
-    public static final String QUERY_EXIST_MSG = "脚本名已存在";
+  public static final String GET_MSM_DES_FAIL = "MEASU-0003";
+  public static final String GET_MSM_DES_FAIL_MSG = "获取物理量描述信息失败";
 
-    public static final String QUERY_NOT_EXIST = "QUERY-0002";
-    public static final String QUERY_NOT_EXIST_MSG = "脚本不存在";
+  // 查询表相关
+  public static final String QUERY_EXIST = "QUERY-0001";
+  public static final String QUERY_EXIST_MSG = "脚本名已存在";
 
+  public static final String QUERY_NOT_EXIST = "QUERY-0002";
+  public static final String QUERY_NOT_EXIST_MSG = "脚本不存在";
 
-    // 参数校验相关
-    public static final String WRONG_PARAM = "PARAM-0001";
+  // 参数校验相关
+  public static final String WRONG_PARAM = "PARAM-0001";
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java b/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
index efe1f84..98047dd 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/common/utils/AuthenticationUtils.java
@@ -19,31 +19,31 @@
 
 package org.apache.iotdb.admin.common.utils;
 
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.interfaces.DecodedJWT;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.interfaces.DecodedJWT;
+
 import javax.servlet.http.HttpServletRequest;
 
-/**
- * 校验工具类
- */
+/** 校验工具类 */
 public class AuthenticationUtils {
 
-    public static void userAuthentication(Integer userId, HttpServletRequest request) throws BaseException {
-        if (userId == null) {
-            throw new BaseException(ErrorCode.NO_USER, ErrorCode.NO_USER_MSG);
-        }
-        DecodedJWT authorization = JWT.decode(request.getHeader("Authorization"));
-        Integer tokenUserId = authorization.getClaim("userId").asInt();
-        if (!tokenUserId.equals(userId)) {
-            throw new BaseException(ErrorCode.USER_AUTH_FAIL, ErrorCode.USER_AUTH_FAIL_MSG);
-        }
+  public static void userAuthentication(Integer userId, HttpServletRequest request)
+      throws BaseException {
+    if (userId == null) {
+      throw new BaseException(ErrorCode.NO_USER, ErrorCode.NO_USER_MSG);
     }
-
-    public static Integer getUserId(HttpServletRequest request) {
-        DecodedJWT authentication = JWT.decode(request.getHeader("Authorization"));
-        return authentication.getClaim("userId").asInt();
+    DecodedJWT authorization = JWT.decode(request.getHeader("Authorization"));
+    Integer tokenUserId = authorization.getClaim("userId").asInt();
+    if (!tokenUserId.equals(userId)) {
+      throw new BaseException(ErrorCode.USER_AUTH_FAIL, ErrorCode.USER_AUTH_FAIL_MSG);
     }
+  }
+
+  public static Integer getUserId(HttpServletRequest request) {
+    DecodedJWT authentication = JWT.decode(request.getHeader("Authorization"));
+    return authentication.getClaim("userId").asInt();
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
index 50dafeb..3a00d52 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/FilterConfig.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.admin.config;
 
 import org.apache.iotdb.admin.filter.TokenFilter;
+
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -28,19 +29,16 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * 拦截器配置类
- */
+/** 拦截器配置类 */
 @Component
 public class FilterConfig implements WebMvcConfigurer {
 
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        InterceptorRegistration interceptorRegistration = registry.addInterceptor(new TokenFilter());
-        List<String> paths = new ArrayList();
-        paths.add("/servers/**");
-        paths.add("/get");
-        interceptorRegistration.addPathPatterns(paths);
-    }
-
+  @Override
+  public void addInterceptors(InterceptorRegistry registry) {
+    InterceptorRegistration interceptorRegistration = registry.addInterceptor(new TokenFilter());
+    List<String> paths = new ArrayList();
+    paths.add("/servers/**");
+    paths.add("/get");
+    interceptorRegistration.addPathPatterns(paths);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
index becedc1..607aa1e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/MybatisPlusConfig.java
@@ -25,27 +25,24 @@ import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerIntercept
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-/**
- * 该类是Mybatis-Plus的配置类,mybatis以插件的形式来实现特定功能
- */
+/** 该类是Mybatis-Plus的配置类,mybatis以插件的形式来实现特定功能 */
 @Configuration
 public class MybatisPlusConfig {
 
-    /**
-     * 分页插件配置,对相关数据库进行拦截并分页
-     *
-     * @return 分页拦截器
-     */
-    @Bean
-    public MybatisPlusInterceptor paginationInterceptor() {
-        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-        // 使用不同的数据库,可以更改DbType.MYSQL的类型
-        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
-        // 每页最多100条,可以更改,但不建议太大
-        paginationInnerInterceptor.setMaxLimit(100L);
-        interceptor.addInnerInterceptor(paginationInnerInterceptor);
-        return interceptor;
-    }
-
-
+  /**
+   * 分页插件配置,对相关数据库进行拦截并分页
+   *
+   * @return 分页拦截器
+   */
+  @Bean
+  public MybatisPlusInterceptor paginationInterceptor() {
+    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+    // 使用不同的数据库,可以更改DbType.MYSQL的类型
+    PaginationInnerInterceptor paginationInnerInterceptor =
+        new PaginationInnerInterceptor(DbType.MYSQL);
+    // 每页最多100条,可以更改,但不建议太大
+    paginationInnerInterceptor.setMaxLimit(100L);
+    interceptor.addInnerInterceptor(paginationInnerInterceptor);
+    return interceptor;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
index bf93858..e4c0340 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/SecurityConfig.java
@@ -25,25 +25,24 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 
-/**
- * 加密算法配置类 hash算法
- */
+/** 加密算法配置类 hash算法 */
 @Configuration
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-        http.authorizeRequests()
-            .antMatchers("/**")
-            .permitAll()
-            .anyRequest()
-            .authenticated()
-            .and().csrf().disable();
-    }
-
-    @Bean
-    public BCryptPasswordEncoder bCryptPasswordEncoder() {
-        return new BCryptPasswordEncoder();
-    }
+  @Override
+  protected void configure(HttpSecurity http) throws Exception {
+    http.authorizeRequests()
+        .antMatchers("/**")
+        .permitAll()
+        .anyRequest()
+        .authenticated()
+        .and()
+        .csrf()
+        .disable();
+  }
 
+  @Bean
+  public BCryptPasswordEncoder bCryptPasswordEncoder() {
+    return new BCryptPasswordEncoder();
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java b/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
index 45a0374..70eb759 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/SwaggerConfig.java
@@ -36,44 +36,42 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * swagger配置类
- */
+/** swagger配置类 */
 @Configuration
 @EnableSwagger2
 @Profile({"dev", "test"})
 public class SwaggerConfig {
 
-    @Bean
-    public Docket createRestApi() {
-        return new Docket(DocumentationType.SWAGGER_2)
-            .apiInfo(apiinfo())
-            .enable(true)
-            .globalOperationParameters(jwtToken())
-            .select()
-            .apis(RequestHandlerSelectors.basePackage("org.apache.iotdb.admin.controller"))
-            .paths(PathSelectors.any())
-            .build();
-    }
-
-    private ApiInfo apiinfo() {
-        return new ApiInfoBuilder()
-            .title("IOTDB接口文档")
-            .description("iotDB层级关系 存储组 -> 实体(设备) -> 测点(时间序列)")
-            .build();
-    }
+  @Bean
+  public Docket createRestApi() {
+    return new Docket(DocumentationType.SWAGGER_2)
+        .apiInfo(apiinfo())
+        .enable(true)
+        .globalOperationParameters(jwtToken())
+        .select()
+        .apis(RequestHandlerSelectors.basePackage("org.apache.iotdb.admin.controller"))
+        .paths(PathSelectors.any())
+        .build();
+  }
 
-    private List<Parameter> jwtToken() {
+  private ApiInfo apiinfo() {
+    return new ApiInfoBuilder()
+        .title("IOTDB接口文档")
+        .description("iotDB层级关系 存储组 -> 实体(设备) -> 测点(时间序列)")
+        .build();
+  }
 
-        ParameterBuilder tokenPar = new ParameterBuilder();
-        List<Parameter> pars = new ArrayList<>();
-        tokenPar.name("Authorization")
-            .description("jwt令牌")
-            .modelRef(new ModelRef("string"))
-            .parameterType("header")
-            .required(false);
-        pars.add(tokenPar.build());
-        return pars;
-    }
+  private List<Parameter> jwtToken() {
 
+    ParameterBuilder tokenPar = new ParameterBuilder();
+    List<Parameter> pars = new ArrayList<>();
+    tokenPar
+        .name("Authorization")
+        .description("jwt令牌")
+        .modelRef(new ModelRef("string"))
+        .parameterType("header")
+        .required(false);
+    pars.add(tokenPar.build());
+    return pars;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java b/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
index ff63d55..4a7653f 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/config/ValidatorConfiguration.java
@@ -27,15 +27,17 @@ import javax.validation.Validation;
 import javax.validation.Validator;
 import javax.validation.ValidatorFactory;
 
-/**
- * 校验框架配置类
- */
+/** 校验框架配置类 */
 @Configuration
 public class ValidatorConfiguration {
 
-    @Bean("validator")
-    public Validator getValidatorFactory() {
-        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory();
-        return validatorFactory.getValidator();
-    }
+  @Bean("validator")
+  public Validator getValidatorFactory() {
+    ValidatorFactory validatorFactory =
+        Validation.byProvider(HibernateValidator.class)
+            .configure()
+            .failFast(true)
+            .buildValidatorFactory();
+    return validatorFactory.getValidator();
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
index 71dbdd3..90086d1 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/ConnectionController.java
@@ -19,8 +19,6 @@
 
 package org.apache.iotdb.admin.controller;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
@@ -31,10 +29,14 @@ import org.apache.iotdb.admin.model.vo.ConnVO;
 import org.apache.iotdb.admin.model.vo.ConnectionVO;
 import org.apache.iotdb.admin.service.ConnectionService;
 import org.apache.iotdb.session.Session;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.util.List;
@@ -43,83 +45,84 @@ import java.util.List;
 @Api(value = "连接相关接口")
 public class ConnectionController {
 
-    @Autowired
-    private ConnectionService connectionService;
-
-    @PostMapping("/servers")
-    @ApiOperation("保存或更新连接")
-    public BaseVO saveOrUpdateConnection(@RequestBody Connection connection, HttpServletRequest request) throws BaseException {
-        AuthenticationUtils.userAuthentication(connection.getUserId(), request);
-        if (connection.getId() != null) {
-            connectionService.update(connection);
-            return BaseVO.success("更新成功", null);
-        }
-        connectionService.insert(connection);
+  @Autowired private ConnectionService connectionService;
 
-        return BaseVO.success("保存成功", null);
+  @PostMapping("/servers")
+  @ApiOperation("保存或更新连接")
+  public BaseVO saveOrUpdateConnection(
+      @RequestBody Connection connection, HttpServletRequest request) throws BaseException {
+    AuthenticationUtils.userAuthentication(connection.getUserId(), request);
+    if (connection.getId() != null) {
+      connectionService.update(connection);
+      return BaseVO.success("更新成功", null);
     }
+    connectionService.insert(connection);
 
-    @DeleteMapping("/servers/{serverId}")
-    @ApiOperation("删除连接")
-    public BaseVO deleteConnection(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
-        Integer userId = AuthenticationUtils.getUserId(request);
-        connectionService.check(serverId, userId);
-        connectionService.deleteById(serverId, userId);
-        return BaseVO.success("删除成功", null);
-    }
+    return BaseVO.success("保存成功", null);
+  }
 
-    @GetMapping("/servers/{serverId}")
-    @ApiOperation("获取连接具体配置")
-    public BaseVO<Connection> getConnection(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
-        Integer userId = AuthenticationUtils.getUserId(request);
-        connectionService.check(serverId, userId);
-        return BaseVO.success("获取成功", connectionService.getById(serverId));
-    }
+  @DeleteMapping("/servers/{serverId}")
+  @ApiOperation("删除连接")
+  public BaseVO deleteConnection(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
+    connectionService.deleteById(serverId, userId);
+    return BaseVO.success("删除成功", null);
+  }
 
-    @GetMapping("/servers")
-    @ApiOperation("获取所有连接")
-    public BaseVO<ConnectionVO> getAllConnections(@RequestParam("userId") Integer userId, HttpServletRequest request) throws BaseException {
-        AuthenticationUtils.userAuthentication(userId, request);
-        List<ConnVO> connVOs = connectionService.getAllConnections(userId);
-        ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, null);
-        return BaseVO.success("获取成功", connectionVO);
-    }
+  @GetMapping("/servers/{serverId}")
+  @ApiOperation("获取连接具体配置")
+  public BaseVO<Connection> getConnection(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
+    return BaseVO.success("获取成功", connectionService.getById(serverId));
+  }
+
+  @GetMapping("/servers")
+  @ApiOperation("获取所有连接")
+  public BaseVO<ConnectionVO> getAllConnections(
+      @RequestParam("userId") Integer userId, HttpServletRequest request) throws BaseException {
+    AuthenticationUtils.userAuthentication(userId, request);
+    List<ConnVO> connVOs = connectionService.getAllConnections(userId);
+    ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, null);
+    return BaseVO.success("获取成功", connectionVO);
+  }
 
-    @PostMapping("/test")
-    @ApiOperation("连通性测试")
-    public BaseVO testConnection(@RequestBody ConnectionDTO conn) throws BaseException {
-        Socket socket = null;
-        try {
-            socket = new Socket();
-            socket.connect(new InetSocketAddress(conn.getHost(), conn.getPort()), 5000);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.TEST_CONN_FAIL, ErrorCode.TEST_CONN_FAIL_MSG);
-        } finally {
-            try {
-                if (socket != null) {
-                    socket.close();
-                }
-            } catch (Exception e) {
-                throw new BaseException(ErrorCode.TEST_CONN_FAIL, ErrorCode.TEST_CONN_FAIL_MSG);
-            }
+  @PostMapping("/test")
+  @ApiOperation("连通性测试")
+  public BaseVO testConnection(@RequestBody ConnectionDTO conn) throws BaseException {
+    Socket socket = null;
+    try {
+      socket = new Socket();
+      socket.connect(new InetSocketAddress(conn.getHost(), conn.getPort()), 5000);
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.TEST_CONN_FAIL, ErrorCode.TEST_CONN_FAIL_MSG);
+    } finally {
+      try {
+        if (socket != null) {
+          socket.close();
         }
-        Session session = null;
-        try {
-            session = new Session(conn.getHost(), conn.getPort(), conn.getUsername(), conn.getPassword());
-            session.open();
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
-        } finally {
-            try {
-                if (session != null) {
-                    session.close();
-                }
-            } catch (Exception e) {
-                throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
-            }
+      } catch (Exception e) {
+        throw new BaseException(ErrorCode.TEST_CONN_FAIL, ErrorCode.TEST_CONN_FAIL_MSG);
+      }
+    }
+    Session session = null;
+    try {
+      session = new Session(conn.getHost(), conn.getPort(), conn.getUsername(), conn.getPassword());
+      session.open();
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
+    } finally {
+      try {
+        if (session != null) {
+          session.close();
         }
-        return BaseVO.success("连通成功", null);
+      } catch (Exception e) {
+        throw new BaseException(ErrorCode.TEST_CONN_FAIL_PWD, ErrorCode.TEST_CONN_FAIL_PWD_MSG);
+      }
     }
-
-
+    return BaseVO.success("连通成功", null);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
index 62efb35..dbc4cd7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/HealthController.java
@@ -19,33 +19,28 @@
 
 package org.apache.iotdb.admin.controller;
 
-import java.io.IOException;
-import javax.servlet.http.HttpServletResponse;
 import org.apache.iotdb.admin.common.exception.BaseException;
+
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
 
-/**
- * 运维平台通过存活、就绪探针表示应用是否存活,就绪。这个类大家最好不好删除,url地址也不要改变
- */
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+
+/** 运维平台通过存活、就绪探针表示应用是否存活,就绪。这个类大家最好不好删除,url地址也不要改变 */
 @Controller
 public class HealthController {
 
-    /**
-     * 存活探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示存活,
-     * 如果多次返回500,则表示这个程序已经死了,会重启这个程序。
-     */
-    @GetMapping(value = "/healthz/liveness")
-    public void liveness(HttpServletResponse response) throws IOException, BaseException {
-        response.setStatus(HttpServletResponse.SC_OK);
-    }
-
-    /**
-     * 就绪探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示程序已经可用,
-     * 如果多次返回500,则表示这个程序未启动成功,会重启这个程序。
-     */
-    @GetMapping(value = "/healthz/readiness")
-    public void readiness(HttpServletResponse response) throws IOException {
-        response.setStatus(HttpServletResponse.SC_OK);
-    }
+  /** 存活探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示存活, 如果多次返回500,则表示这个程序已经死了,会重启这个程序。 */
+  @GetMapping(value = "/healthz/liveness")
+  public void liveness(HttpServletResponse response) throws IOException, BaseException {
+    response.setStatus(HttpServletResponse.SC_OK);
+  }
+
+  /** 就绪探针,运维平台会每格一段时间,请求一下这个接口,如果这个接口返回200,那么表示程序已经可用, 如果多次返回500,则表示这个程序未启动成功,会重启这个程序。 */
+  @GetMapping(value = "/healthz/readiness")
+  public void readiness(HttpServletResponse response) throws IOException {
+    response.setStatus(HttpServletResponse.SC_OK);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
index 8153022..5c4e86c 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
@@ -19,8 +19,6 @@
 
 package org.apache.iotdb.admin.controller;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
@@ -30,11 +28,15 @@ import org.apache.iotdb.admin.model.entity.Device;
 import org.apache.iotdb.admin.model.entity.StorageGroup;
 import org.apache.iotdb.admin.model.vo.*;
 import org.apache.iotdb.admin.service.*;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -45,823 +47,869 @@ import java.util.List;
 @RequestMapping("/servers/{serverId}")
 public class IotDBController {
 
-    @Autowired
-    private ConnectionService connectionService;
-
-    @Autowired
-    private IotDBService iotDBService;
+  @Autowired private ConnectionService connectionService;
 
-    @Autowired
-    private GroupService groupService;
+  @Autowired private IotDBService iotDBService;
 
-    @Autowired
-    private DeviceService deviceService;
+  @Autowired private GroupService groupService;
 
-    @Autowired
-    private MeasurementService measurementService;
+  @Autowired private DeviceService deviceService;
 
+  @Autowired private MeasurementService measurementService;
 
-    @GetMapping("/storageGroups/info")
-    @ApiOperation("获得存储组信息列表")
-    public BaseVO<List<GroupInfoVO>> getAllStorageGroupsInfo(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        List<String> groupNames = iotDBService.getAllStorageGroups(connection);
-        List<GroupInfoVO> groupInfoList = new ArrayList<>();
-        if (groupNames == null || groupNames.size() == 0) {
-            return BaseVO.success("获取成功", groupInfoList);
-        }
-        String host = connection.getHost();
-        List<Integer> deviceCounts = iotDBService.getDevicesCount(connection, groupNames);
-        List<String> descriptions = groupService.getGroupDescription(host, groupNames);
-        for (int i = 0; i < groupNames.size(); i++) {
-            GroupInfoVO groupInfoVO = new GroupInfoVO();
-            groupInfoVO.setGroupName(groupNames.get(i).replaceFirst("root.", ""));
-            groupInfoVO.setDeviceCount(deviceCounts.get(i));
-            groupInfoVO.setDescription(descriptions.get(i));
-            groupInfoList.add(groupInfoVO);
+  @GetMapping("/storageGroups/info")
+  @ApiOperation("获得存储组信息列表")
+  public BaseVO<List<GroupInfoVO>> getAllStorageGroupsInfo(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<String> groupNames = iotDBService.getAllStorageGroups(connection);
+    List<GroupInfoVO> groupInfoList = new ArrayList<>();
+    if (groupNames == null || groupNames.size() == 0) {
+      return BaseVO.success("获取成功", groupInfoList);
+    }
+    String host = connection.getHost();
+    List<Integer> deviceCounts = iotDBService.getDevicesCount(connection, groupNames);
+    List<String> descriptions = groupService.getGroupDescription(host, groupNames);
+    for (int i = 0; i < groupNames.size(); i++) {
+      GroupInfoVO groupInfoVO = new GroupInfoVO();
+      groupInfoVO.setGroupName(groupNames.get(i).replaceFirst("root.", ""));
+      groupInfoVO.setDeviceCount(deviceCounts.get(i));
+      groupInfoVO.setDescription(descriptions.get(i));
+      groupInfoList.add(groupInfoVO);
+    }
+    return BaseVO.success("获取成功", groupInfoList);
+  }
+
+  @GetMapping("/storageGroups")
+  @ApiOperation("获得存储组列表")
+  public BaseVO<List<StorageGroupVO>> getAllStorageGroups(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<StorageGroupVO> storageGroupVOList = new ArrayList<>();
+    List<String> groupNames = iotDBService.getAllStorageGroups(connection);
+    if (groupNames == null || groupNames.size() == 0) {
+      return BaseVO.success("获取成功", storageGroupVOList);
+    }
+    String host = connection.getHost();
+    for (String groupName : groupNames) {
+      StorageGroupVO storageGroupVO = new StorageGroupVO();
+      Integer id = groupService.getGroupId(host, groupName);
+      storageGroupVO.setGroupId(id);
+      groupName = groupName.replaceFirst("root.", "");
+      storageGroupVO.setGroupName(groupName);
+      storageGroupVOList.add(storageGroupVO);
+    }
+    return BaseVO.success("获取成功", storageGroupVOList);
+  }
+
+  @PostMapping("/storageGroups")
+  @ApiOperation("新增或修改存储组")
+  public BaseVO saveStorageGroup(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody GroupDTO groupDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    String groupName = groupDTO.getGroupName();
+    String checkName = groupName.toLowerCase();
+    if (checkName.contains("root")) {
+      throw new BaseException(ErrorCode.NO_SUP_CONTAIN_ROOT, ErrorCode.NO_SUP_CONTAIN_ROOT_MSG);
+    }
+    groupName = "root." + groupName;
+    Long ttl = groupDTO.getTtl();
+    String ttlUnit = groupDTO.getTtlUnit();
+    Integer groupId = groupDTO.getGroupId();
+    groupDTO.setGroupName(groupName);
+
+    List<String> groupNames = iotDBService.getAllStorageGroups(connection);
+    if (groupId == null) {
+      if (!groupNames.contains(groupDTO.getGroupName())) {
+        iotDBService.saveStorageGroup(connection, groupName);
+      }
+      groupService.setStorageGroupInfo(connection, groupDTO);
+    } else {
+      groupService.updateStorageGroupInfo(connection, groupDTO);
+    }
+    if (ttl != null && ttlUnit != null) {
+      if (ttl >= 0) {
+        Long times = switchTime(ttlUnit);
+        iotDBService.saveGroupTtl(connection, groupName, ttl * times);
+      } else {
+        throw new BaseException(ErrorCode.TTL_WRONG, ErrorCode.TTL_WRONG_MSG);
+      }
+    } else {
+      if (ttl == null && ttlUnit == null) {
+        iotDBService.cancelGroupTtl(connection, groupName);
+      } else {
+        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+      }
+    }
+    return BaseVO.success("新增或更新成功", null);
+  }
+
+  @DeleteMapping("/storageGroups/{groupName}")
+  @ApiOperation("删除存储组")
+  public BaseVO deleteStorageGroup(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    String host = connection.getHost();
+    iotDBService.deleteStorageGroup(connection, groupName);
+    groupService.deleteGroupInfo(host, groupName);
+    deviceService.deleteDeviceInfo(host, groupName);
+    measurementService.deleteMeasurementInfo(host, groupName);
+    return BaseVO.success("删除成功", null);
+  }
+
+  @GetMapping("/storageGroups/{groupName}")
+  @ApiOperation("存储组详情获取")
+  public BaseVO<GroupVO> getStorageGroup(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    String host = connection.getHost();
+    StorageGroup group = groupService.getGroupInfo(host, groupName);
+    String ttl = iotDBService.getGroupTTL(connection, groupName);
+    String ttlUnit;
+    GroupVO groupVO = new GroupVO();
+    if (ttl != null && !"null".equalsIgnoreCase(ttl)) {
+      Long totalTime = Long.valueOf(ttl);
+      ttlUnit = getTTL(totalTime);
+      Long times = switchTime(ttlUnit);
+      ttl = String.valueOf(totalTime / times);
+      groupVO.setTtl(ttl);
+      groupVO.setTtiUnit(ttlUnit);
+    } else {
+      groupVO.setTtl(null);
+    }
+    if (group != null) {
+      groupVO.setCreator(group.getCreator());
+      groupVO.setDescription(group.getDescription());
+      Date date = new Date(group.getCreateTime());
+      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+      String createTime = simpleDateFormat.format(date);
+      groupVO.setCreateTime(createTime);
+    }
+    groupVO.setGroupName(groupName.replaceFirst("root.", ""));
+    groupVO.setAlias(connection.getAlias());
+    return BaseVO.success("获取成功", groupVO);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/info")
+  @ApiOperation("获取指定存储组下的实体(设备)信息列表")
+  public BaseVO<DeviceInfoVO> getDevicesInfoByGroupName(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @RequestParam("pageSize") Integer pageSize,
+      @RequestParam("pageNum") Integer pageNum,
+      @RequestParam(value = "keyword", required = false) String keyword,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    if (pageSize == null || pageNum == null) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    CountDTO countDTO =
+        iotDBService.getDevicesByGroup(connection, groupName, pageSize, pageNum, keyword);
+    List<String> deviceNames = countDTO.getObjects();
+    DeviceInfoVO deviceInfoVO = new DeviceInfoVO();
+    Integer totalPage = countDTO.getTotalPage();
+    Integer totalCount = countDTO.getTotalCount();
+    deviceInfoVO.setTotalCount(totalCount);
+    deviceInfoVO.setTotalPage(totalPage);
+    List<Integer> lines = iotDBService.getTimeseriesCount(connection, deviceNames);
+    List<Device> devices = deviceService.getDevices(connection.getHost(), deviceNames);
+    List<DeviceInfo> deviceInfos = new ArrayList<>();
+    if (deviceNames != null) {
+      for (int i = 0; i < deviceNames.size(); i++) {
+        String deviceName = deviceNames.get(i);
+        if (groupName.equals(deviceName)) {
+          continue;
+        }
+        DeviceInfo deviceInfo = new DeviceInfo();
+        deviceInfo.setDeviceName(deviceName.replaceFirst(groupName + ".", ""));
+        deviceInfo.setLine(lines.get(i));
+        if (devices.get(i) != null) {
+          deviceInfo.setDeviceId(devices.get(i).getId());
+          deviceInfo.setCreator(devices.get(i).getCreator());
+          deviceInfo.setDescription(devices.get(i).getDescription());
+        }
+        deviceInfos.add(deviceInfo);
+      }
+    }
+    deviceInfoVO.setDeviceInfos(deviceInfos);
+    return BaseVO.success("获取成功", deviceInfoVO);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices")
+  @ApiOperation("获取指定存储组下的实体(设备)列表")
+  public BaseVO<List<String>> getDevicesByGroupName(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    List<String> deviceNamesStr = iotDBService.getDevices(connection, groupName);
+    List<String> deviceNames = new ArrayList<>();
+    for (String s : deviceNamesStr) {
+      String deviceName;
+      if (groupName.equals(s)) {
+        continue;
+      } else {
+        deviceName = s.replaceFirst(groupName + ".", "");
+      }
+      deviceNames.add(deviceName);
+    }
+    return BaseVO.success("获取成功", deviceNames);
+  }
+
+  @PostMapping("/storageGroups/{groupName}/devices")
+  @ApiOperation("新增或编辑实体(设备)")
+  public BaseVO<List<String>> saveOrUpdateDevice(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @RequestBody DeviceInfoDTO deviceInfoDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    if (deviceInfoDTO.getDeviceDTOList() == null || deviceInfoDTO.getDeviceDTOList().size() == 0) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceInfoDTO.setDeviceName(groupName + "." + deviceInfoDTO.getDeviceName());
+    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+      deviceDTO.setTimeseries(deviceInfoDTO.getDeviceName() + "." + deviceDTO.getTimeseries());
+    }
+    String host = connection.getHost();
+    iotDBService.createDeviceWithMeasurements(connection, deviceInfoDTO);
+    if (deviceInfoDTO.getDeviceId() == null) {
+      deviceService.setDeviceInfo(connection, deviceInfoDTO);
+      measurementService.setMeasurementsInfo(host, deviceInfoDTO);
+    } else {
+      deviceService.updateDeviceInfo(deviceInfoDTO);
+      measurementService.updateMeasurementsInfo(host, deviceInfoDTO);
+    }
+    return BaseVO.success("新增或更新成功", null);
+  }
+
+  @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}")
+  @ApiOperation("删除实体(设备)")
+  public BaseVO deleteDevice(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    String host = connection.getHost();
+    iotDBService.deleteTimeseriesByDevice(connection, deviceName);
+    deviceService.deleteDeviceInfoByDeviceName(host, deviceName);
+    measurementService.deleteMeasurementInfoByDeviceName(host, deviceName);
+    return BaseVO.success("删除成功", null);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}")
+  @ApiOperation("获取实体(设备)详情")
+  public BaseVO<DeviceVO> getDeviceInfo(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    String host = connection.getHost();
+    DeviceVO deviceVO = deviceService.getDevice(host, deviceName);
+    return BaseVO.success("获取成功", deviceVO);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/info")
+  @ApiOperation("获取指定实体(设备)下的物理量列表详情")
+  public BaseVO<MeasuremtnInfoVO> getMeasurementsByDeviceName(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @RequestParam("pageSize") Integer pageSize,
+      @RequestParam("pageNum") Integer pageNum,
+      @RequestParam(value = "keyword", required = false) String keyword,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    CountDTO countDTO =
+        iotDBService.getMeasurementsByDevice(connection, deviceName, pageSize, pageNum, keyword);
+    List<MeasurementDTO> measurementDTOList = countDTO.getObjects();
+    List<MeasurementVO> measurementVOList = new ArrayList<>();
+    String host = connection.getHost();
+    if (measurementDTOList != null) {
+      for (MeasurementDTO measurementDTO : measurementDTOList) {
+        MeasurementVO measurementVO = new MeasurementVO();
+        BeanUtils.copyProperties(measurementDTO, measurementVO);
+        if (measurementVO.getTimeseries() != null) {
+          measurementVO.setTimeseries(
+              measurementVO.getTimeseries().replaceFirst(deviceName + ".", ""));
+        }
+        String description =
+            measurementService.getDescription(host, measurementDTO.getTimeseries());
+        String newValue =
+            iotDBService.getLastMeasurementValue(connection, measurementDTO.getTimeseries());
+        measurementVO.setNewValue(newValue);
+        measurementVO.setDescription(description);
+        measurementVOList.add(measurementVO);
+      }
+    }
+    MeasuremtnInfoVO measuremtnInfoVO = new MeasuremtnInfoVO();
+    measuremtnInfoVO.setTotalCount(countDTO.getTotalCount());
+    measuremtnInfoVO.setTotalPage(countDTO.getTotalPage());
+    measuremtnInfoVO.setMeasurementVOList(measurementVOList);
+    return BaseVO.success("获取成功", measuremtnInfoVO);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
+  @ApiOperation("获取指定物理量的最新两百条数据记录")
+  public BaseVO<RecordVO> getMeasurementInfo(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @PathVariable("timeseriesName") String timeseriesName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (groupName == null || !groupName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    RecordVO recordVO = iotDBService.getRecords(connection, deviceName, timeseriesName);
+    return BaseVO.success("获取成功", recordVO);
+  }
+
+  @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
+  @ApiOperation("创建时间序列  (未使用)")
+  public BaseVO insertTimeseries(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @RequestBody Timeseries timeseries,
+      HttpServletRequest request)
+      throws BaseException {
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    iotDBService.insertTimeseries(connection, deviceName, timeseries);
+    return BaseVO.success("创建成功", null);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/info")
+  @ApiOperation("指定设备下的所有物理量  (未使用)")
+  public BaseVO<SqlResultVO> showTimeseries(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    SqlResultVO resultVO = iotDBService.showTimeseries(connection, deviceName);
+    return BaseVO.success("获取成功", resultVO);
+  }
+
+  @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
+  @ApiOperation("指定设备下的物理量列表")
+  public BaseVO<List<String>> getTimeseries(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    List<String> timeseriesStr = iotDBService.getTimeseries(connection, deviceName);
+    List<String> timeseries = new ArrayList<>();
+    for (String s : timeseriesStr) {
+      timeseries.add(s.replaceFirst(deviceName + ".", ""));
+    }
+    return BaseVO.success("获取成功", timeseries);
+  }
+
+  @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
+  @ApiOperation("删除物理量")
+  public BaseVO deleteTimeseries(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("groupName") String groupName,
+      @PathVariable("deviceName") String deviceName,
+      @PathVariable("timeseriesName") String timeseriesName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (timeseriesName == null || !timeseriesName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    groupName = "root." + groupName;
+    deviceName = groupName + "." + deviceName;
+    timeseriesName = deviceName + "." + timeseriesName;
+    iotDBService.deleteTimeseries(connection, timeseriesName);
+    String host = connection.getHost();
+    measurementService.deleteMeasurementInfo(host, timeseriesName);
+    return BaseVO.success("删除成功", null);
+  }
+
+  @GetMapping("/users")
+  @ApiOperation("获取数据库用户列表")
+  public BaseVO<List<String>> getIotDBUserList(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<String> users = iotDBService.getIotDBUserList(connection);
+    String username = connection.getUsername();
+    if (users == null) {
+      users = new ArrayList<>();
+      users.add(username);
+      return BaseVO.success("获取成功", users);
+    }
+    // 前端需要将当前用户处于列表第一位
+    List<String> newUsers = new ArrayList<>();
+    newUsers.add(username);
+    for (String user : users) {
+      if (username.equalsIgnoreCase(user)) {
+        continue;
+      }
+      newUsers.add(user);
+    }
+    return BaseVO.success("获取成功", newUsers);
+  }
+
+  @GetMapping("/roles")
+  @ApiOperation("获取数据库角色列表   (未使用)")
+  public BaseVO<List<String>> getIotDBRoleList(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    List<String> roles = iotDBService.getIotDBRoleList(connection);
+    return BaseVO.success("获取成功", roles);
+  }
+
+  @GetMapping("/users/{userName}")
+  @ApiOperation("获取数据源用户的具体信息或其他用户的权限信息")
+  public BaseVO<IotDBUserVO> getIotDBUser(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (userName == null || !userName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    IotDBUserVO iotDBUserVO = iotDBService.getIotDBUser(connection, userName);
+    return BaseVO.success("获取成功", iotDBUserVO);
+  }
+
+  @PostMapping("/users/{userName}")
+  @ApiOperation("数据库用户赋权")
+  public BaseVO setUserPrivileges(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      @RequestBody PrivilegeInfoDTO privilegeInfoDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    if (userName == null || !userName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    if (privilegeInfoDTO == null) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    Integer type = privilegeInfoDTO.getType();
+    if (type != null && (type > 3 || type < 0)) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    //        Integer delType = pathCheckAndGetDelType(privilegeInfoDTO);
+    pathCheck(privilegeInfoDTO);
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.setUserPrivileges(connection, userName, privilegeInfoDTO);
+    return BaseVO.success("操作成功", null);
+  }
+
+  private void pathCheck(PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
+    Integer type = privilegeInfoDTO.getType();
+    List<String> groupPaths = privilegeInfoDTO.getGroupPaths();
+    List<String> devicePaths = privilegeInfoDTO.getDevicePaths();
+    List<String> timeseriesPaths = privilegeInfoDTO.getTimeseriesPaths();
+    List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
+    List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
+    List<String> delTimeseriesPaths = privilegeInfoDTO.getDelTimeseriesPaths();
+    if (type == null) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    switch (type) {
+      case 0:
+        if (groupPaths != null && groupPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        return BaseVO.success("获取成功", groupInfoList);
-    }
-
-    @GetMapping("/storageGroups")
-    @ApiOperation("获得存储组列表")
-    public BaseVO<List<StorageGroupVO>> getAllStorageGroups(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        List<StorageGroupVO> storageGroupVOList = new ArrayList<>();
-        List<String> groupNames = iotDBService.getAllStorageGroups(connection);
-        if (groupNames == null || groupNames.size() == 0) {
-            return BaseVO.success("获取成功", storageGroupVOList);
+        if (devicePaths != null && devicePaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        String host = connection.getHost();
-        for (String groupName : groupNames) {
-            StorageGroupVO storageGroupVO = new StorageGroupVO();
-            Integer id = groupService.getGroupId(host, groupName);
-            storageGroupVO.setGroupId(id);
-            groupName = groupName.replaceFirst("root.", "");
-            storageGroupVO.setGroupName(groupName);
-            storageGroupVOList.add(storageGroupVO);
+        if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        return BaseVO.success("获取成功", storageGroupVOList);
-    }
-
-    @PostMapping("/storageGroups")
-    @ApiOperation("新增或修改存储组")
-    public BaseVO saveStorageGroup(@PathVariable("serverId") Integer serverId,
-        @RequestBody GroupDTO groupDTO,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        String groupName = groupDTO.getGroupName();
-        String checkName = groupName.toLowerCase();
-        if (checkName.contains("root")) {
-            throw new BaseException(ErrorCode.NO_SUP_CONTAIN_ROOT, ErrorCode.NO_SUP_CONTAIN_ROOT_MSG);
+        if (delDevicePaths != null && delDevicePaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        groupName = "root." + groupName;
-        Long ttl = groupDTO.getTtl();
-        String ttlUnit = groupDTO.getTtlUnit();
-        Integer groupId = groupDTO.getGroupId();
-        groupDTO.setGroupName(groupName);
-
-        List<String> groupNames = iotDBService.getAllStorageGroups(connection);
-        if (groupId == null) {
-            if (!groupNames.contains(groupDTO.getGroupName())) {
-                iotDBService.saveStorageGroup(connection, groupName);
-            }
-            groupService.setStorageGroupInfo(connection, groupDTO);
-        } else {
-            groupService.updateStorageGroupInfo(connection, groupDTO);
+        if (delGroupPaths != null && delGroupPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        if (ttl != null && ttlUnit != null) {
-            if (ttl >= 0) {
-                Long times = switchTime(ttlUnit);
-                iotDBService.saveGroupTtl(connection, groupName, ttl * times);
-            } else {
-                throw new BaseException(ErrorCode.TTL_WRONG, ErrorCode.TTL_WRONG_MSG);
-            }
-        } else {
-            if (ttl == null && ttlUnit == null) {
-                iotDBService.cancelGroupTtl(connection, groupName);
-            } else {
-                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-            }
+        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        return BaseVO.success("新增或更新成功", null);
-    }
-
-    @DeleteMapping("/storageGroups/{groupName}")
-    @ApiOperation("删除存储组")
-    public BaseVO deleteStorageGroup(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
-            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        break;
+      case 1:
+        if (devicePaths != null && devicePaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        String host = connection.getHost();
-        iotDBService.deleteStorageGroup(connection, groupName);
-        groupService.deleteGroupInfo(host, groupName);
-        deviceService.deleteDeviceInfo(host, groupName);
-        measurementService.deleteMeasurementInfo(host, groupName);
-        return BaseVO.success("删除成功", null);
-    }
-
-    @GetMapping("/storageGroups/{groupName}")
-    @ApiOperation("存储组详情获取")
-    public BaseVO<GroupVO> getStorageGroup(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
-            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        String host = connection.getHost();
-        StorageGroup group = groupService.getGroupInfo(host, groupName);
-        String ttl = iotDBService.getGroupTTL(connection, groupName);
-        String ttlUnit;
-        GroupVO groupVO = new GroupVO();
-        if (ttl != null && !"null".equalsIgnoreCase(ttl)) {
-            Long totalTime = Long.valueOf(ttl);
-            ttlUnit = getTTL(totalTime);
-            Long times = switchTime(ttlUnit);
-            ttl = String.valueOf(totalTime / times);
-            groupVO.setTtl(ttl);
-            groupVO.setTtiUnit(ttlUnit);
-        } else {
-            groupVO.setTtl(null);
+        if (delDevicePaths != null && delDevicePaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        if (group != null) {
-            groupVO.setCreator(group.getCreator());
-            groupVO.setDescription(group.getDescription());
-            Date date = new Date(group.getCreateTime());
-            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
-            String createTime = simpleDateFormat.format(date);
-            groupVO.setCreateTime(createTime);
+        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        groupVO.setGroupName(groupName.replaceFirst("root.", ""));
-        groupVO.setAlias(connection.getAlias());
-        return BaseVO.success("获取成功", groupVO);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices/info")
-    @ApiOperation("获取指定存储组下的实体(设备)信息列表")
-    public BaseVO<DeviceInfoVO> getDevicesInfoByGroupName(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @RequestParam("pageSize") Integer pageSize,
-        @RequestParam("pageNum") Integer pageNum,
-        @RequestParam(value = "keyword", required = false) String keyword,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+        break;
+      case 2:
+        if (groupPaths != null && groupPaths.size() > 0) {
+          if (groupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        if (pageSize == null || pageNum == null) {
+          }
+          if (devicePaths == null || devicePaths.size() == 0) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        CountDTO countDTO = iotDBService.getDevicesByGroup(connection, groupName, pageSize, pageNum, keyword);
-        List<String> deviceNames = countDTO.getObjects();
-        DeviceInfoVO deviceInfoVO = new DeviceInfoVO();
-        Integer totalPage = countDTO.getTotalPage();
-        Integer totalCount = countDTO.getTotalCount();
-        deviceInfoVO.setTotalCount(totalCount);
-        deviceInfoVO.setTotalPage(totalPage);
-        List<Integer> lines = iotDBService.getTimeseriesCount(connection, deviceNames);
-        List<Device> devices = deviceService.getDevices(connection.getHost(), deviceNames);
-        List<DeviceInfo> deviceInfos = new ArrayList<>();
-        if (deviceNames != null) {
-            for (int i = 0; i < deviceNames.size(); i++) {
-                String deviceName = deviceNames.get(i);
-                if (groupName.equals(deviceName)) {
-                    continue;
-                }
-                DeviceInfo deviceInfo = new DeviceInfo();
-                deviceInfo.setDeviceName(deviceName.replaceFirst(groupName + ".", ""));
-                deviceInfo.setLine(lines.get(i));
-                if (devices.get(i) != null) {
-                    deviceInfo.setDeviceId(devices.get(i).getId());
-                    deviceInfo.setCreator(devices.get(i).getCreator());
-                    deviceInfo.setDescription(devices.get(i).getDescription());
-                }
-                deviceInfos.add(deviceInfo);
-            }
-        }
-        deviceInfoVO.setDeviceInfos(deviceInfos);
-        return BaseVO.success("获取成功", deviceInfoVO);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices")
-    @ApiOperation("获取指定存储组下的实体(设备)列表")
-    public BaseVO<List<String>> getDevicesByGroupName(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+        if (devicePaths != null && devicePaths.size() > 0) {
+          if (groupPaths == null || groupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        List<String> deviceNamesStr = iotDBService.getDevices(connection, groupName);
-        List<String> deviceNames = new ArrayList<>();
-        for (String s : deviceNamesStr) {
-            String deviceName;
-            if (groupName.equals(s)) {
-                continue;
-            } else {
-                deviceName = s.replaceFirst(groupName + ".", "");
-            }
-            deviceNames.add(deviceName);
+        if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        return BaseVO.success("获取成功", deviceNames);
-    }
-
-    @PostMapping("/storageGroups/{groupName}/devices")
-    @ApiOperation("新增或编辑实体(设备)")
-    public BaseVO<List<String>> saveOrUpdateDevice(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @RequestBody DeviceInfoDTO deviceInfoDTO,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+        if (delGroupPaths != null && delGroupPaths.size() > 0) {
+          if (delGroupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        if (deviceInfoDTO.getDeviceDTOList() == null || deviceInfoDTO.getDeviceDTOList().size() == 0) {
+          }
+          if (delDevicePaths == null || delDevicePaths.size() == 0) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceInfoDTO.setDeviceName(groupName + "." + deviceInfoDTO.getDeviceName());
-        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
-            deviceDTO.setTimeseries(deviceInfoDTO.getDeviceName() + "." + deviceDTO.getTimeseries());
-        }
-        String host = connection.getHost();
-        iotDBService.createDeviceWithMeasurements(connection, deviceInfoDTO);
-        if (deviceInfoDTO.getDeviceId() == null) {
-            deviceService.setDeviceInfo(connection, deviceInfoDTO);
-            measurementService.setMeasurementsInfo(host, deviceInfoDTO);
-        } else {
-            deviceService.updateDeviceInfo(deviceInfoDTO);
-            measurementService.updateMeasurementsInfo(host, deviceInfoDTO);
-        }
-        return BaseVO.success("新增或更新成功", null);
-    }
-
-
-    @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}")
-    @ApiOperation("删除实体(设备)")
-    public BaseVO deleteDevice(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+        if (delDevicePaths != null && delDevicePaths.size() > 0) {
+          if (delGroupPaths == null || delGroupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
-            throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+          throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        String host = connection.getHost();
-        iotDBService.deleteTimeseriesByDevice(connection, deviceName);
-        deviceService.deleteDeviceInfoByDeviceName(host, deviceName);
-        measurementService.deleteMeasurementInfoByDeviceName(host, deviceName);
-        return BaseVO.success("删除成功", null);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}")
-    @ApiOperation("获取实体(设备)详情")
-    public BaseVO<DeviceVO> getDeviceInfo(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        HttpServletRequest request) throws BaseException {
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+        break;
+      case 3:
+        if (groupPaths != null && groupPaths.size() > 0) {
+          if (groupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        String host = connection.getHost();
-        DeviceVO deviceVO = deviceService.getDevice(host, deviceName);
-        return BaseVO.success("获取成功", deviceVO);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/info")
-    @ApiOperation("获取指定实体(设备)下的物理量列表详情")
-    public BaseVO<MeasuremtnInfoVO> getMeasurementsByDeviceName(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        @RequestParam("pageSize") Integer pageSize,
-        @RequestParam("pageNum") Integer pageNum,
-        @RequestParam(value = "keyword", required = false) String keyword,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+          }
+          if (devicePaths == null || devicePaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+          }
+          if (timeseriesPaths == null || timeseriesPaths.size() == 0) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        CountDTO countDTO = iotDBService.getMeasurementsByDevice(connection, deviceName, pageSize, pageNum, keyword);
-        List<MeasurementDTO> measurementDTOList = countDTO.getObjects();
-        List<MeasurementVO> measurementVOList = new ArrayList<>();
-        String host = connection.getHost();
-        if (measurementDTOList != null) {
-            for (MeasurementDTO measurementDTO : measurementDTOList) {
-                MeasurementVO measurementVO = new MeasurementVO();
-                BeanUtils.copyProperties(measurementDTO, measurementVO);
-                if (measurementVO.getTimeseries() != null) {
-                    measurementVO.setTimeseries(measurementVO.getTimeseries().replaceFirst(deviceName + ".", ""));
-                }
-                String description = measurementService.getDescription(host, measurementDTO.getTimeseries());
-                String newValue = iotDBService.getLastMeasurementValue(connection, measurementDTO.getTimeseries());
-                measurementVO.setNewValue(newValue);
-                measurementVO.setDescription(description);
-                measurementVOList.add(measurementVO);
-            }
-        }
-        MeasuremtnInfoVO measuremtnInfoVO = new MeasuremtnInfoVO();
-        measuremtnInfoVO.setTotalCount(countDTO.getTotalCount());
-        measuremtnInfoVO.setTotalPage(countDTO.getTotalPage());
-        measuremtnInfoVO.setMeasurementVOList(measurementVOList);
-        return BaseVO.success("获取成功", measuremtnInfoVO);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
-    @ApiOperation("获取指定物理量的最新两百条数据记录")
-    public BaseVO<RecordVO> getMeasurementInfo(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        @PathVariable("timeseriesName") String timeseriesName,
-        HttpServletRequest request) throws BaseException {
-        if (groupName == null || !groupName.matches("^[^ ]+$")) {
+        if (devicePaths != null && devicePaths.size() > 0) {
+          if (devicePaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+          }
+          if (groupPaths == null || groupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        RecordVO recordVO = iotDBService.getRecords(connection, deviceName, timeseriesName);
-        return BaseVO.success("获取成功", recordVO);
-    }
-
-    @PostMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
-    @ApiOperation("创建时间序列  (未使用)")
-    public BaseVO insertTimeseries(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        @RequestBody Timeseries timeseries,
-        HttpServletRequest request) throws BaseException {
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+          }
+          if (timeseriesPaths == null || timeseriesPaths.size() == 0) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        iotDBService.insertTimeseries(connection, deviceName, timeseries);
-        return BaseVO.success("创建成功", null);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/info")
-    @ApiOperation("指定设备下的所有物理量  (未使用)")
-    public BaseVO<SqlResultVO> showTimeseries(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        HttpServletRequest request) throws BaseException {
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+        if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
+          if (groupPaths == null || groupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        SqlResultVO resultVO = iotDBService.showTimeseries(connection, deviceName);
-        return BaseVO.success("获取成功", resultVO);
-    }
-
-    @GetMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries")
-    @ApiOperation("指定设备下的物理量列表")
-    public BaseVO<List<String>> getTimeseries(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        HttpServletRequest request) throws BaseException {
-        if (deviceName == null || !deviceName.matches("^[^ ]+$")) {
+          }
+          if (devicePaths == null || devicePaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        List<String> timeseriesStr = iotDBService.getTimeseries(connection, deviceName);
-        List<String> timeseries = new ArrayList<>();
-        for (String s : timeseriesStr) {
-            timeseries.add(s.replaceFirst(deviceName + ".", ""));
-        }
-        return BaseVO.success("获取成功", timeseries);
-    }
-
-    @DeleteMapping("/storageGroups/{groupName}/devices/{deviceName}/timeseries/{timeseriesName}")
-    @ApiOperation("删除物理量")
-    public BaseVO deleteTimeseries(@PathVariable("serverId") Integer serverId,
-        @PathVariable("groupName") String groupName,
-        @PathVariable("deviceName") String deviceName,
-        @PathVariable("timeseriesName") String timeseriesName,
-        HttpServletRequest request) throws BaseException {
-        if (timeseriesName == null || !timeseriesName.matches("^[^ ]+$")) {
+        if (delGroupPaths != null && delGroupPaths.size() > 0) {
+          if (delGroupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        groupName = "root." + groupName;
-        deviceName = groupName + "." + deviceName;
-        timeseriesName = deviceName + "." + timeseriesName;
-        iotDBService.deleteTimeseries(connection, timeseriesName);
-        String host = connection.getHost();
-        measurementService.deleteMeasurementInfo(host, timeseriesName);
-        return BaseVO.success("删除成功", null);
-    }
-
-    @GetMapping("/users")
-    @ApiOperation("获取数据库用户列表")
-    public BaseVO<List<String>> getIotDBUserList(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        List<String> users = iotDBService.getIotDBUserList(connection);
-        String username = connection.getUsername();
-        if (users == null) {
-            users = new ArrayList<>();
-            users.add(username);
-            return BaseVO.success("获取成功", users);
-        }
-        // 前端需要将当前用户处于列表第一位
-        List<String> newUsers = new ArrayList<>();
-        newUsers.add(username);
-        for (String user : users) {
-            if (username.equalsIgnoreCase(user)) {
-                continue;
-            }
-            newUsers.add(user);
-        }
-        return BaseVO.success("获取成功", newUsers);
-    }
-
-    @GetMapping("/roles")
-    @ApiOperation("获取数据库角色列表   (未使用)")
-    public BaseVO<List<String>> getIotDBRoleList(@PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        List<String> roles = iotDBService.getIotDBRoleList(connection);
-        return BaseVO.success("获取成功", roles);
-    }
-
-    @GetMapping("/users/{userName}")
-    @ApiOperation("获取数据源用户的具体信息或其他用户的权限信息")
-    public BaseVO<IotDBUserVO> getIotDBUser(@PathVariable("serverId") Integer serverId,
-        @PathVariable("userName") String userName,
-        HttpServletRequest request) throws BaseException {
-        if (userName == null || !userName.matches("^[^ ]+$")) {
+          }
+          if (delDevicePaths == null || delDevicePaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        IotDBUserVO iotDBUserVO = iotDBService.getIotDBUser(connection, userName);
-        return BaseVO.success("获取成功", iotDBUserVO);
-    }
-
-    @PostMapping("/users/{userName}")
-    @ApiOperation("数据库用户赋权")
-    public BaseVO setUserPrivileges(@PathVariable("serverId") Integer serverId,
-        @PathVariable("userName") String userName,
-        @RequestBody PrivilegeInfoDTO privilegeInfoDTO,
-        HttpServletRequest request) throws BaseException {
-        if (userName == null || !userName.matches("^[^ ]+$")) {
+          }
+          if (delTimeseriesPaths == null || delTimeseriesPaths.size() == 0) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        if (privilegeInfoDTO == null) {
+        if (delDevicePaths != null && delDevicePaths.size() > 0) {
+          if (delDevicePaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        Integer type = privilegeInfoDTO.getType();
-        if (type != null && (type > 3 || type < 0)) {
+          }
+          if (delGroupPaths == null || delGroupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-//        Integer delType = pathCheckAndGetDelType(privilegeInfoDTO);
-        pathCheck(privilegeInfoDTO);
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        iotDBService.setUserPrivileges(connection, userName, privilegeInfoDTO);
-        return BaseVO.success("操作成功", null);
-    }
-
-    private void pathCheck(PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
-        Integer type = privilegeInfoDTO.getType();
-        List<String> groupPaths = privilegeInfoDTO.getGroupPaths();
-        List<String> devicePaths = privilegeInfoDTO.getDevicePaths();
-        List<String> timeseriesPaths = privilegeInfoDTO.getTimeseriesPaths();
-        List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
-        List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
-        List<String> delTimeseriesPaths = privilegeInfoDTO.getDelTimeseriesPaths();
-        if (type == null) {
+          }
+          if (delTimeseriesPaths == null || delTimeseriesPaths.size() == 0) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        switch (type) {
-            case 0:
-                if (groupPaths != null && groupPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (devicePaths != null && devicePaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (delDevicePaths != null && delDevicePaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (delGroupPaths != null && delGroupPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                break;
-            case 1:
-                if (devicePaths != null && devicePaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (delDevicePaths != null && delDevicePaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                break;
-            case 2:
-                if (groupPaths != null && groupPaths.size() > 0) {
-                    if (groupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (devicePaths == null || devicePaths.size() == 0) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (devicePaths != null && devicePaths.size() > 0) {
-                    if (groupPaths == null || groupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                if (delGroupPaths != null && delGroupPaths.size() > 0) {
-                    if (delGroupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (delDevicePaths == null || delDevicePaths.size() == 0) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (delDevicePaths != null && delDevicePaths.size() > 0) {
-                    if (delGroupPaths == null || delGroupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
-                    throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                }
-                break;
-            case 3:
-                if (groupPaths != null && groupPaths.size() > 0) {
-                    if (groupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (devicePaths == null || devicePaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (timeseriesPaths == null || timeseriesPaths.size() == 0) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (devicePaths != null && devicePaths.size() > 0) {
-                    if (devicePaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (groupPaths == null || groupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (timeseriesPaths == null || timeseriesPaths.size() == 0) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (timeseriesPaths != null && timeseriesPaths.size() > 0) {
-                    if (groupPaths == null || groupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (devicePaths == null || devicePaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (delGroupPaths != null && delGroupPaths.size() > 0) {
-                    if (delGroupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (delDevicePaths == null || delDevicePaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (delTimeseriesPaths == null || delTimeseriesPaths.size() == 0) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (delDevicePaths != null && delDevicePaths.size() > 0) {
-                    if (delDevicePaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (delGroupPaths == null || delGroupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (delTimeseriesPaths == null || delTimeseriesPaths.size() == 0) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
-                    if (delGroupPaths == null || delGroupPaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                    if (delDevicePaths == null || delDevicePaths.size() != 1) {
-                        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-                    }
-                }
-                break;
-            default:
-                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-//        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
-//            if (delGroupPaths == null || delGroupPaths.size() != 1) {
-//                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-//            }
-//            if (delDevicePaths == null || delDevicePaths.size() != 1) {
-//                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-//            }
-//            return 3;
-//        }
-//        if (delDevicePaths != null && delDevicePaths.size() > 0) {
-//            if (delGroupPaths == null || delGroupPaths.size() != 1) {
-//                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-//            }
-//            return 2;
-//        }
-//        if (delGroupPaths != null && delGroupPaths.size() > 0) {
-//            return 1;
-//        }
-//        return 0;
-    }
-
-    @PostMapping("/users/pwd")
-    @ApiOperation("改变用户密码")
-    public BaseVO updatePassword(@PathVariable("serverId") Integer serverId,
-        @RequestBody IotDBUser iotDBUser,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        iotDBService.updatePwd(connection, iotDBUser);
-        return BaseVO.success("修改成功", null);
-    }
-
-    @DeleteMapping("/users/{userName}")
-    @ApiOperation("删除数据库用户")
-    public BaseVO deleteIotDBUser(@PathVariable("serverId") Integer serverId,
-        @PathVariable("userName") String userName,
-        HttpServletRequest request) throws BaseException {
-        if (userName == null || !userName.matches("^[^ ]+$")) {
+        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+          if (delGroupPaths == null || delGroupPaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        iotDBService.deleteIotDBUser(connection, userName);
-        return BaseVO.success("删除成功", null);
-    }
-
-    @DeleteMapping("/roles/{roleName}")
-    @ApiOperation("删除数据库角色  (未使用)")
-    public BaseVO deleteIotDBRole(@PathVariable("serverId") Integer serverId,
-        @PathVariable("roleName") String roleName,
-        HttpServletRequest request) throws BaseException {
-        if (roleName == null || roleName.matches("^[^ ]+$")) {
+          }
+          if (delDevicePaths == null || delDevicePaths.size() != 1) {
             throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+          }
         }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        iotDBService.deleteIotDBRole(connection, roleName);
-        return BaseVO.success("删除成功", null);
-    }
-
-    @PostMapping("/users")
-    @ApiOperation("创建数据库用户")
-    public BaseVO setIotDBUser(@PathVariable("serverId") Integer serverId,
-        @RequestBody IotDBUser iotDBUser,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        iotDBService.setIotDBUser(connection, iotDBUser);
-        return BaseVO.success("创建成功", null);
-    }
-
-    @PostMapping("/roles")
-    @ApiOperation("创建数据角色   (未使用)")
-    public BaseVO setIotDBUser(@PathVariable("serverId") Integer serverId,
-        @RequestBody IotDBRole iotDBRole,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        iotDBService.setIotDBRole(connection, iotDBRole);
-        return BaseVO.success("创建成功", null);
-    }
-
-    private void check(HttpServletRequest request, Integer serverId) throws BaseException {
-        Integer userId = AuthenticationUtils.getUserId(request);
-        connectionService.check(serverId, userId);
-    }
-
-
-    private Long switchTime(String ttlUnit) throws BaseException {
-        Long time = 0L;
-        switch (ttlUnit) {
-            case "second":
-                time = 1000L;
-                break;
-            case "minute":
-                time = 60 * 1000L;
-                break;
-            case "hour":
-                time = 60 * 60 * 1000L;
-                break;
-            case "day":
-                time = 24 * 60 * 60 * 1000L;
-                break;
-            case "week":
-                time = 7 * 24 * 60 * 60 * 1000L;
-                break;
-            case "month":
-                time = 30 * 24 * 60 * 60 * 1000L;
-                break;
-            case "year":
-                time = 12 * 30 * 24 * 60 * 60 * 1000L;
-                break;
-            default:
-                throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
-        }
-        return time;
-    }
-
-    private String getTTL(Long time) {
-        long yearTime = 31104000000L;
-        long monthTime = 2592000000L;
-        long weekTime = 604800000L;
-        long dayTime = 86400000L;
-        long hourTime = 3600000L;
-        long minuteTime = 60000L;
-        long secondTime = 1000L;
-        if (time == 0) {
-            return "milliSecond";
-        }
-        if ((time / yearTime != 0) && (time % yearTime == 0)) {
-            return "year";
-        }
-        if ((time / monthTime != 0) && (time % monthTime == 0)) {
-            return "month";
-        }
-        if ((time / weekTime != 0) && (time % weekTime == 0)) {
-            return "week";
-        }
-        if ((time / dayTime != 0) && (time % dayTime == 0)) {
-            return "day";
-        }
-        if ((time / hourTime != 0) && (time % hourTime == 0)) {
-            return "hour";
-        }
-        if ((time / minuteTime != 0) && (time % minuteTime == 0)) {
-            return "minute";
-        }
-        if ((time / secondTime != 0) && (time % secondTime == 0)) {
-            return "second";
-        }
-        return null;
+        break;
+      default:
+        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    //        if (delTimeseriesPaths != null && delTimeseriesPaths.size() > 0) {
+    //            if (delGroupPaths == null || delGroupPaths.size() != 1) {
+    //                throw new BaseException(ErrorCode.WRONG_DB_PARAM,
+    // ErrorCode.WRONG_DB_PARAM_MSG);
+    //            }
+    //            if (delDevicePaths == null || delDevicePaths.size() != 1) {
+    //                throw new BaseException(ErrorCode.WRONG_DB_PARAM,
+    // ErrorCode.WRONG_DB_PARAM_MSG);
+    //            }
+    //            return 3;
+    //        }
+    //        if (delDevicePaths != null && delDevicePaths.size() > 0) {
+    //            if (delGroupPaths == null || delGroupPaths.size() != 1) {
+    //                throw new BaseException(ErrorCode.WRONG_DB_PARAM,
+    // ErrorCode.WRONG_DB_PARAM_MSG);
+    //            }
+    //            return 2;
+    //        }
+    //        if (delGroupPaths != null && delGroupPaths.size() > 0) {
+    //            return 1;
+    //        }
+    //        return 0;
+  }
+
+  @PostMapping("/users/pwd")
+  @ApiOperation("改变用户密码")
+  public BaseVO updatePassword(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody IotDBUser iotDBUser,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.updatePwd(connection, iotDBUser);
+    return BaseVO.success("修改成功", null);
+  }
+
+  @DeleteMapping("/users/{userName}")
+  @ApiOperation("删除数据库用户")
+  public BaseVO deleteIotDBUser(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("userName") String userName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (userName == null || !userName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.deleteIotDBUser(connection, userName);
+    return BaseVO.success("删除成功", null);
+  }
+
+  @DeleteMapping("/roles/{roleName}")
+  @ApiOperation("删除数据库角色  (未使用)")
+  public BaseVO deleteIotDBRole(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("roleName") String roleName,
+      HttpServletRequest request)
+      throws BaseException {
+    if (roleName == null || roleName.matches("^[^ ]+$")) {
+      throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.deleteIotDBRole(connection, roleName);
+    return BaseVO.success("删除成功", null);
+  }
+
+  @PostMapping("/users")
+  @ApiOperation("创建数据库用户")
+  public BaseVO setIotDBUser(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody IotDBUser iotDBUser,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.setIotDBUser(connection, iotDBUser);
+    return BaseVO.success("创建成功", null);
+  }
+
+  @PostMapping("/roles")
+  @ApiOperation("创建数据角色   (未使用)")
+  public BaseVO setIotDBUser(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody IotDBRole iotDBRole,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    iotDBService.setIotDBRole(connection, iotDBRole);
+    return BaseVO.success("创建成功", null);
+  }
+
+  private void check(HttpServletRequest request, Integer serverId) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
+  }
+
+  private Long switchTime(String ttlUnit) throws BaseException {
+    Long time = 0L;
+    switch (ttlUnit) {
+      case "second":
+        time = 1000L;
+        break;
+      case "minute":
+        time = 60 * 1000L;
+        break;
+      case "hour":
+        time = 60 * 60 * 1000L;
+        break;
+      case "day":
+        time = 24 * 60 * 60 * 1000L;
+        break;
+      case "week":
+        time = 7 * 24 * 60 * 60 * 1000L;
+        break;
+      case "month":
+        time = 30 * 24 * 60 * 60 * 1000L;
+        break;
+      case "year":
+        time = 12 * 30 * 24 * 60 * 60 * 1000L;
+        break;
+      default:
+        throw new BaseException(ErrorCode.WRONG_DB_PARAM, ErrorCode.WRONG_DB_PARAM_MSG);
+    }
+    return time;
+  }
+
+  private String getTTL(Long time) {
+    long yearTime = 31104000000L;
+    long monthTime = 2592000000L;
+    long weekTime = 604800000L;
+    long dayTime = 86400000L;
+    long hourTime = 3600000L;
+    long minuteTime = 60000L;
+    long secondTime = 1000L;
+    if (time == 0) {
+      return "milliSecond";
+    }
+    if ((time / yearTime != 0) && (time % yearTime == 0)) {
+      return "year";
+    }
+    if ((time / monthTime != 0) && (time % monthTime == 0)) {
+      return "month";
+    }
+    if ((time / weekTime != 0) && (time % weekTime == 0)) {
+      return "week";
+    }
+    if ((time / dayTime != 0) && (time % dayTime == 0)) {
+      return "day";
+    }
+    if ((time / hourTime != 0) && (time % hourTime == 0)) {
+      return "hour";
+    }
+    if ((time / minuteTime != 0) && (time % minuteTime == 0)) {
+      return "minute";
+    }
+    if ((time / secondTime != 0) && (time % secondTime == 0)) {
+      return "second";
     }
+    return null;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
index 88ec329..b162210 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/QueryController.java
@@ -19,8 +19,6 @@
 
 package org.apache.iotdb.admin.controller;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
@@ -33,10 +31,14 @@ import org.apache.iotdb.admin.model.vo.SqlResultVO;
 import org.apache.iotdb.admin.service.ConnectionService;
 import org.apache.iotdb.admin.service.IotDBService;
 import org.apache.iotdb.admin.service.QueryService;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+
 import java.util.List;
 
 @RestController
@@ -44,90 +46,97 @@ import java.util.List;
 @RequestMapping("/servers/{serverId}")
 public class QueryController {
 
-    @Autowired
-    private ConnectionService connectionService;
-
-    @Autowired
-    private IotDBService iotDBService;
-
-    @Autowired
-    private QueryService queryService;
-
-    @PostMapping("/querySql")
-    @ApiOperation("用于查询器查询")
-    public BaseVO<List<SqlResultVO>> query(@PathVariable("serverId") Integer serverId,
-        @RequestBody SearchDTO searchDTO,
-        HttpServletRequest request) throws BaseException {
-        List<String> sqls = searchDTO.getSqls();
-        if (sqls == null || sqls.size() == 0) {
-            throw new BaseException(ErrorCode.NO_SQL, ErrorCode.NO_SQL_MSG);
-        }
-        check(request, serverId);
-        Connection connection = connectionService.getById(serverId);
-        Long timestamp = searchDTO.getTimestamp();
-        List<SqlResultVO> sqlResultVOList = iotDBService.queryAll(connection, sqls, timestamp);
-        return BaseVO.success("查询成功", sqlResultVOList);
-    }
+  @Autowired private ConnectionService connectionService;
 
-    @PostMapping("/query")
-    @ApiOperation("用于查询脚本保存或编辑")
-    public BaseVO saveQuery(@PathVariable("serverId") Integer serverId,
-        @RequestBody Query query,
-        HttpServletRequest request) throws BaseException {
-        String sqls = query.getSqls();
-        if (sqls == null || "".equals(sqls)) {
-            throw new BaseException(ErrorCode.NO_SQL, ErrorCode.NO_SQL_MSG);
-        }
-        check(request, serverId);
-        if (query.getId() != null) {
-            queryService.update(serverId, query);
-            return BaseVO.success("更新成功", null);
-        }
-        queryService.save(serverId, query);
-        return BaseVO.success("保存成功", null);
-    }
+  @Autowired private IotDBService iotDBService;
 
-    @GetMapping("/query")
-    @ApiOperation("获取脚本列表")
-    public BaseVO<List<QueryVO>> getQueries(@PathVariable("serverId") Integer serverId,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        List<QueryVO> queryVOList = queryService.getQueryList(serverId);
-        return BaseVO.success("获取成功", queryVOList);
-    }
+  @Autowired private QueryService queryService;
 
-    @DeleteMapping("/query/{queryId}")
-    @ApiOperation("删除脚本")
-    public BaseVO deleteQuery(@PathVariable("serverId") Integer serverId,
-        @PathVariable("queryId") Integer queryId,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        queryService.deleteQuery(queryId);
-        return BaseVO.success("删除成功", null);
+  @PostMapping("/querySql")
+  @ApiOperation("用于查询器查询")
+  public BaseVO<List<SqlResultVO>> query(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody SearchDTO searchDTO,
+      HttpServletRequest request)
+      throws BaseException {
+    List<String> sqls = searchDTO.getSqls();
+    if (sqls == null || sqls.size() == 0) {
+      throw new BaseException(ErrorCode.NO_SQL, ErrorCode.NO_SQL_MSG);
     }
+    check(request, serverId);
+    Connection connection = connectionService.getById(serverId);
+    Long timestamp = searchDTO.getTimestamp();
+    List<SqlResultVO> sqlResultVOList = iotDBService.queryAll(connection, sqls, timestamp);
+    return BaseVO.success("查询成功", sqlResultVOList);
+  }
 
-    @GetMapping("/query/{queryId}")
-    @ApiOperation("获取指定脚本")
-    public BaseVO<Query> getQuery(@PathVariable("serverId") Integer serverId,
-        @PathVariable("queryId") Integer queryId,
-        HttpServletRequest request) throws BaseException {
-        check(request, serverId);
-        Query query = queryService.getQuery(queryId);
-        return BaseVO.success("获取成功", query);
+  @PostMapping("/query")
+  @ApiOperation("用于查询脚本保存或编辑")
+  public BaseVO saveQuery(
+      @PathVariable("serverId") Integer serverId,
+      @RequestBody Query query,
+      HttpServletRequest request)
+      throws BaseException {
+    String sqls = query.getSqls();
+    if (sqls == null || "".equals(sqls)) {
+      throw new BaseException(ErrorCode.NO_SQL, ErrorCode.NO_SQL_MSG);
     }
-
-    @GetMapping("/stop")
-    @ApiOperation("用于查询终止")
-    public BaseVO query(@PathVariable("serverId") Integer serverId, @RequestParam("timestamp") Long timestamp, HttpServletRequest request)
-        throws BaseException {
-        check(request, serverId);
-        iotDBService.stopQuery(serverId, timestamp);
-        return BaseVO.success("停止成功", null);
+    check(request, serverId);
+    if (query.getId() != null) {
+      queryService.update(serverId, query);
+      return BaseVO.success("更新成功", null);
     }
+    queryService.save(serverId, query);
+    return BaseVO.success("保存成功", null);
+  }
 
-    public void check(HttpServletRequest request, Integer serverId) throws BaseException {
-        Integer userId = AuthenticationUtils.getUserId(request);
-        connectionService.check(serverId, userId);
-    }
+  @GetMapping("/query")
+  @ApiOperation("获取脚本列表")
+  public BaseVO<List<QueryVO>> getQueries(
+      @PathVariable("serverId") Integer serverId, HttpServletRequest request) throws BaseException {
+    check(request, serverId);
+    List<QueryVO> queryVOList = queryService.getQueryList(serverId);
+    return BaseVO.success("获取成功", queryVOList);
+  }
+
+  @DeleteMapping("/query/{queryId}")
+  @ApiOperation("删除脚本")
+  public BaseVO deleteQuery(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("queryId") Integer queryId,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    queryService.deleteQuery(queryId);
+    return BaseVO.success("删除成功", null);
+  }
+
+  @GetMapping("/query/{queryId}")
+  @ApiOperation("获取指定脚本")
+  public BaseVO<Query> getQuery(
+      @PathVariable("serverId") Integer serverId,
+      @PathVariable("queryId") Integer queryId,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    Query query = queryService.getQuery(queryId);
+    return BaseVO.success("获取成功", query);
+  }
+
+  @GetMapping("/stop")
+  @ApiOperation("用于查询终止")
+  public BaseVO query(
+      @PathVariable("serverId") Integer serverId,
+      @RequestParam("timestamp") Long timestamp,
+      HttpServletRequest request)
+      throws BaseException {
+    check(request, serverId);
+    iotDBService.stopQuery(serverId, timestamp);
+    return BaseVO.success("停止成功", null);
+  }
 
+  public void check(HttpServletRequest request, Integer serverId) throws BaseException {
+    Integer userId = AuthenticationUtils.getUserId(request);
+    connectionService.check(serverId, userId);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
index 8fbbc3d..ff0e235 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/UserController.java
@@ -19,11 +19,6 @@
 
 package org.apache.iotdb.admin.controller;
 
-import com.auth0.jwt.JWT;
-import com.auth0.jwt.algorithms.Algorithm;
-import com.auth0.jwt.interfaces.DecodedJWT;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.common.utils.AuthenticationUtils;
@@ -33,6 +28,12 @@ import org.apache.iotdb.admin.model.vo.ConnVO;
 import org.apache.iotdb.admin.model.vo.ConnectionVO;
 import org.apache.iotdb.admin.service.ConnectionService;
 import org.apache.iotdb.admin.service.UserService;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -40,6 +41,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import java.net.InetAddress;
 import java.util.Calendar;
 import java.util.List;
@@ -48,74 +50,76 @@ import java.util.List;
 @Api(value = "登录相关接口")
 public class UserController {
 
-    @Autowired
-    private UserService userService;
+  @Autowired private UserService userService;
 
-    @Autowired
-    private ConnectionService connectionService;
+  @Autowired private ConnectionService connectionService;
 
-    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
+  private static final Logger logger = LoggerFactory.getLogger(UserController.class);
 
-    @PostMapping("/login")
-    @ApiOperation("登录")
-    public BaseVO<ConnectionVO> login(@RequestParam("name") String name, @RequestParam("password") String password, HttpServletResponse response)
-        throws BaseException {
-        if (name == null || password == null || name.length() < 4 || password.length() < 4) {
-            throw new BaseException(ErrorCode.WRONG_USER_PARAM, ErrorCode.WRONG_USER_PARAM_MSG);
-        }
-        User user = userService.login(name, password);
-        int userId = user.getId();
-        List<ConnVO> connVOs = connectionService.getAllConnections(userId);
-        ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, name);
-        response.addHeader("Authorization", getToken(user));
-        return BaseVO.success("登录成功", connectionVO);
-    }
-
-    @PostMapping("/save")
-    @ApiOperation("创建用户  (未使用)")
-    public BaseVO save(@RequestBody User user) throws BaseException {
-        userService.insert(user);
-        return BaseVO.success("保存成功", null);
+  @PostMapping("/login")
+  @ApiOperation("登录")
+  public BaseVO<ConnectionVO> login(
+      @RequestParam("name") String name,
+      @RequestParam("password") String password,
+      HttpServletResponse response)
+      throws BaseException {
+    if (name == null || password == null || name.length() < 4 || password.length() < 4) {
+      throw new BaseException(ErrorCode.WRONG_USER_PARAM, ErrorCode.WRONG_USER_PARAM_MSG);
     }
+    User user = userService.login(name, password);
+    int userId = user.getId();
+    List<ConnVO> connVOs = connectionService.getAllConnections(userId);
+    ConnectionVO connectionVO = new ConnectionVO(connVOs, userId, name);
+    response.addHeader("Authorization", getToken(user));
+    return BaseVO.success("登录成功", connectionVO);
+  }
 
+  @PostMapping("/save")
+  @ApiOperation("创建用户  (未使用)")
+  public BaseVO save(@RequestBody User user) throws BaseException {
+    userService.insert(user);
+    return BaseVO.success("保存成功", null);
+  }
 
-    @DeleteMapping("/delete")
-    @ApiOperation("删除用户  (未使用)")
-    public BaseVO delete(@RequestParam("userId") Integer userId, HttpServletRequest request) throws BaseException {
-        AuthenticationUtils.userAuthentication(userId, request);
-        userService.delete(userId);
-        return BaseVO.success("删除成功", null);
-    }
+  @DeleteMapping("/delete")
+  @ApiOperation("删除用户  (未使用)")
+  public BaseVO delete(@RequestParam("userId") Integer userId, HttpServletRequest request)
+      throws BaseException {
+    AuthenticationUtils.userAuthentication(userId, request);
+    userService.delete(userId);
+    return BaseVO.success("删除成功", null);
+  }
 
-    @GetMapping("/get")
-    @ApiOperation("二次登录获取用户信息")
-    public BaseVO<User> getUser(HttpServletRequest request) {
-        String authorization = request.getHeader("Authorization");
-        DecodedJWT decode = JWT.decode(authorization);
-        User user = new User();
-        if (decode != null) {
-            Integer userId = decode.getClaim("userId").asInt();
-            String name = decode.getClaim("name").asString();
-            user.setId(userId);
-            user.setName(name);
-        }
-        return BaseVO.success("获取成功", user);
+  @GetMapping("/get")
+  @ApiOperation("二次登录获取用户信息")
+  public BaseVO<User> getUser(HttpServletRequest request) {
+    String authorization = request.getHeader("Authorization");
+    DecodedJWT decode = JWT.decode(authorization);
+    User user = new User();
+    if (decode != null) {
+      Integer userId = decode.getClaim("userId").asInt();
+      String name = decode.getClaim("name").asString();
+      user.setId(userId);
+      user.setName(name);
     }
+    return BaseVO.success("获取成功", user);
+  }
 
-    private String getToken(User user) throws BaseException {
-        Calendar instance = Calendar.getInstance();
-        try {
-            instance.add(Calendar.HOUR, 24);
-            String token = JWT.create()
-                .withClaim("userId", user.getId())
-                .withClaim("name", user.getName())
-                .withExpiresAt(instance.getTime())
-                .sign(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()));
-            logger.info(user.getName() + "登录成功");
-            return token;
-        } catch (Exception e) {
-            logger.info(e.getMessage());
-            throw new BaseException(ErrorCode.GET_TOKEN_FAIL, ErrorCode.GET_TOKEN_FAIL_MSG);
-        }
+  private String getToken(User user) throws BaseException {
+    Calendar instance = Calendar.getInstance();
+    try {
+      instance.add(Calendar.HOUR, 24);
+      String token =
+          JWT.create()
+              .withClaim("userId", user.getId())
+              .withClaim("name", user.getName())
+              .withExpiresAt(instance.getTime())
+              .sign(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()));
+      logger.info(user.getName() + "登录成功");
+      return token;
+    } catch (Exception e) {
+      logger.info(e.getMessage());
+      throw new BaseException(ErrorCode.GET_TOKEN_FAIL, ErrorCode.GET_TOKEN_FAIL_MSG);
     }
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java b/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
index 3cb100a..750ef37 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/demo/JDBC.java
@@ -19,141 +19,134 @@
 
 package org.apache.iotdb.admin.demo;
 
-
 import java.sql.*;
 
-/**
- * JDBC demo代码
- */
+/** JDBC demo代码 */
 public class JDBC {
 
-    public static void main(String[] args) throws SQLException {
-        Connection connection = getConnection();
-        if (connection == null) {
-            System.out.println("get connection defeat");
-            return;
-        }
-        Statement statement = connection.createStatement();
-        //创建存储组
-        try {
-            statement.execute("SET STORAGE GROUP TO root.demo");
-        } catch (SQLException e) {
-            e.printStackTrace();
-        }
-        //展示存储组
-        statement.execute("SHOW STORAGE GROUP");
-        outputResult(statement.getResultSet());
-        //创建时间序列
-        //不同的数据类型有不同的编码方式. 这里以INT32作为例子
-        try {
-            statement.execute("CREATE TIMESERIES root.demo.s0 WITH DATATYPE=INT32,ENCODING=RLE;");
-        } catch (SQLException e) {
-            System.out.println(e.getMessage());
-        }
-        //展示时间序列
-        statement.execute("SHOW TIMESERIES root.demo");
-        outputResult(statement.getResultSet());
-        //展示设备
-        statement.execute("SHOW DEVICES");
-        outputResult(statement.getResultSet());
-        //计算时间序列个数
-        statement.execute("COUNT TIMESERIES root");
-        outputResult(statement.getResultSet());
-        //计算给定级别的nodes个数
-        statement.execute("COUNT NODES root LEVEL=3");
-        outputResult(statement.getResultSet());
-        //计算时间序列以级别3分组的个数
-        statement.execute("COUNT TIMESERIES root GROUP BY LEVEL=3");
-        outputResult(statement.getResultSet());
-
-        //批量执行插入语句
-        statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
-        statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
-        statement.addBatch("insert into root.demo(timestamp,s0) values(2,15);");
-        statement.addBatch("insert into root.demo(timestamp,s0) values(2,17);");
-        statement.addBatch("insert into root.demo(timestamp,s0) values(4,12);");
-        statement.executeBatch();
-        statement.clearBatch();
-
-        //查询语句
-        String sql = "select * from root.demo";
-        ResultSet resultSet = statement.executeQuery(sql);
-        System.out.println("sql: " + sql);
-        outputResult(resultSet);
-
-        //精确的查询语句
-        sql = "select s0 from root.demo where time = 4;";
-        resultSet = statement.executeQuery(sql);
-        System.out.println("sql: " + sql);
-        outputResult(resultSet);
-
-        //时间范围查询
-        sql = "select s0 from root.demo where time >= 2 and time < 5;";
-        resultSet = statement.executeQuery(sql);
-        System.out.println("sql: " + sql);
-        outputResult(resultSet);
-
-        //聚合查询
-        sql = "select count(s0) from root.demo;";
-        resultSet = statement.executeQuery(sql);
-        System.out.println("sql: " + sql);
-        outputResult(resultSet);
-
-        //删除时间序列
-        statement.execute("delete timeseries root.demo.s0");
-
-        //关闭连接
-        statement.close();
-        connection.close();
+  public static void main(String[] args) throws SQLException {
+    Connection connection = getConnection();
+    if (connection == null) {
+      System.out.println("get connection defeat");
+      return;
     }
-
-
-    public static Connection getConnection() {
-        // JDBC driver name and database URL
-        String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
-        String url = "jdbc:iotdb://127.0.0.1:6667/";
-
-        // Database credentials
-        String username = "root";
-        String password = "root";
-
-        Connection connection = null;
-        try {
-            Class.forName(driver);
-            connection = DriverManager.getConnection(url, username, password);
-        } catch (ClassNotFoundException e) {
-            e.printStackTrace();
-        } catch (SQLException e) {
-            e.printStackTrace();
-        }
-        return connection;
+    Statement statement = connection.createStatement();
+    // 创建存储组
+    try {
+      statement.execute("SET STORAGE GROUP TO root.demo");
+    } catch (SQLException e) {
+      e.printStackTrace();
     }
-
-
-    /**
-     * This is an example of outputting the results in the ResultSet
-     */
-    private static void outputResult(ResultSet resultSet) throws SQLException {
-        if (resultSet != null) {
-            System.out.println("--------------------------");
-            final ResultSetMetaData metaData = resultSet.getMetaData();
-            final int columnCount = metaData.getColumnCount();
-            for (int i = 0; i < columnCount; i++) {
-                System.out.print(metaData.getColumnLabel(i + 1) + " ");
-            }
+    // 展示存储组
+    statement.execute("SHOW STORAGE GROUP");
+    outputResult(statement.getResultSet());
+    // 创建时间序列
+    // 不同的数据类型有不同的编码方式. 这里以INT32作为例子
+    try {
+      statement.execute("CREATE TIMESERIES root.demo.s0 WITH DATATYPE=INT32,ENCODING=RLE;");
+    } catch (SQLException e) {
+      System.out.println(e.getMessage());
+    }
+    // 展示时间序列
+    statement.execute("SHOW TIMESERIES root.demo");
+    outputResult(statement.getResultSet());
+    // 展示设备
+    statement.execute("SHOW DEVICES");
+    outputResult(statement.getResultSet());
+    // 计算时间序列个数
+    statement.execute("COUNT TIMESERIES root");
+    outputResult(statement.getResultSet());
+    // 计算给定级别的nodes个数
+    statement.execute("COUNT NODES root LEVEL=3");
+    outputResult(statement.getResultSet());
+    // 计算时间序列以级别3分组的个数
+    statement.execute("COUNT TIMESERIES root GROUP BY LEVEL=3");
+    outputResult(statement.getResultSet());
+
+    // 批量执行插入语句
+    statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
+    statement.addBatch("insert into root.demo(timestamp,s0) values(1,1);");
+    statement.addBatch("insert into root.demo(timestamp,s0) values(2,15);");
+    statement.addBatch("insert into root.demo(timestamp,s0) values(2,17);");
+    statement.addBatch("insert into root.demo(timestamp,s0) values(4,12);");
+    statement.executeBatch();
+    statement.clearBatch();
+
+    // 查询语句
+    String sql = "select * from root.demo";
+    ResultSet resultSet = statement.executeQuery(sql);
+    System.out.println("sql: " + sql);
+    outputResult(resultSet);
+
+    // 精确的查询语句
+    sql = "select s0 from root.demo where time = 4;";
+    resultSet = statement.executeQuery(sql);
+    System.out.println("sql: " + sql);
+    outputResult(resultSet);
+
+    // 时间范围查询
+    sql = "select s0 from root.demo where time >= 2 and time < 5;";
+    resultSet = statement.executeQuery(sql);
+    System.out.println("sql: " + sql);
+    outputResult(resultSet);
+
+    // 聚合查询
+    sql = "select count(s0) from root.demo;";
+    resultSet = statement.executeQuery(sql);
+    System.out.println("sql: " + sql);
+    outputResult(resultSet);
+
+    // 删除时间序列
+    statement.execute("delete timeseries root.demo.s0");
+
+    // 关闭连接
+    statement.close();
+    connection.close();
+  }
+
+  public static Connection getConnection() {
+    // JDBC driver name and database URL
+    String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
+    String url = "jdbc:iotdb://127.0.0.1:6667/";
+
+    // Database credentials
+    String username = "root";
+    String password = "root";
+
+    Connection connection = null;
+    try {
+      Class.forName(driver);
+      connection = DriverManager.getConnection(url, username, password);
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+    } catch (SQLException e) {
+      e.printStackTrace();
+    }
+    return connection;
+  }
+
+  /** This is an example of outputting the results in the ResultSet */
+  private static void outputResult(ResultSet resultSet) throws SQLException {
+    if (resultSet != null) {
+      System.out.println("--------------------------");
+      final ResultSetMetaData metaData = resultSet.getMetaData();
+      final int columnCount = metaData.getColumnCount();
+      for (int i = 0; i < columnCount; i++) {
+        System.out.print(metaData.getColumnLabel(i + 1) + " ");
+      }
+      System.out.println();
+      while (resultSet.next()) {
+        for (int i = 1; ; i++) {
+          System.out.print(resultSet.getString(i));
+          if (i < columnCount) {
+            System.out.print(", ");
+          } else {
             System.out.println();
-            while (resultSet.next()) {
-                for (int i = 1; ; i++) {
-                    System.out.print(resultSet.getString(i));
-                    if (i < columnCount) {
-                        System.out.print(", ");
-                    } else {
-                        System.out.println();
-                        break;
-                    }
-                }
-            }
-            System.out.println("--------------------------\n");
+            break;
+          }
         }
+      }
+      System.out.println("--------------------------\n");
     }
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java b/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
index 11259c1..892182d 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/demo/NativeAPI.java
@@ -32,92 +32,82 @@ import org.apache.iotdb.tsfile.read.common.RowRecord;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * 原生api demo代码
- */
+/** 原生api demo代码 */
 public class NativeAPI {
 
-    public static void main(String[] args) throws IoTDBConnectionException, StatementExecutionException {
-        //建立连接
-        Session session = new Session("localhost", 6667, "root", "root");
-        session.open();
-//        SessionPool sessionPool = new SessionPool("localhost", 6667,"root","root",3);
-//        sessionPool.insertRecord();
-        //创建存储组
-        session.setStorageGroup("root.fyx");
-        //创建时间序列
-        /**
-         *   path:层级路径
-         *  TSDataType数据类型:六种                 支持编码方式
-         *          boolean              PLAIN,RLE
-         *          int32                PLAIN,RLE,TS_2DIFF,GORILLA
-         *          int64                PLAIN,RLE,TS_2DIFF,GORILLA
-         *          float                PLAIN,RLE,TS_2DIFF,GORILLA
-         *          double               PLAIN,RLE,TS_2DIFF,GORILLA
-         *          text(字符串)         PLAIN
-         *
-         *  TSEncoding编码方式:
-         *        PLAIN编码:不编码 压缩效率高 空间存储效率低
-         *       二阶差分编码(TS_2DIFF):适合单调序列数据 不适合编码波动较大的数据
-         *       游程编码(RLE):比较适合整数值连续出现的序列
-         *       GORILLA编码:无损编码,它比较适合编码前后值比较接近的数值序列
-         *       定频数据编码(REGULAR):仅适用于整型 允许数据缺失
-         *
-         *  CompressionType压缩方式:
-         *        UMCOMPRESSED
-         *        SNAPPY
-         *        LZ4
-         *        GZIP
-         *        SDT
-         *        PAA
-         *        PLA
-         */
-        session.createTimeseries("root.fyx.cq.dev.temp", TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY, null, null, null, null);
-        //创建多个时间序列
-//        session.createMultiTimeseries();
-        //插入数据
-        List<String> measurements = new ArrayList<>();
-        List<TSDataType> types = new ArrayList<>();
-        measurements.add("temp");
-        types.add(TSDataType.FLOAT);
-        for (long time = 0; time < 10; time++) {
-            List<Object> values = new ArrayList<>();
-            values.add(time * 6.6f);
-            //如果不加type,服务器会做类型推断,会有额外耗时
-            session.insertRecord("root.fyx.cq.dev", time, measurements, types, values);
-        }
-        //执行非查询语句的sql
-        session.executeNonQueryStatement("insert into root.fyx.cq.dev(timestamp,temp) values(now(),66.66)");
-        //执行查询语句的sql
-        SessionDataSet sessionDataSet = session.executeQueryStatement("select * from root.fyx.cq.dev");
-        //数据处理
-        int fetchSize = sessionDataSet.getFetchSize();
-        List<String> columnNames = sessionDataSet.getColumnNames();
-        List<TSDataType> columnTypes = sessionDataSet.getColumnTypes();
-        System.out.println(columnNames);
-        System.out.println(columnTypes);
-        if (fetchSize > 0) {
-            while (sessionDataSet.hasNext()) {
-                RowRecord next = sessionDataSet.next();
-                List<Field> fields = next.getFields();
-                // 查询结果第一个为时间戳
-                long timestamp = next.getTimestamp();
-                System.out.print(timestamp + "\t");
-                for (int i = 0; i < fields.size(); i++) {
-                    Field field = fields.get(i);
-                    // 这里的需要按照类型获取
-                    System.out.print(field.getObjectValue(field.getDataType()));
-                }
-                System.out.println();
-            }
+  public static void main(String[] args)
+      throws IoTDBConnectionException, StatementExecutionException {
+    // 建立连接
+    Session session = new Session("localhost", 6667, "root", "root");
+    session.open();
+    //        SessionPool sessionPool = new SessionPool("localhost", 6667,"root","root",3);
+    //        sessionPool.insertRecord();
+    // 创建存储组
+    session.setStorageGroup("root.fyx");
+    // 创建时间序列
+    /**
+     * path:层级路径 TSDataType数据类型:六种 支持编码方式 boolean PLAIN,RLE int32 PLAIN,RLE,TS_2DIFF,GORILLA int64
+     * PLAIN,RLE,TS_2DIFF,GORILLA float PLAIN,RLE,TS_2DIFF,GORILLA double PLAIN,RLE,TS_2DIFF,GORILLA
+     * text(字符串) PLAIN
+     *
+     * <p>TSEncoding编码方式: PLAIN编码:不编码 压缩效率高 空间存储效率低 二阶差分编码(TS_2DIFF):适合单调序列数据 不适合编码波动较大的数据
+     * 游程编码(RLE):比较适合整数值连续出现的序列 GORILLA编码:无损编码,它比较适合编码前后值比较接近的数值序列 定频数据编码(REGULAR):仅适用于整型 允许数据缺失
+     *
+     * <p>CompressionType压缩方式: UMCOMPRESSED SNAPPY LZ4 GZIP SDT PAA PLA
+     */
+    session.createTimeseries(
+        "root.fyx.cq.dev.temp",
+        TSDataType.FLOAT,
+        TSEncoding.RLE,
+        CompressionType.SNAPPY,
+        null,
+        null,
+        null,
+        null);
+    // 创建多个时间序列
+    //        session.createMultiTimeseries();
+    // 插入数据
+    List<String> measurements = new ArrayList<>();
+    List<TSDataType> types = new ArrayList<>();
+    measurements.add("temp");
+    types.add(TSDataType.FLOAT);
+    for (long time = 0; time < 10; time++) {
+      List<Object> values = new ArrayList<>();
+      values.add(time * 6.6f);
+      // 如果不加type,服务器会做类型推断,会有额外耗时
+      session.insertRecord("root.fyx.cq.dev", time, measurements, types, values);
+    }
+    // 执行非查询语句的sql
+    session.executeNonQueryStatement(
+        "insert into root.fyx.cq.dev(timestamp,temp) values(now(),66.66)");
+    // 执行查询语句的sql
+    SessionDataSet sessionDataSet = session.executeQueryStatement("select * from root.fyx.cq.dev");
+    // 数据处理
+    int fetchSize = sessionDataSet.getFetchSize();
+    List<String> columnNames = sessionDataSet.getColumnNames();
+    List<TSDataType> columnTypes = sessionDataSet.getColumnTypes();
+    System.out.println(columnNames);
+    System.out.println(columnTypes);
+    if (fetchSize > 0) {
+      while (sessionDataSet.hasNext()) {
+        RowRecord next = sessionDataSet.next();
+        List<Field> fields = next.getFields();
+        // 查询结果第一个为时间戳
+        long timestamp = next.getTimestamp();
+        System.out.print(timestamp + "\t");
+        for (int i = 0; i < fields.size(); i++) {
+          Field field = fields.get(i);
+          // 这里的需要按照类型获取
+          System.out.print(field.getObjectValue(field.getDataType()));
         }
-        sessionDataSet.closeOperationHandle();
-        //删除时间序列
-        session.deleteTimeseries("root.fyx.cq.dev.temp");
-        //删除存储组
-        session.deleteStorageGroup("root.fyx");
-        session.close();
+        System.out.println();
+      }
     }
-
-
+    sessionDataSet.closeOperationHandle();
+    // 删除时间序列
+    session.deleteTimeseries("root.fyx.cq.dev.temp");
+    // 删除存储组
+    session.deleteStorageGroup("root.fyx");
+    session.close();
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java b/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
index 59be4fa..615ac99 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/filter/TokenFilter.java
@@ -19,39 +19,42 @@
 
 package org.apache.iotdb.admin.filter;
 
+import org.apache.iotdb.admin.common.exception.BaseException;
+import org.apache.iotdb.admin.common.exception.ErrorCode;
+
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.JWTVerifier;
 import com.auth0.jwt.algorithms.Algorithm;
-import org.apache.iotdb.admin.common.exception.BaseException;
-import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.springframework.web.servlet.HandlerInterceptor;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
-/**
- * 拦截器
- */
+/** 拦截器 */
 public class TokenFilter implements HandlerInterceptor {
 
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws BaseException {
-        JWTVerifier jwtVerifier;
-        try {
-            jwtVerifier = JWT.require(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress())).build();
-        } catch (UnknownHostException e) {
-            e.printStackTrace();
-            throw new BaseException(ErrorCode.SET_JWT_FAIL, ErrorCode.SET_JWT_FAIL_MSG);
-        }
-        try {
-            String authorization = request.getHeader("Authorization");
-            jwtVerifier.verify(authorization);
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new BaseException(ErrorCode.TOKEN_ERR, ErrorCode.TOKEN_ERR_MSG);
-        }
-        return true;
+  @Override
+  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+      throws BaseException {
+    JWTVerifier jwtVerifier;
+    try {
+      jwtVerifier =
+          JWT.require(Algorithm.HMAC256("IOTDB:" + InetAddress.getLocalHost().getHostAddress()))
+              .build();
+    } catch (UnknownHostException e) {
+      e.printStackTrace();
+      throw new BaseException(ErrorCode.SET_JWT_FAIL, ErrorCode.SET_JWT_FAIL_MSG);
+    }
+    try {
+      String authorization = request.getHeader("Authorization");
+      jwtVerifier.verify(authorization);
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new BaseException(ErrorCode.TOKEN_ERR, ErrorCode.TOKEN_ERR_MSG);
     }
+    return true;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java
index a9db0bb..60c36fd 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/ConnectionMapper.java
@@ -19,11 +19,10 @@
 
 package org.apache.iotdb.admin.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.iotdb.admin.model.entity.Connection;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
 @Component
-public interface ConnectionMapper extends BaseMapper<Connection> {
-
-}
+public interface ConnectionMapper extends BaseMapper<Connection> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java
index b870411..2931563 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/DeviceMapper.java
@@ -19,10 +19,10 @@
 
 package org.apache.iotdb.admin.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.iotdb.admin.model.entity.Device;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
 @Component
-public interface DeviceMapper extends BaseMapper<Device> {
-}
+public interface DeviceMapper extends BaseMapper<Device> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java
index 5752ff6..d7fff10 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/GroupMapper.java
@@ -19,10 +19,10 @@
 
 package org.apache.iotdb.admin.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.iotdb.admin.model.entity.StorageGroup;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
 @Component
-public interface GroupMapper extends BaseMapper<StorageGroup> {
-}
+public interface GroupMapper extends BaseMapper<StorageGroup> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java
index be3a017..bf69d91 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/MeasurementMapper.java
@@ -19,11 +19,10 @@
 
 package org.apache.iotdb.admin.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.iotdb.admin.model.entity.Measurement;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
 @Component
-public interface MeasurementMapper extends BaseMapper<Measurement> {
-
-}
+public interface MeasurementMapper extends BaseMapper<Measurement> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java
index d0c8858..7c80fba 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/QueryMapper.java
@@ -19,11 +19,10 @@
 
 package org.apache.iotdb.admin.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.iotdb.admin.model.entity.Query;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
 @Component
-public interface QueryMapper extends BaseMapper<Query> {
-
-}
+public interface QueryMapper extends BaseMapper<Query> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java b/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java
index 55889c2..584a146 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/mapper/UserMapper.java
@@ -19,11 +19,10 @@
 
 package org.apache.iotdb.admin.mapper;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.iotdb.admin.model.entity.User;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springframework.stereotype.Component;
 
 @Component
-public interface UserMapper extends BaseMapper<User> {
-
-}
+public interface UserMapper extends BaseMapper<User> {}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
index a87dac6..d17f8ab 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/ConnectionDTO.java
@@ -26,28 +26,30 @@ import org.hibernate.validator.constraints.Range;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
 @Data
 public class ConnectionDTO implements Serializable {
 
-    @NotBlank(message = "主机地址不能为空或为null")
-    @Pattern(regexp = "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$", message = "主机号输入不合法")
-    private String host;
-
-    @NotNull(message = "端口号不能为null")
-    @Range(min = 0, max = 65535, message = "端口号输入不合法")
-    private Integer port;
-
-    @NotBlank(message = "用户名不能为空或为null")
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
-    private String username;
-
-    @NotBlank(message = "密码不能为空或为null")
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
-    private String password;
-
+  @NotBlank(message = "主机地址不能为空或为null")
+  @Pattern(
+      regexp =
+          "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$",
+      message = "主机号输入不合法")
+  private String host;
+
+  @NotNull(message = "端口号不能为null")
+  @Range(min = 0, max = 65535, message = "端口号输入不合法")
+  private Integer port;
+
+  @NotBlank(message = "用户名不能为空或为null")
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
+  private String username;
+
+  @NotBlank(message = "密码不能为空或为null")
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
+  private String password;
 }
-
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
index c04efa3..9b2246e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/CountDTO.java
@@ -27,7 +27,7 @@ import java.util.List;
 @Data
 public class CountDTO<T> implements Serializable {
 
-    private List<T> objects;
-    private Integer totalCount;
-    private Integer totalPage;
+  private List<T> objects;
+  private Integer totalCount;
+  private Integer totalPage;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
index 5050673..e26eea3 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceDTO.java
@@ -26,11 +26,11 @@ import java.io.Serializable;
 @Data
 public class DeviceDTO implements Serializable {
 
-    private String timeseries;
+  private String timeseries;
 
-    private String dataType;
+  private String dataType;
 
-    private String encoding;
+  private String encoding;
 
-    private String description;
+  private String description;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
index 3733e54..f2364af 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DeviceInfoDTO.java
@@ -23,19 +23,20 @@ import lombok.Data;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 import java.util.List;
 
 @Data
 public class DeviceInfoDTO implements Serializable {
 
-    private List<DeviceDTO> deviceDTOList;
+  private List<DeviceDTO> deviceDTOList;
 
-    @NotNull(message = "设备名不能为null")
-    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-    private String deviceName;
+  @NotNull(message = "设备名不能为null")
+  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  private String deviceName;
 
-    private String description;
+  private String description;
 
-    private Integer deviceId;
+  private Integer deviceId;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
index 5aa6070..3e751b9 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/GroupDTO.java
@@ -23,19 +23,18 @@ import lombok.Data;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
 @Data
 public class GroupDTO implements Serializable {
 
-    @NotNull(message = "存储组名不能为null")
-    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-    private String groupName;
-    private String description;
-    private Long ttl;
-    private String ttlUnit;
-    private Integer groupId;
+  @NotNull(message = "存储组名不能为null")
+  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  private String groupName;
 
+  private String description;
+  private Long ttl;
+  private String ttlUnit;
+  private Integer groupId;
 }
-
-
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
index 6d2ba60..4a25786 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBRole.java
@@ -25,15 +25,12 @@ import org.hibernate.validator.constraints.Length;
 import java.io.Serializable;
 import java.util.List;
 
-/**
- * 传输role信息类
- */
+/** 传输role信息类 */
 @Data
 public class IotDBRole implements Serializable {
 
-    @Length(min = 4, message = "长度必须大于等于4")
-    private String roleName;
-
-    private List<String> privileges;
+  @Length(min = 4, message = "长度必须大于等于4")
+  private String roleName;
 
+  private List<String> privileges;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
index 767ad92..d0beb5b 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUser.java
@@ -23,23 +23,22 @@ import lombok.Data;
 import org.hibernate.validator.constraints.Length;
 
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
-/**
- * 传输User信息类
- */
+/** 传输User信息类 */
 @Data
 public class IotDBUser implements Serializable {
 
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-    private String userName;
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  private String userName;
 
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-    private String password;
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  private String password;
 
-//    private List<String> privileges;
-//
-//    private List<String> roles;
+  //    private List<String> privileges;
+  //
+  //    private List<String> roles;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java
index 562fc62..daf3027 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/IotDBUserDTO.java
@@ -27,5 +27,5 @@ import java.util.List;
 @Data
 public class IotDBUserDTO implements Serializable {
 
-    private List<PrivilegeInfoDTO> privilegesInfos;
+  private List<PrivilegeInfoDTO> privilegesInfos;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
index b9e6fc7..7b2eda7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/MeasurementDTO.java
@@ -26,12 +26,12 @@ import java.io.Serializable;
 @Data
 public class MeasurementDTO implements Serializable {
 
-    private String timeseries;
-    private String alias;
-    private String storagegroup;
-    private String dataType;
-    private String encoding;
-    private String compression;
-    private String tags;
-    private String attributes;
+  private String timeseries;
+  private String alias;
+  private String storagegroup;
+  private String dataType;
+  private String encoding;
+  private String compression;
+  private String tags;
+  private String attributes;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
index 69488b6..7e55404 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/PrivilegeInfoDTO.java
@@ -27,14 +27,14 @@ import java.util.List;
 @Data
 public class PrivilegeInfoDTO implements Serializable {
 
-    // 0 1 2 3 对应 root、storageGroup、device、timeseries
-    private Integer type;
-    private List<String> groupPaths;
-    private List<String> devicePaths;
-    private List<String> timeseriesPaths;
-    private List<String> privileges;
-    private List<String> cancelPrivileges;
-    private List<String> delGroupPaths;
-    private List<String> delDevicePaths;
-    private List<String> delTimeseriesPaths;
+  // 0 1 2 3 对应 root、storageGroup、device、timeseries
+  private Integer type;
+  private List<String> groupPaths;
+  private List<String> devicePaths;
+  private List<String> timeseriesPaths;
+  private List<String> privileges;
+  private List<String> cancelPrivileges;
+  private List<String> delGroupPaths;
+  private List<String> delDevicePaths;
+  private List<String> delTimeseriesPaths;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java
index ca8a86a..6ddfd51 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/QueryDTO.java
@@ -22,14 +22,14 @@ package org.apache.iotdb.admin.model.dto;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+
 import java.io.Serializable;
 
 @Data
 public class QueryDTO implements Serializable {
 
+  @NotNull(message = "未指定脚本名")
+  private String queryName;
 
-    @NotNull(message = "未指定脚本名")
-    private String queryName;
-
-    private String sqls;
+  private String sqls;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
index 4d0c8ba..366dff0 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/SearchDTO.java
@@ -22,15 +22,15 @@ package org.apache.iotdb.admin.model.dto;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+
 import java.io.Serializable;
 import java.util.List;
 
 @Data
 public class SearchDTO implements Serializable {
 
-    private List<String> sqls;
-
-    @NotNull(message = "不能为null")
-    private Long timestamp;
+  private List<String> sqls;
 
+  @NotNull(message = "不能为null")
+  private Long timestamp;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java
index ecf72cf..31fef36 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/Timeseries.java
@@ -25,18 +25,15 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-/**
- * 传输时间序列信息的类
- */
+/** 传输时间序列信息的类 */
 @Data
 public class Timeseries implements Serializable {
 
-    private List<String> measurements = new ArrayList<>();
-
-    private List<String> types = new ArrayList<>();
+  private List<String> measurements = new ArrayList<>();
 
-    private long time;
+  private List<String> types = new ArrayList<>();
 
-    private List<String> values;
+  private long time;
 
+  private List<String> values;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
index 6672db9..9080433 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Connection.java
@@ -28,38 +28,41 @@ import org.hibernate.validator.constraints.Range;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
 @Data
 public class Connection implements Serializable {
 
-    @TableId(type = IdType.AUTO)
-    private Integer id;
-
-    @NotBlank(message = "主机地址不能为空或为null")
-    @Pattern(regexp = "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$", message = "主机号输入不合法")
-    private String host;
+  @TableId(type = IdType.AUTO)
+  private Integer id;
 
-    @NotNull(message = "端口号不能为null")
-    @Range(min = 0, max = 65535, message = "端口号输入不合法")
-    private Integer port;
+  @NotBlank(message = "主机地址不能为空或为null")
+  @Pattern(
+      regexp =
+          "^((2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})(\\.(2(5[0-5]{1}|[0-4]\\d{1})|[0-1]?\\d{1,2})){3})|(localhost)$",
+      message = "主机号输入不合法")
+  private String host;
 
-    @NotBlank(message = "用户名不能为空或为null")
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
-    private String username;
+  @NotNull(message = "端口号不能为null")
+  @Range(min = 0, max = 65535, message = "端口号输入不合法")
+  private Integer port;
 
-    @NotBlank(message = "密码不能为空或为null")
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
-    private String password;
+  @NotBlank(message = "用户名不能为空或为null")
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "用户名不能包含空格")
+  private String username;
 
-    @NotBlank(message = "连接名不能为空或为null")
-    @Length(min = 3, max = 100, message = "连接名长度必须在3-100之间")
-    @Pattern(regexp = "^[^ ]+$", message = "连接名不能包含空格")
-    private String alias;
+  @NotBlank(message = "密码不能为空或为null")
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "密码不能包含空格")
+  private String password;
 
-    @NotNull(message = "用户id不能为null")
-    private Integer userId;
+  @NotBlank(message = "连接名不能为空或为null")
+  @Length(min = 3, max = 100, message = "连接名长度必须在3-100之间")
+  @Pattern(regexp = "^[^ ]+$", message = "连接名不能包含空格")
+  private String alias;
 
+  @NotNull(message = "用户id不能为null")
+  private Integer userId;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
index 8d0abc4..7ce33e1 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Device.java
@@ -27,28 +27,29 @@ import org.hibernate.validator.constraints.Length;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
 @Data
 public class Device implements Serializable {
 
-    @TableId(type = IdType.AUTO)
-    private Integer id;
+  @TableId(type = IdType.AUTO)
+  private Integer id;
 
-    @NotNull(message = "未指定所属主机")
-    private String host;
+  @NotNull(message = "未指定所属主机")
+  private String host;
 
-    private String description;
+  private String description;
 
-    @NotBlank
-    @Length(min = 4, message = "创建者名长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
-    private String creator;
+  @NotBlank
+  @Length(min = 4, message = "创建者名长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
+  private String creator;
 
-    @NotNull(message = "未指定创建时间")
-    private Long createTime;
+  @NotNull(message = "未指定创建时间")
+  private Long createTime;
 
-    @NotBlank
-    @Pattern(regexp = "^[^ ]+$", message = "设备名不能包含空格")
-    private String deviceName;
+  @NotBlank
+  @Pattern(regexp = "^[^ ]+$", message = "设备名不能包含空格")
+  private String deviceName;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
index c6178a6..43f15f2 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Measurement.java
@@ -19,25 +19,25 @@
 
 package org.apache.iotdb.admin.model.entity;
 
-
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+
 import java.io.Serializable;
 
 @Data
 public class Measurement implements Serializable {
 
-    @TableId(type = IdType.AUTO)
-    private Integer id;
+  @TableId(type = IdType.AUTO)
+  private Integer id;
 
-    @NotNull(message = "未指定所属主机")
-    private String host;
+  @NotNull(message = "未指定所属主机")
+  private String host;
 
-    @NotNull(message = "未指定测点名")
-    private String measurementName;
+  @NotNull(message = "未指定测点名")
+  private String measurementName;
 
-    private String description;
+  private String description;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
index 0d98620..f2b7898 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/Query.java
@@ -24,19 +24,20 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+
 import java.io.Serializable;
 
 @Data
 public class Query implements Serializable {
 
-    @TableId(type = IdType.AUTO)
-    private Integer id;
+  @TableId(type = IdType.AUTO)
+  private Integer id;
 
-    @NotNull(message = "未指定所属连接id")
-    private Integer connectionId;
+  @NotNull(message = "未指定所属连接id")
+  private Integer connectionId;
 
-    @NotNull(message = "未指定脚本名")
-    private String queryName;
+  @NotNull(message = "未指定脚本名")
+  private String queryName;
 
-    private String sqls;
+  private String sqls;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
index 51e9e0e..8550ac8 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/StorageGroup.java
@@ -27,28 +27,27 @@ import org.hibernate.validator.constraints.Length;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
 @Data
 public class StorageGroup implements Serializable {
 
-    @TableId(type = IdType.AUTO)
-    private Integer id;
-
-    @NotNull(message = "未指定所属主机")
-    private String host;
+  @TableId(type = IdType.AUTO)
+  private Integer id;
 
-    private String description;
+  @NotNull(message = "未指定所属主机")
+  private String host;
 
-    @NotBlank
-    @Length(min = 4, message = "创建者名长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
-    private String creator;
+  private String description;
 
-    @NotNull(message = "未指定创建时间")
-    private Long createTime;
+  @NotBlank
+  @Length(min = 4, message = "创建者名长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "创建者名不能包含空格")
+  private String creator;
 
-    @NotBlank
-    private String groupName;
+  @NotNull(message = "未指定创建时间")
+  private Long createTime;
 
+  @NotBlank private String groupName;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java b/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
index 9df52b7..c778fd7 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/entity/User.java
@@ -27,23 +27,23 @@ import org.hibernate.validator.constraints.Length;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Null;
 import javax.validation.constraints.Pattern;
+
 import java.io.Serializable;
 
 @Data
 public class User implements Serializable {
 
-    @Null
-    @TableId(type = IdType.AUTO)
-    private Integer id;
-
-    @NotBlank
-    @Length(min = 4, message = "长度必须大于等于4")
-    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-    private String name;
+  @Null
+  @TableId(type = IdType.AUTO)
+  private Integer id;
 
-    @NotBlank
-    @Length(min = 6, message = "长度必须大于等于6")
-    @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
-    private String password;
+  @NotBlank
+  @Length(min = 4, message = "长度必须大于等于4")
+  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  private String name;
 
+  @NotBlank
+  @Length(min = 6, message = "长度必须大于等于6")
+  @Pattern(regexp = "^[^ ]+$", message = "不能包含空格")
+  private String password;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
index 07f1179..23eec26 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/BaseVO.java
@@ -21,38 +21,28 @@ package org.apache.iotdb.admin.model.vo;
 
 import lombok.Data;
 
-/**
- * 返回信息类
- */
+/** 返回信息类 */
 @Data
 public class BaseVO<T> {
 
-    /**
-     * 0 表示成功 其他表示错误类型
-     */
-    private String code;
-
-    /**
-     * 定义出错时候用户可读的信息
-     */
-    private String message;
+  /** 0 表示成功 其他表示错误类型 */
+  private String code;
 
-    /**
-     * 这是一个返回数据的通用类型模板
-     */
-    private T data;
+  /** 定义出错时候用户可读的信息 */
+  private String message;
 
-    public BaseVO() {
-    }
+  /** 这是一个返回数据的通用类型模板 */
+  private T data;
 
-    public BaseVO(String code, String message, T data) {
-        this.code = code;
-        this.message = message;
-        this.data = data;
-    }
+  public BaseVO() {}
 
-    public static <T> BaseVO<T> success(String message, T data) {
-        return new BaseVO<>("0", message, data);
-    }
+  public BaseVO(String code, String message, T data) {
+    this.code = code;
+    this.message = message;
+    this.data = data;
+  }
 
+  public static <T> BaseVO<T> success(String message, T data) {
+    return new BaseVO<>("0", message, data);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
index da2e511..0f33ac9 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnVO.java
@@ -25,14 +25,12 @@ import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
 
-/**
- * 展示别名及serverId
- */
+/** 展示别名及serverId */
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class ConnVO implements Serializable {
 
-    private Integer id;
-    private String alias;
+  private Integer id;
+  private String alias;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
index dbc50ce..ff7df4a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/ConnectionVO.java
@@ -26,15 +26,13 @@ import lombok.NoArgsConstructor;
 import java.io.Serializable;
 import java.util.List;
 
-/**
- * 展示用户的连接列表
- */
+/** 展示用户的连接列表 */
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class ConnectionVO implements Serializable {
 
-    List<ConnVO> aliasList;
-    Integer userId;
-    String name;
+  List<ConnVO> aliasList;
+  Integer userId;
+  String name;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
index 60a5a21..b182eef 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfo.java
@@ -26,9 +26,9 @@ import java.io.Serializable;
 @Data
 public class DeviceInfo implements Serializable {
 
-    private String deviceName;
-    private String description;
-    private String creator;
-    private Integer line;
-    private Integer deviceId;
+  private String deviceName;
+  private String description;
+  private String creator;
+  private Integer line;
+  private Integer deviceId;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
index 88f47bd..779973a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceInfoVO.java
@@ -27,7 +27,7 @@ import java.util.List;
 @Data
 public class DeviceInfoVO implements Serializable {
 
-    private List<DeviceInfo> deviceInfos;
-    private Integer totalCount;
-    private Integer totalPage;
+  private List<DeviceInfo> deviceInfos;
+  private Integer totalCount;
+  private Integer totalPage;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
index de0fec7..9030089 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/DeviceVO.java
@@ -26,8 +26,8 @@ import java.io.Serializable;
 @Data
 public class DeviceVO implements Serializable {
 
-    private String description;
-    private String creator;
-    private String time;
-    private Integer deviceId;
+  private String description;
+  private String creator;
+  private String time;
+  private Integer deviceId;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
index 5a3b320..f60f74d 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupInfoVO.java
@@ -24,14 +24,13 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
-import java.util.List;
 
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 public class GroupInfoVO implements Serializable {
 
-    private String groupName;
-    private Integer deviceCount;
-    private String description;
+  private String groupName;
+  private Integer deviceCount;
+  private String description;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
index efbf29c..09eeae3 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/GroupVO.java
@@ -26,11 +26,11 @@ import java.io.Serializable;
 @Data
 public class GroupVO implements Serializable {
 
-    private String groupName;
-    private String alias;
-    private String description;
-    private String creator;
-    private String createTime;
-    private String ttl;
-    private String ttiUnit;
+  private String groupName;
+  private String alias;
+  private String description;
+  private String creator;
+  private String createTime;
+  private String ttl;
+  private String ttiUnit;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java
index f5976ad..d8e89c5 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/IotDBUserVO.java
@@ -27,8 +27,8 @@ import java.util.List;
 @Data
 public class IotDBUserVO implements Serializable {
 
-    private String userName;
-    private String password;
-    private List<PrivilegeInfo> privilegesInfo;
-//    private List<RoleWithPrivilegesVO> roleWithPrivileges;
+  private String userName;
+  private String password;
+  private List<PrivilegeInfo> privilegesInfo;
+  //    private List<RoleWithPrivilegesVO> roleWithPrivileges;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
index 3e7574d..3606c51 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasurementVO.java
@@ -26,9 +26,9 @@ import java.io.Serializable;
 @Data
 public class MeasurementVO implements Serializable {
 
-    private String timeseries;
-    private String dataType;
-    private String encoding;
-    private String description;
-    private String newValue;
+  private String timeseries;
+  private String dataType;
+  private String encoding;
+  private String description;
+  private String newValue;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
index 35334dc..1c56d63 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/MeasuremtnInfoVO.java
@@ -27,7 +27,7 @@ import java.util.List;
 @Data
 public class MeasuremtnInfoVO implements Serializable {
 
-    private List<MeasurementVO> measurementVOList;
-    private Integer totalCount;
-    private Integer totalPage;
+  private List<MeasurementVO> measurementVOList;
+  private Integer totalCount;
+  private Integer totalPage;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java
index 0c9884e..258ac61 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PathVO.java
@@ -26,7 +26,7 @@ import java.io.Serializable;
 @Data
 public class PathVO implements Serializable {
 
-    private String groupName;
-    private String deviceName;
-    private String timeseriesName;
+  private String groupName;
+  private String deviceName;
+  private String timeseriesName;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java
index f1fc85a..af1c201 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/PrivilegeInfo.java
@@ -27,13 +27,13 @@ import java.util.List;
 @Data
 public class PrivilegeInfo implements Serializable {
 
-    // 0 1 2 3 对应 root、storageGroup、device、timeseries
-    private Integer type;
-    private List<String> groupPaths;
-    private List<String> devicePaths;
-    private List<String> timeseriesPaths;
-    private List<String> privileges;
-    private List<String> allTimeseriesPaths;
-    private List<String> allDevicePaths;
-    private List<String> allGroupPaths;
+  // 0 1 2 3 对应 root、storageGroup、device、timeseries
+  private Integer type;
+  private List<String> groupPaths;
+  private List<String> devicePaths;
+  private List<String> timeseriesPaths;
+  private List<String> privileges;
+  private List<String> allTimeseriesPaths;
+  private List<String> allDevicePaths;
+  private List<String> allGroupPaths;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
index 51d6ddc..0848dbe 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/QueryVO.java
@@ -26,6 +26,6 @@ import java.io.Serializable;
 @Data
 public class QueryVO implements Serializable {
 
-    private Integer id;
-    private String queryName;
+  private Integer id;
+  private String queryName;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
index 6b34ee1..696931e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RecordVO.java
@@ -28,6 +28,6 @@ import java.util.List;
 @Data
 public class RecordVO implements Serializable {
 
-    private List<Date> timeList;
-    private List<Long> valueList;
+  private List<Date> timeList;
+  private List<Long> valueList;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java
index 21ecfd7..704f09a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/RoleWithPrivilegesVO.java
@@ -23,12 +23,10 @@ import lombok.Data;
 
 import java.io.Serializable;
 
-/**
- * 角色及其对应权限
- */
+/** 角色及其对应权限 */
 @Data
 public class RoleWithPrivilegesVO implements Serializable {
 
-    private String role;
-    private String privilege;
+  private String role;
+  private String privilege;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
index c810248..d8ba158 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/SqlResultVO.java
@@ -24,14 +24,12 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.List;
 
-/**
- * sql查询的元数据列表和数据列表
- */
+/** sql查询的元数据列表和数据列表 */
 @Data
 public class SqlResultVO implements Serializable {
 
-    private List<String> metaDataList;
-    private List<List<String>> valueList;
-    private String queryTime;
-    private Long line;
+  private List<String> metaDataList;
+  private List<List<String>> valueList;
+  private String queryTime;
+  private Long line;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
index f6876a6..3303d9e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/StorageGroupVO.java
@@ -26,6 +26,6 @@ import java.io.Serializable;
 @Data
 public class StorageGroupVO implements Serializable {
 
-    private String groupName;
-    private Integer groupId;
-}
\ No newline at end of file
+  private String groupName;
+  private Integer groupId;
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java b/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
index 5b63a64..b5829a5 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/ConnectionService.java
@@ -27,15 +27,15 @@ import java.util.List;
 
 public interface ConnectionService {
 
-    List<ConnVO> getAllConnections(Integer id);
+  List<ConnVO> getAllConnections(Integer id);
 
-    void insert(Connection connection) throws BaseException;
+  void insert(Connection connection) throws BaseException;
 
-    void deleteById(Integer serverId, Integer userId) throws BaseException;
+  void deleteById(Integer serverId, Integer userId) throws BaseException;
 
-    Connection getById(Integer serverId) throws BaseException;
+  Connection getById(Integer serverId) throws BaseException;
 
-    void check(Integer serverId, Integer userId) throws BaseException;
+  void check(Integer serverId, Integer userId) throws BaseException;
 
-    void update(Connection connection) throws BaseException;
+  void update(Connection connection) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java b/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
index 5d9d202..d1de1b9 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/DeviceService.java
@@ -29,15 +29,15 @@ import java.util.List;
 
 public interface DeviceService {
 
-    List<Device> getDevices(String host, List<String> deviceNames);
+  List<Device> getDevices(String host, List<String> deviceNames);
 
-    void deleteDeviceInfo(String host, String groupName) throws BaseException;
+  void deleteDeviceInfo(String host, String groupName) throws BaseException;
 
-    void deleteDeviceInfoByDeviceName(String host, String deviceName) throws BaseException;
+  void deleteDeviceInfoByDeviceName(String host, String deviceName) throws BaseException;
 
-    void setDeviceInfo(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+  void setDeviceInfo(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException;
 
-    DeviceVO getDevice(String host, String deviceName);
+  DeviceVO getDevice(String host, String deviceName);
 
-    void updateDeviceInfo(DeviceInfoDTO deviceInfoDTO) throws BaseException;
+  void updateDeviceInfo(DeviceInfoDTO deviceInfoDTO) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java b/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
index 1155d55..76ee8c5 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/GroupService.java
@@ -28,17 +28,17 @@ import java.util.List;
 
 public interface GroupService {
 
-    List<String> getGroupDescription(String host, List<String> groupNames) throws BaseException;
+  List<String> getGroupDescription(String host, List<String> groupNames) throws BaseException;
 
-    void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
+  void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
 
-    boolean isExist(String host, String groupName);
+  boolean isExist(String host, String groupName);
 
-    void deleteGroupInfo(String host, String groupName) throws BaseException;
+  void deleteGroupInfo(String host, String groupName) throws BaseException;
 
-    StorageGroup getGroupInfo(String host, String groupName);
+  StorageGroup getGroupInfo(String host, String groupName);
 
-    void updateStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
+  void updateStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException;
 
-    Integer getGroupId(String host, String groupName);
+  Integer getGroupId(String host, String groupName);
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
index 82c15a3..83c6a4a 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
@@ -30,67 +30,78 @@ import java.util.List;
 
 public interface IotDBService {
 
-    List<String> getAllStorageGroups(Connection connection) throws BaseException;
+  List<String> getAllStorageGroups(Connection connection) throws BaseException;
 
-    void saveStorageGroup(Connection connection, String groupName) throws BaseException;
+  void saveStorageGroup(Connection connection, String groupName) throws BaseException;
 
-    void deleteStorageGroup(Connection connection, String groupName) throws BaseException;
+  void deleteStorageGroup(Connection connection, String groupName) throws BaseException;
 
-    CountDTO getDevicesByGroup(Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword) throws BaseException;
+  CountDTO getDevicesByGroup(
+      Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword)
+      throws BaseException;
 
-    CountDTO getMeasurementsByDevice(Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword) throws BaseException;
+  CountDTO getMeasurementsByDevice(
+      Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword)
+      throws BaseException;
 
-    List<String> getIotDBUserList(Connection connection) throws BaseException;
+  List<String> getIotDBUserList(Connection connection) throws BaseException;
 
-    List<String> getIotDBRoleList(Connection connection) throws BaseException;
+  List<String> getIotDBRoleList(Connection connection) throws BaseException;
 
-    IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException;
+  IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException;
 
-    void deleteIotDBUser(Connection connection, String userName) throws BaseException;
+  void deleteIotDBUser(Connection connection, String userName) throws BaseException;
 
-    void deleteIotDBRole(Connection connection, String roleName) throws BaseException;
+  void deleteIotDBRole(Connection connection, String roleName) throws BaseException;
 
-    void setIotDBUser(Connection connection, IotDBUser iotDBUserVO) throws BaseException;
+  void setIotDBUser(Connection connection, IotDBUser iotDBUserVO) throws BaseException;
 
-    void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException;
+  void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException;
 
-    void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries) throws BaseException;
+  void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries)
+      throws BaseException;
 
-    void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException;
+  void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException;
 
-    SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException;
+  SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException;
 
-    List<Integer> getDevicesCount(Connection connection, List<String> groupNames) throws BaseException;
+  List<Integer> getDevicesCount(Connection connection, List<String> groupNames)
+      throws BaseException;
 
-    void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException;
+  void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException;
 
-    void cancelGroupTtl(Connection connection, String groupName) throws BaseException;
+  void cancelGroupTtl(Connection connection, String groupName) throws BaseException;
 
-    Integer getDeviceCount(Connection connection, String groupName) throws BaseException;
+  Integer getDeviceCount(Connection connection, String groupName) throws BaseException;
 
-    List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames) throws BaseException;
+  List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames)
+      throws BaseException;
 
-    void deleteTimeseriesByDevice(Connection connection, String deviceName) throws BaseException;
+  void deleteTimeseriesByDevice(Connection connection, String deviceName) throws BaseException;
 
-    void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+  void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO)
+      throws BaseException;
 
-    Integer getMeasurementsCount(Connection connection, String deviceName) throws BaseException;
+  Integer getMeasurementsCount(Connection connection, String deviceName) throws BaseException;
 
-    String getLastMeasurementValue(Connection connection, String timeseries) throws BaseException;
+  String getLastMeasurementValue(Connection connection, String timeseries) throws BaseException;
 
-    String getGroupTTL(Connection connection, String groupName) throws BaseException;
+  String getGroupTTL(Connection connection, String groupName) throws BaseException;
 
-    List<String> getDevices(Connection connection, String groupName) throws BaseException;
+  List<String> getDevices(Connection connection, String groupName) throws BaseException;
 
-    List<String> getTimeseries(Connection connection, String deviceName) throws BaseException;
+  List<String> getTimeseries(Connection connection, String deviceName) throws BaseException;
 
-    void setUserPrivileges(Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO) throws BaseException;
+  void setUserPrivileges(Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO)
+      throws BaseException;
 
-    RecordVO getRecords(Connection connection, String deviceName, String timeseriesName) throws BaseException;
+  RecordVO getRecords(Connection connection, String deviceName, String timeseriesName)
+      throws BaseException;
 
-    List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp) throws BaseException;
+  List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp)
+      throws BaseException;
 
-    void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException;
+  void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException;
 
-    void stopQuery(Integer serverId, Long timestamp) throws BaseException;
+  void stopQuery(Integer serverId, Long timestamp) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java b/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
index 64240db..1c0e699 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/MeasurementService.java
@@ -24,13 +24,13 @@ import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
 
 public interface MeasurementService {
 
-    void deleteMeasurementInfo(String host, String groupName) throws BaseException;
+  void deleteMeasurementInfo(String host, String groupName) throws BaseException;
 
-    void deleteMeasurementInfoByDeviceName(String host, String deviceName) throws BaseException;
+  void deleteMeasurementInfoByDeviceName(String host, String deviceName) throws BaseException;
 
-    void setMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+  void setMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException;
 
-    String getDescription(String host, String timeseries) throws BaseException;
+  String getDescription(String host, String timeseries) throws BaseException;
 
-    void updateMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException;
+  void updateMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java b/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
index 613966f..eeb8138 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/QueryService.java
@@ -27,13 +27,13 @@ import java.util.List;
 
 public interface QueryService {
 
-    void save(Integer serverId, Query query) throws BaseException;
+  void save(Integer serverId, Query query) throws BaseException;
 
-    void update(Integer serverId, Query query) throws BaseException;
+  void update(Integer serverId, Query query) throws BaseException;
 
-    List<QueryVO> getQueryList(Integer serverId);
+  List<QueryVO> getQueryList(Integer serverId);
 
-    void deleteQuery(Integer queryId) throws BaseException;
+  void deleteQuery(Integer queryId) throws BaseException;
 
-    Query getQuery(Integer queryId) throws BaseException;
+  Query getQuery(Integer queryId) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java b/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
index d263646..fb9c1e2 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/UserService.java
@@ -24,9 +24,9 @@ import org.apache.iotdb.admin.model.entity.User;
 
 public interface UserService {
 
-    User login(String name, String password) throws BaseException;
+  User login(String name, String password) throws BaseException;
 
-    void insert(User user) throws BaseException;
+  void insert(User user) throws BaseException;
 
-    void delete(Integer userId) throws BaseException;
+  void delete(Integer userId) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
index 40dedbc..670f0cb 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/ConnectionServiceImpl.java
@@ -19,14 +19,15 @@
 
 package org.apache.iotdb.admin.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.mapper.ConnectionMapper;
 import org.apache.iotdb.admin.model.entity.Connection;
 import org.apache.iotdb.admin.model.vo.ConnVO;
 import org.apache.iotdb.admin.service.ConnectionService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -34,95 +35,94 @@ import java.util.ArrayList;
 import java.util.List;
 
 @Service
-public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connection> implements ConnectionService {
+public class ConnectionServiceImpl extends ServiceImpl<ConnectionMapper, Connection>
+    implements ConnectionService {
 
-    @Autowired
-    private ConnectionMapper connectionMapper;
+  @Autowired private ConnectionMapper connectionMapper;
 
-    @Override
-    public List<ConnVO> getAllConnections(Integer userId) {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("user_id", userId);
-        List<Connection> connections = connectionMapper.selectList(queryWrapper);
-        List<ConnVO> ConnVOs = new ArrayList();
-        for (Connection connection : connections) {
-            ConnVOs.add(new ConnVO(connection.getId(), connection.getAlias()));
-        }
-        return ConnVOs;
+  @Override
+  public List<ConnVO> getAllConnections(Integer userId) {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("user_id", userId);
+    List<Connection> connections = connectionMapper.selectList(queryWrapper);
+    List<ConnVO> ConnVOs = new ArrayList();
+    for (Connection connection : connections) {
+      ConnVOs.add(new ConnVO(connection.getId(), connection.getAlias()));
     }
+    return ConnVOs;
+  }
 
-    @Override
-    public void insert(Connection connection) throws BaseException {
-        String alias = connection.getAlias();
-        Integer userId = connection.getUserId();
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("user_id", userId);
-        queryWrapper.eq("alias", alias);
-        Connection existConnection = connectionMapper.selectOne(queryWrapper);
-        // 别名唯一
-        if (existConnection != null) {
-            throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
-        }
-        if ("127.0.0.1".equals(connection.getHost())) {
-            connection.setHost("localhost");
-        }
-        int flag = connectionMapper.insert(connection);
-        if (flag <= 0) {
-            throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
-        }
+  @Override
+  public void insert(Connection connection) throws BaseException {
+    String alias = connection.getAlias();
+    Integer userId = connection.getUserId();
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("user_id", userId);
+    queryWrapper.eq("alias", alias);
+    Connection existConnection = connectionMapper.selectOne(queryWrapper);
+    // 别名唯一
+    if (existConnection != null) {
+      throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
     }
-
-    @Override
-    public void deleteById(Integer serverId, Integer userId) throws BaseException {
-        try {
-            connectionMapper.deleteById(serverId);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.DELETE_CONN_FAIL, ErrorCode.DELETE_CONN_FAIL_MSG);
-        }
+    if ("127.0.0.1".equals(connection.getHost())) {
+      connection.setHost("localhost");
+    }
+    int flag = connectionMapper.insert(connection);
+    if (flag <= 0) {
+      throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
     }
+  }
 
-    @Override
-    public Connection getById(Integer serverId) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("id", serverId);
-        try {
-            Connection connection = connectionMapper.selectOne(queryWrapper);
-            if (connection == null) {
-                throw new BaseException(ErrorCode.NO_CONN, ErrorCode.NO_CONN_MSG);
-            }
-            return connection;
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.GET_CONN_FAIL, ErrorCode.GET_CONN_FAIL_MSG);
-        }
+  @Override
+  public void deleteById(Integer serverId, Integer userId) throws BaseException {
+    try {
+      connectionMapper.deleteById(serverId);
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.DELETE_CONN_FAIL, ErrorCode.DELETE_CONN_FAIL_MSG);
     }
+  }
 
-    @Override
-    public void check(Integer serverId, Integer userId) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("id", serverId);
-        queryWrapper.eq("user_id", userId);
-        Connection connection = connectionMapper.selectOne(queryWrapper);
-        if (connection == null) {
-            throw new BaseException(ErrorCode.CHECK_FAIL, ErrorCode.CHECK_FAIL_MSG);
-        }
+  @Override
+  public Connection getById(Integer serverId) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("id", serverId);
+    try {
+      Connection connection = connectionMapper.selectOne(queryWrapper);
+      if (connection == null) {
+        throw new BaseException(ErrorCode.NO_CONN, ErrorCode.NO_CONN_MSG);
+      }
+      return connection;
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.GET_CONN_FAIL, ErrorCode.GET_CONN_FAIL_MSG);
     }
+  }
 
-    @Override
-    public void update(Connection connection) throws BaseException {
-        String alias = connection.getAlias();
-        Integer userId = connection.getUserId();
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("user_id", userId);
-        queryWrapper.eq("alias", alias);
-        Connection existConnection = connectionMapper.selectOne(queryWrapper);
-        // 别名唯一
-        if (existConnection != null && !connection.getId().equals(existConnection.getId())) {
-            throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
-        }
-        int flag = connectionMapper.updateById(connection);
-        if (flag <= 0) {
-            throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
-        }
+  @Override
+  public void check(Integer serverId, Integer userId) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("id", serverId);
+    queryWrapper.eq("user_id", userId);
+    Connection connection = connectionMapper.selectOne(queryWrapper);
+    if (connection == null) {
+      throw new BaseException(ErrorCode.CHECK_FAIL, ErrorCode.CHECK_FAIL_MSG);
     }
+  }
 
+  @Override
+  public void update(Connection connection) throws BaseException {
+    String alias = connection.getAlias();
+    Integer userId = connection.getUserId();
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("user_id", userId);
+    queryWrapper.eq("alias", alias);
+    Connection existConnection = connectionMapper.selectOne(queryWrapper);
+    // 别名唯一
+    if (existConnection != null && !connection.getId().equals(existConnection.getId())) {
+      throw new BaseException(ErrorCode.ALIAS_REPEAT, ErrorCode.ALIAS_REPEAT_MSG);
+    }
+    int flag = connectionMapper.updateById(connection);
+    if (flag <= 0) {
+      throw new BaseException(ErrorCode.INSERT_CONN_FAIL, ErrorCode.INSERT_CONN_FAIL_MSG);
+    }
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
index d507d91..0687f5c 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/DeviceServiceImpl.java
@@ -19,8 +19,6 @@
 
 package org.apache.iotdb.admin.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.mapper.DeviceMapper;
@@ -29,6 +27,9 @@ import org.apache.iotdb.admin.model.entity.Connection;
 import org.apache.iotdb.admin.model.entity.Device;
 import org.apache.iotdb.admin.model.vo.DeviceVO;
 import org.apache.iotdb.admin.service.DeviceService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -40,105 +41,106 @@ import java.util.List;
 @Service
 public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
 
+  @Autowired private DeviceMapper deviceMapper;
 
-    @Autowired
-    private DeviceMapper deviceMapper;
-
-    @Override
-    public List<Device> getDevices(String host, List<String> deviceNames) {
-        List<Device> devices = new ArrayList<>();
-        for (String deviceName : deviceNames) {
-            QueryWrapper queryWrapper = new QueryWrapper();
-            queryWrapper.eq("host", host);
-            queryWrapper.eq("device_name", deviceName);
-            Device device = deviceMapper.selectOne(queryWrapper);
-            devices.add(device);
-        }
-        return devices;
+  @Override
+  public List<Device> getDevices(String host, List<String> deviceNames) {
+    List<Device> devices = new ArrayList<>();
+    for (String deviceName : deviceNames) {
+      QueryWrapper queryWrapper = new QueryWrapper();
+      queryWrapper.eq("host", host);
+      queryWrapper.eq("device_name", deviceName);
+      Device device = deviceMapper.selectOne(queryWrapper);
+      devices.add(device);
     }
+    return devices;
+  }
 
-    @Override
-    public void deleteDeviceInfo(String host, String groupName) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.like("device_name", groupName);
-        try {
-            deviceMapper.delete(queryWrapper);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.DELETE_DEVICE_INFO_FAIL, ErrorCode.DELETE_DEVICE_INFO_FAIL_MSG);
-        }
+  @Override
+  public void deleteDeviceInfo(String host, String groupName) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.like("device_name", groupName);
+    try {
+      deviceMapper.delete(queryWrapper);
+    } catch (Exception e) {
+      throw new BaseException(
+          ErrorCode.DELETE_DEVICE_INFO_FAIL, ErrorCode.DELETE_DEVICE_INFO_FAIL_MSG);
     }
+  }
 
-    @Override
-    public void deleteDeviceInfoByDeviceName(String host, String deviceName) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("device_name", deviceName);
-        try {
-            deviceMapper.delete(queryWrapper);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.DELETE_DEVICE_INFO_FAIL, ErrorCode.DELETE_DEVICE_INFO_FAIL_MSG);
-        }
+  @Override
+  public void deleteDeviceInfoByDeviceName(String host, String deviceName) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("device_name", deviceName);
+    try {
+      deviceMapper.delete(queryWrapper);
+    } catch (Exception e) {
+      throw new BaseException(
+          ErrorCode.DELETE_DEVICE_INFO_FAIL, ErrorCode.DELETE_DEVICE_INFO_FAIL_MSG);
     }
+  }
 
-    @Override
-    public void setDeviceInfo(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", connection.getHost());
-        queryWrapper.eq("device_name", deviceInfoDTO.getDeviceName());
-        Device existDevice = deviceMapper.selectOne(queryWrapper);
-        if (existDevice == null) {
-            Device device = new Device();
-            device.setCreator(connection.getUsername());
-            device.setDeviceName(deviceInfoDTO.getDeviceName());
-            device.setCreateTime(System.currentTimeMillis());
-            device.setHost(connection.getHost());
-            device.setDescription(deviceInfoDTO.getDescription());
-            int flag = deviceMapper.insert(device);
-            if (flag <= 0) {
-                throw new BaseException(ErrorCode.SET_DEVICE_INFO_FAIL, ErrorCode.SET_DEVICE_INFO_FAIL_MSG);
-            }
-            return;
-        }
-        existDevice.setDescription(deviceInfoDTO.getDescription());
-        int flag = deviceMapper.updateById(existDevice);
-        if (flag <= 0) {
-            throw new BaseException(ErrorCode.SET_DEVICE_INFO_FAIL, ErrorCode.SET_DEVICE_INFO_FAIL_MSG);
-        }
+  @Override
+  public void setDeviceInfo(Connection connection, DeviceInfoDTO deviceInfoDTO)
+      throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", connection.getHost());
+    queryWrapper.eq("device_name", deviceInfoDTO.getDeviceName());
+    Device existDevice = deviceMapper.selectOne(queryWrapper);
+    if (existDevice == null) {
+      Device device = new Device();
+      device.setCreator(connection.getUsername());
+      device.setDeviceName(deviceInfoDTO.getDeviceName());
+      device.setCreateTime(System.currentTimeMillis());
+      device.setHost(connection.getHost());
+      device.setDescription(deviceInfoDTO.getDescription());
+      int flag = deviceMapper.insert(device);
+      if (flag <= 0) {
+        throw new BaseException(ErrorCode.SET_DEVICE_INFO_FAIL, ErrorCode.SET_DEVICE_INFO_FAIL_MSG);
+      }
+      return;
+    }
+    existDevice.setDescription(deviceInfoDTO.getDescription());
+    int flag = deviceMapper.updateById(existDevice);
+    if (flag <= 0) {
+      throw new BaseException(ErrorCode.SET_DEVICE_INFO_FAIL, ErrorCode.SET_DEVICE_INFO_FAIL_MSG);
     }
+  }
 
-    @Override
-    public DeviceVO getDevice(String host, String deviceName) {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("device_name", deviceName);
-        Device device = deviceMapper.selectOne(queryWrapper);
-        // 非系统创建的设备没有设备信息
-        DeviceVO deviceVO = new DeviceVO();
-        if (device != null) {
-            deviceVO.setCreator(device.getCreator());
-            deviceVO.setDescription(device.getDescription());
-            deviceVO.setDeviceId(device.getId());
-            Long createTime = device.getCreateTime();
-            Date date = new Date(createTime);
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
-            String time = sdf.format(date);
-            deviceVO.setTime(time);
-            return deviceVO;
-        }
-        return deviceVO;
+  @Override
+  public DeviceVO getDevice(String host, String deviceName) {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("device_name", deviceName);
+    Device device = deviceMapper.selectOne(queryWrapper);
+    // 非系统创建的设备没有设备信息
+    DeviceVO deviceVO = new DeviceVO();
+    if (device != null) {
+      deviceVO.setCreator(device.getCreator());
+      deviceVO.setDescription(device.getDescription());
+      deviceVO.setDeviceId(device.getId());
+      Long createTime = device.getCreateTime();
+      Date date = new Date(createTime);
+      SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+      String time = sdf.format(date);
+      deviceVO.setTime(time);
+      return deviceVO;
     }
+    return deviceVO;
+  }
 
-    @Override
-    public void updateDeviceInfo(DeviceInfoDTO deviceInfoDTO) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("id", deviceInfoDTO.getDeviceId());
-        Device existDevice = deviceMapper.selectOne(queryWrapper);
-        if (existDevice != null) {
-            existDevice.setDescription(deviceInfoDTO.getDescription());
-            deviceMapper.updateById(existDevice);
-            return;
-        }
-        throw new BaseException(ErrorCode.NO_DEVICE_INFO, ErrorCode.NO_DEVICE_INFO_MSG);
+  @Override
+  public void updateDeviceInfo(DeviceInfoDTO deviceInfoDTO) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("id", deviceInfoDTO.getDeviceId());
+    Device existDevice = deviceMapper.selectOne(queryWrapper);
+    if (existDevice != null) {
+      existDevice.setDescription(deviceInfoDTO.getDescription());
+      deviceMapper.updateById(existDevice);
+      return;
     }
+    throw new BaseException(ErrorCode.NO_DEVICE_INFO, ErrorCode.NO_DEVICE_INFO_MSG);
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
index 7ae2122..5ae53be 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/GroupServiceImpl.java
@@ -19,8 +19,6 @@
 
 package org.apache.iotdb.admin.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.mapper.GroupMapper;
@@ -28,6 +26,9 @@ import org.apache.iotdb.admin.model.dto.GroupDTO;
 import org.apache.iotdb.admin.model.entity.Connection;
 import org.apache.iotdb.admin.model.entity.StorageGroup;
 import org.apache.iotdb.admin.service.GroupService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -35,123 +36,128 @@ import java.util.ArrayList;
 import java.util.List;
 
 @Service
-public class GroupServiceImpl extends ServiceImpl<GroupMapper, StorageGroup> implements GroupService {
+public class GroupServiceImpl extends ServiceImpl<GroupMapper, StorageGroup>
+    implements GroupService {
 
+  @Autowired private GroupMapper groupMapper;
 
-    @Autowired
-    private GroupMapper groupMapper;
-
-    @Override
-    public List<String> getGroupDescription(String host, List<String> groupNames) throws BaseException {
-        List<String> descriptions = new ArrayList<>();
-        for (String groupName : groupNames) {
-            descriptions.add(getDescription(host, groupName));
-        }
-        return descriptions;
+  @Override
+  public List<String> getGroupDescription(String host, List<String> groupNames)
+      throws BaseException {
+    List<String> descriptions = new ArrayList<>();
+    for (String groupName : groupNames) {
+      descriptions.add(getDescription(host, groupName));
     }
+    return descriptions;
+  }
 
-    @Override
-    public void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        String host = connection.getHost();
-        String groupName = groupDTO.getGroupName();
-        String description = groupDTO.getDescription();
-        if ("127.0.0.1".equals(host)) {
-            host = "localhost";
-        }
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("group_name", groupName);
-        StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
-        if (storageGroup != null) {
-            storageGroup.setDescription(description);
-            int flag = groupMapper.updateById(storageGroup);
-            if (flag <= 0) {
-                throw new BaseException(ErrorCode.INSERT_GROUP_INFO_FAIL, ErrorCode.INSERT_GROUP_INFO_FAIL_MSG);
-            }
-            return;
-        }
-        String username = connection.getUsername();
-        StorageGroup group = new StorageGroup();
-        group.setCreateTime(System.currentTimeMillis());
-        group.setCreator(username);
-        group.setGroupName(groupName);
-        group.setDescription(description);
-        group.setHost(host);
-        int flag = groupMapper.insert(group);
-        if (flag <= 0) {
-            throw new BaseException(ErrorCode.INSERT_GROUP_INFO_FAIL, ErrorCode.INSERT_GROUP_INFO_FAIL_MSG);
-        }
+  @Override
+  public void setStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    String host = connection.getHost();
+    String groupName = groupDTO.getGroupName();
+    String description = groupDTO.getDescription();
+    if ("127.0.0.1".equals(host)) {
+      host = "localhost";
     }
-
-    @Override
-    public boolean isExist(String host, String groupName) {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("group_name", groupName);
-        StorageGroup group = groupMapper.selectOne(queryWrapper);
-        if (group != null) {
-            return true;
-        }
-        return false;
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("group_name", groupName);
+    StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
+    if (storageGroup != null) {
+      storageGroup.setDescription(description);
+      int flag = groupMapper.updateById(storageGroup);
+      if (flag <= 0) {
+        throw new BaseException(
+            ErrorCode.INSERT_GROUP_INFO_FAIL, ErrorCode.INSERT_GROUP_INFO_FAIL_MSG);
+      }
+      return;
     }
+    String username = connection.getUsername();
+    StorageGroup group = new StorageGroup();
+    group.setCreateTime(System.currentTimeMillis());
+    group.setCreator(username);
+    group.setGroupName(groupName);
+    group.setDescription(description);
+    group.setHost(host);
+    int flag = groupMapper.insert(group);
+    if (flag <= 0) {
+      throw new BaseException(
+          ErrorCode.INSERT_GROUP_INFO_FAIL, ErrorCode.INSERT_GROUP_INFO_FAIL_MSG);
+    }
+  }
 
-    @Override
-    public void deleteGroupInfo(String host, String groupName) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("group_name", groupName);
-        try {
-            groupMapper.delete(queryWrapper);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.DELETE_GROUP_INFO_FAIL, ErrorCode.DELETE_GROUP_INFO_FAIL_MSG);
-        }
+  @Override
+  public boolean isExist(String host, String groupName) {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("group_name", groupName);
+    StorageGroup group = groupMapper.selectOne(queryWrapper);
+    if (group != null) {
+      return true;
     }
+    return false;
+  }
 
-    @Override
-    public StorageGroup getGroupInfo(String host, String groupName) {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("group_name", groupName);
-        return groupMapper.selectOne(queryWrapper);
+  @Override
+  public void deleteGroupInfo(String host, String groupName) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("group_name", groupName);
+    try {
+      groupMapper.delete(queryWrapper);
+    } catch (Exception e) {
+      throw new BaseException(
+          ErrorCode.DELETE_GROUP_INFO_FAIL, ErrorCode.DELETE_GROUP_INFO_FAIL_MSG);
     }
+  }
+
+  @Override
+  public StorageGroup getGroupInfo(String host, String groupName) {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("group_name", groupName);
+    return groupMapper.selectOne(queryWrapper);
+  }
 
-    @Override
-    public void updateStorageGroupInfo(Connection connection, GroupDTO groupDTO) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", connection.getHost());
-        queryWrapper.eq("group_name", groupDTO.getGroupName());
-        StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
-        if (storageGroup != null) {
-            storageGroup.setDescription(groupDTO.getDescription());
-            int flag = groupMapper.updateById(storageGroup);
-            if (flag <= 0) {
-                throw new BaseException(ErrorCode.UPDATE_GROUP_INFO_FAIL, ErrorCode.UPDATE_GROUP_INFO_FAIL_MSG);
-            }
-            return;
-        }
-        throw new BaseException(ErrorCode.NO_GROUP_INFO, ErrorCode.NO_GROUP_INFO_MSG);
+  @Override
+  public void updateStorageGroupInfo(Connection connection, GroupDTO groupDTO)
+      throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", connection.getHost());
+    queryWrapper.eq("group_name", groupDTO.getGroupName());
+    StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
+    if (storageGroup != null) {
+      storageGroup.setDescription(groupDTO.getDescription());
+      int flag = groupMapper.updateById(storageGroup);
+      if (flag <= 0) {
+        throw new BaseException(
+            ErrorCode.UPDATE_GROUP_INFO_FAIL, ErrorCode.UPDATE_GROUP_INFO_FAIL_MSG);
+      }
+      return;
     }
+    throw new BaseException(ErrorCode.NO_GROUP_INFO, ErrorCode.NO_GROUP_INFO_MSG);
+  }
 
-    @Override
-    public Integer getGroupId(String host, String groupName) {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("group_name", groupName);
-        StorageGroup group = groupMapper.selectOne(queryWrapper);
-        if (group != null) {
-            return group.getId();
-        }
-        return null;
+  @Override
+  public Integer getGroupId(String host, String groupName) {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("group_name", groupName);
+    StorageGroup group = groupMapper.selectOne(queryWrapper);
+    if (group != null) {
+      return group.getId();
     }
+    return null;
+  }
 
-    private String getDescription(String host, String groupName) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("group_name", groupName);
-        StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
-        if (storageGroup != null) {
-            return storageGroup.getDescription();
-        }
-        return null;
+  private String getDescription(String host, String groupName) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("group_name", groupName);
+    StorageGroup storageGroup = groupMapper.selectOne(queryWrapper);
+    if (storageGroup != null) {
+      return storageGroup.getDescription();
     }
+    return null;
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
index 5a69eac..1c56635 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.admin.service.impl;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.model.dto.*;
@@ -34,6 +33,8 @@ import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.common.RowRecord;
+
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -41,1817 +42,1926 @@ import org.springframework.stereotype.Service;
 import java.lang.reflect.Field;
 import java.sql.*;
 import java.text.SimpleDateFormat;
-import java.util.Date;
 import java.util.*;
+import java.util.Date;
 import java.util.concurrent.*;
 
 @Service
 public class IotDBServiceImpl implements IotDBService {
 
-    private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
-
-    private static final HashMap<String, Boolean> SPECIAL_PRIVILEGES = new HashMap();
-
-    private static final String NO_NEED_PRIVILEGES = "SET_STORAGE_GROUP";
-
-    private static final List<String> PRIVILEGES = new ArrayList<>();
-
-    private static final HashMap<String, Boolean> QUERY_STOP = new HashMap<>();
-
-    static {
-        SPECIAL_PRIVILEGES.put("CREATE_TIMESERIES", true);
-        SPECIAL_PRIVILEGES.put("INSERT_TIMESERIES", true);
-        SPECIAL_PRIVILEGES.put("READ_TIMESERIES", true);
-        SPECIAL_PRIVILEGES.put("DELETE_TIMESERIES", true);
+  private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
+
+  private static final HashMap<String, Boolean> SPECIAL_PRIVILEGES = new HashMap();
+
+  private static final String NO_NEED_PRIVILEGES = "SET_STORAGE_GROUP";
+
+  private static final List<String> PRIVILEGES = new ArrayList<>();
+
+  private static final HashMap<String, Boolean> QUERY_STOP = new HashMap<>();
+
+  static {
+    SPECIAL_PRIVILEGES.put("CREATE_TIMESERIES", true);
+    SPECIAL_PRIVILEGES.put("INSERT_TIMESERIES", true);
+    SPECIAL_PRIVILEGES.put("READ_TIMESERIES", true);
+    SPECIAL_PRIVILEGES.put("DELETE_TIMESERIES", true);
+  }
+
+  static {
+    PRIVILEGES.add("SET_STORAGE_GROUP");
+    PRIVILEGES.add("CREATE_TIMESERIES");
+    PRIVILEGES.add("INSERT_TIMESERIES");
+    PRIVILEGES.add("READ_TIMESERIES");
+    PRIVILEGES.add("DELETE_TIMESERIES");
+    PRIVILEGES.add("CREATE_USER");
+    PRIVILEGES.add("DELETE_USER");
+    PRIVILEGES.add("MODIFY_PASSWORD");
+    PRIVILEGES.add("LIST_USER");
+    PRIVILEGES.add("GRANT_USER_PRIVILEGE");
+    PRIVILEGES.add("REVOKE_USER_PRIVILEGE");
+    PRIVILEGES.add("CREATE_FUNCTION");
+    PRIVILEGES.add("DROP_FUNCTION");
+    PRIVILEGES.add("CREATE_TRIGGER");
+    PRIVILEGES.add("DROP_TRIGGER");
+    PRIVILEGES.add("START_TRIGGER");
+    PRIVILEGES.add("STOP_TRIGGER");
+  }
+
+  @Override
+  public List<String> getAllStorageGroups(Connection connection) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "show storage group";
+    List<String> users = executeQueryOneColumn(sessionPool, sql);
+    sessionPool.close();
+    return users;
+  }
+
+  @Override
+  public void saveStorageGroup(Connection connection, String groupName) throws BaseException {
+    paramValid(groupName);
+    SessionPool sessionPool = getSessionPool(connection);
+    try {
+      sessionPool.setStorageGroup(groupName);
+    } catch (StatementExecutionException e) {
+      // 300为存储组重复或者其前/后路径上已经有存储组了
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_SET_GROUP, ErrorCode.NO_PRI_SET_GROUP_MSG);
+      }
+      if (e.getStatusCode() == 300) {
+        throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
+      }
+      logger.error(e.getMessage());
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
+        sessionPool.close();
+      }
     }
-
-    static {
-        PRIVILEGES.add("SET_STORAGE_GROUP");
-        PRIVILEGES.add("CREATE_TIMESERIES");
-        PRIVILEGES.add("INSERT_TIMESERIES");
-        PRIVILEGES.add("READ_TIMESERIES");
-        PRIVILEGES.add("DELETE_TIMESERIES");
-        PRIVILEGES.add("CREATE_USER");
-        PRIVILEGES.add("DELETE_USER");
-        PRIVILEGES.add("MODIFY_PASSWORD");
-        PRIVILEGES.add("LIST_USER");
-        PRIVILEGES.add("GRANT_USER_PRIVILEGE");
-        PRIVILEGES.add("REVOKE_USER_PRIVILEGE");
-        PRIVILEGES.add("CREATE_FUNCTION");
-        PRIVILEGES.add("DROP_FUNCTION");
-        PRIVILEGES.add("CREATE_TRIGGER");
-        PRIVILEGES.add("DROP_TRIGGER");
-        PRIVILEGES.add("START_TRIGGER");
-        PRIVILEGES.add("STOP_TRIGGER");
+  }
+
+  @Override
+  public void deleteStorageGroup(Connection connection, String groupName) throws BaseException {
+    paramValid(groupName);
+    SessionPool sessionPool = getSessionPool(connection);
+    try {
+      sessionPool.deleteStorageGroup(groupName);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_DELETE_GROUP, ErrorCode.NO_PRI_DELETE_GROUP_MSG);
+      }
+      throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
+        sessionPool.close();
+      }
     }
-
-
-    @Override
-    public List<String> getAllStorageGroups(Connection connection) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "show storage group";
-        List<String> users = executeQueryOneColumn(sessionPool, sql);
+  }
+
+  @Override
+  public CountDTO getDevicesByGroup(
+      Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword)
+      throws BaseException {
+    paramValid(groupName);
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "show devices " + groupName;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      List<String> values = new ArrayList<>();
+      int count = 0;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+          if (keyword != null || "".equals(keyword)) {
+            String deviceName = fields.get(0).toString();
+            deviceName = StringUtils.removeStart(deviceName, groupName + ".");
+            if (deviceName.contains(keyword)) {
+              count++;
+            } else {
+              continue;
+            }
+            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+              values.add(fields.get(0).toString());
+            }
+          } else {
+            count++;
+            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+              values.add(fields.get(0).toString());
+            }
+          }
+        }
+      }
+      CountDTO countDTO = new CountDTO();
+      countDTO.setObjects(values);
+      countDTO.setTotalCount(count);
+      Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+      countDTO.setTotalPage(totalPage);
+      return countDTO;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
+      if (sessionPool != null) {
         sessionPool.close();
-        return users;
+      }
     }
-
-    @Override
-    public void saveStorageGroup(Connection connection, String groupName) throws BaseException {
-        paramValid(groupName);
-        SessionPool sessionPool = getSessionPool(connection);
-        try {
-            sessionPool.setStorageGroup(groupName);
-        } catch (StatementExecutionException e) {
-            // 300为存储组重复或者其前/后路径上已经有存储组了
-            if (e.getStatusCode() == 602) {
-                throw new BaseException(ErrorCode.NO_PRI_SET_GROUP, ErrorCode.NO_PRI_SET_GROUP_MSG);
-            }
-            if (e.getStatusCode() == 300) {
-                throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
-            }
-            logger.error(e.getMessage());
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SET_GROUP_FAIL, ErrorCode.SET_GROUP_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+  }
+
+  @Override
+  public CountDTO getMeasurementsByDevice(
+      Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword)
+      throws BaseException {
+    paramValid(deviceName);
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "show timeseries " + deviceName;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      List<MeasurementDTO> results = new ArrayList<>();
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      int count = 0;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+          if (keyword != null || "".equals(keyword)) {
+            String measurementName = fields.get(0).toString();
+            measurementName = StringUtils.removeStart(measurementName, deviceName + ".");
+            if (measurementName.contains(keyword)) {
+              count++;
+            } else {
+              continue;
+            }
+            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+              MeasurementDTO t = new MeasurementDTO();
+              List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+              for (int i = 0; i < fields.size(); i++) {
+                Field field =
+                    MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+                field.setAccessible(true);
+                field.set(t, fields.get(i).toString());
+              }
+              results.add(t);
+            }
+          } else {
+            count++;
+            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+              MeasurementDTO t = new MeasurementDTO();
+              List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+              for (int i = 0; i < fields.size(); i++) {
+                Field field =
+                    MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+                field.setAccessible(true);
+                field.set(t, fields.get(i).toString());
+              }
+              results.add(t);
+            }
+          }
+        }
+      }
+      CountDTO countDTO = new CountDTO();
+      countDTO.setObjects(results);
+      countDTO.setTotalCount(count);
+      Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+      countDTO.setTotalPage(totalPage);
+      return countDTO;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+    } catch (Exception e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
     }
-
-    @Override
-    public void deleteStorageGroup(Connection connection, String groupName) throws BaseException {
-        paramValid(groupName);
-        SessionPool sessionPool = getSessionPool(connection);
-        try {
-            sessionPool.deleteStorageGroup(groupName);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            if (e.getStatusCode() == 602) {
-                throw new BaseException(ErrorCode.NO_PRI_DELETE_GROUP, ErrorCode.NO_PRI_DELETE_GROUP_MSG);
-            }
-            throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.DELETE_GROUP_FAIL, ErrorCode.DELETE_GROUP_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+  }
+
+  @Override
+  public List<String> getIotDBUserList(Connection connection) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "list user";
+    List<String> users = executeQueryOneColumn(sessionPool, sql);
+    sessionPool.close();
+    return users;
+  }
+
+  @Override
+  public List<String> getIotDBRoleList(Connection connection) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "list role";
+    List<String> roles = executeQueryOneColumn(sessionPool, sql);
+    sessionPool.close();
+    return roles;
+  }
+
+  @Override
+  public IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException {
+    paramValid(userName);
+    IotDBUserVO iotDBUserVO = new IotDBUserVO();
+    iotDBUserVO.setUserName(userName);
+    if (userName.equals(connection.getUsername())) {
+      iotDBUserVO.setPassword(connection.getPassword());
+    } else {
+      iotDBUserVO.setPassword(null);
     }
-
-    @Override
-    public CountDTO getDevicesByGroup(Connection connection, String groupName, Integer pageSize, Integer pageNum, String keyword) throws BaseException {
-        paramValid(groupName);
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "show devices " + groupName;
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            List<String> values = new ArrayList<>();
-            int count = 0;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
-                    if (keyword != null || "".equals(keyword)) {
-                        String deviceName = fields.get(0).toString();
-                        deviceName = StringUtils.removeStart(deviceName, groupName + ".");
-                        if (deviceName.contains(keyword)) {
-                            count++;
-                        } else {
-                            continue;
-                        }
-                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-                            values.add(fields.get(0).toString());
-                        }
-                    } else {
-                        count++;
-                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-                            values.add(fields.get(0).toString());
-                        }
-                    }
-                }
-            }
-            CountDTO countDTO = new CountDTO();
-            countDTO.setObjects(values);
-            countDTO.setTotalCount(count);
-            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
-            countDTO.setTotalPage(totalPage);
-            return countDTO;
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+    if ("root".equalsIgnoreCase(userName)) {
+      List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
+      PrivilegeInfo privilegeInfo = new PrivilegeInfo();
+      privilegeInfo.setType(0);
+      privilegeInfo.setPrivileges(PRIVILEGES);
+      privilegeInfos.add(privilegeInfo);
+      iotDBUserVO.setPrivilegesInfo(privilegeInfos);
+      return iotDBUserVO;
     }
-
-    @Override
-    public CountDTO getMeasurementsByDevice(Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword) throws BaseException {
-        paramValid(deviceName);
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "show timeseries " + deviceName;
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            List<MeasurementDTO> results = new ArrayList<>();
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            int count = 0;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
-                    if (keyword != null || "".equals(keyword)) {
-                        String measurementName = fields.get(0).toString();
-                        measurementName = StringUtils.removeStart(measurementName, deviceName + ".");
-                        if (measurementName.contains(keyword)) {
-                            count++;
-                        } else {
-                            continue;
-                        }
-                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-                            MeasurementDTO t = new MeasurementDTO();
-                            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-                            for (int i = 0; i < fields.size(); i++) {
-                                Field field = MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
-                                field.setAccessible(true);
-                                field.set(t, fields.get(i).toString());
-                            }
-                            results.add(t);
-                        }
-                    } else {
-                        count++;
-                        if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-                            MeasurementDTO t = new MeasurementDTO();
-                            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-                            for (int i = 0; i < fields.size(); i++) {
-                                Field field = MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
-                                field.setAccessible(true);
-                                field.set(t, fields.get(i).toString());
-                            }
-                            results.add(t);
-                        }
-                    }
-                }
-            }
-            CountDTO countDTO = new CountDTO();
-            countDTO.setObjects(results);
-            countDTO.setTotalCount(count);
-            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
-            countDTO.setTotalPage(totalPage);
-            return countDTO;
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
-        } catch (Exception e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-        }
+    SessionPool sessionpool = getSessionPool(connection);
+    String sql = "list user privileges " + userName;
+    try {
+      SessionDataSetWrapper sessionDataSetWrapper = sessionpool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        List<String> privileges = new ArrayList<>();
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord next = sessionDataSetWrapper.next();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+          for (int i = 0; i < fields.size(); i++) {
+            org.apache.iotdb.tsfile.read.common.Field field = fields.get(i);
+            if (i == 0) {
+              if (field != null && field.toString().length() > 0) {
+                break;
+              }
+              continue;
+            }
+            privileges.add(field.toString());
+          }
+        }
+        // privileges String内容形式 "path : 权限1 权限2 权限3"
+        // 组装成权限信息集合
+        List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
+        if (privileges != null && privileges.size() > 0) {
+          privilegeInfos = privilegesStrSwitchToObject(sessionpool, privileges);
+        }
+        iotDBUserVO.setPrivilegesInfo(privilegeInfos);
+      }
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.GET_USER_FAIL, ErrorCode.GET_USER_FAIL_MSG);
+    } finally {
+      if (sessionpool != null) {
+        sessionpool.close();
+      }
     }
-
-    @Override
-    public List<String> getIotDBUserList(Connection connection) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "list user";
-        List<String> users = executeQueryOneColumn(sessionPool, sql);
+    return iotDBUserVO;
+  }
+
+  @Override
+  public void deleteIotDBUser(Connection connection, String userName) throws BaseException {
+    paramValid(userName);
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "drop user " + userName;
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
         sessionPool.close();
-        return users;
+      }
     }
-
-    @Override
-    public List<String> getIotDBRoleList(Connection connection) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "list role";
-        List<String> roles = executeQueryOneColumn(sessionPool, sql);
+  }
+
+  @Override
+  public void deleteIotDBRole(Connection connection, String roleName) throws BaseException {
+    paramValid(roleName);
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "drop role " + roleName;
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
         sessionPool.close();
-        return roles;
-    }
-
-    @Override
-    public IotDBUserVO getIotDBUser(Connection connection, String userName) throws BaseException {
-        paramValid(userName);
-        IotDBUserVO iotDBUserVO = new IotDBUserVO();
-        iotDBUserVO.setUserName(userName);
-        if (userName.equals(connection.getUsername())) {
-            iotDBUserVO.setPassword(connection.getPassword());
-        } else {
-            iotDBUserVO.setPassword(null);
-        }
-        if ("root".equalsIgnoreCase(userName)) {
-            List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
-            PrivilegeInfo privilegeInfo = new PrivilegeInfo();
-            privilegeInfo.setType(0);
-            privilegeInfo.setPrivileges(PRIVILEGES);
-            privilegeInfos.add(privilegeInfo);
-            iotDBUserVO.setPrivilegesInfo(privilegeInfos);
-            return iotDBUserVO;
-        }
-        SessionPool sessionpool = getSessionPool(connection);
-        String sql = "list user privileges " + userName;
-        try {
-            SessionDataSetWrapper sessionDataSetWrapper = sessionpool.executeQueryStatement(sql);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            if (batchSize > 0) {
-                List<String> privileges = new ArrayList<>();
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord next = sessionDataSetWrapper.next();
-                    List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
-                    for (int i = 0; i < fields.size(); i++) {
-                        org.apache.iotdb.tsfile.read.common.Field field = fields.get(i);
-                        if (i == 0) {
-                            if (field != null && field.toString().length() > 0) {
-                                break;
-                            }
-                            continue;
-                        }
-                        privileges.add(field.toString());
-                    }
-                }
-                // privileges String内容形式 "path : 权限1 权限2 权限3"
-                // 组装成权限信息集合
-                List<PrivilegeInfo> privilegeInfos = new ArrayList<>();
-                if (privileges != null && privileges.size() > 0) {
-                    privilegeInfos = privilegesStrSwitchToObject(sessionpool, privileges);
-                }
-                iotDBUserVO.setPrivilegesInfo(privilegeInfos);
-            }
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.GET_USER_FAIL, ErrorCode.GET_USER_FAIL_MSG);
-        } finally {
-            if (sessionpool != null) {
-                sessionpool.close();
-            }
-        }
-        return iotDBUserVO;
+      }
     }
-
-    @Override
-    public void deleteIotDBUser(Connection connection, String userName) throws BaseException {
-        paramValid(userName);
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "drop user " + userName;
-        try {
-            sessionPool.executeNonQueryStatement(sql);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.DELETE_DB_USER_FAIL, ErrorCode.DELETE_DB_USER_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+  }
+
+  @Override
+  public void setIotDBUser(Connection connection, IotDBUser iotDBUser) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String userName = iotDBUser.getUserName();
+    String password = iotDBUser.getPassword();
+    String sql = "create user " + userName + " '" + password + "'";
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
+        sessionPool.close();
+      }
     }
-
-    @Override
-    public void deleteIotDBRole(Connection connection, String roleName) throws BaseException {
-        paramValid(roleName);
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "drop role " + roleName;
-        try {
-            sessionPool.executeNonQueryStatement(sql);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.DELETE_DB_ROLE_FAIL, ErrorCode.DELETE_DB_ROLE_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+    //        // 用户角色
+    //        for (String role : iotDBUser.getRoles()) {
+    //            paramValid(role);
+    //            sql = "grant " + role + " to " + userName;
+    //            customExecute(conn, sql);
+    //        }
+    //        // 用户授权
+    //        List<String> privileges = iotDBUser.getPrivileges();
+    //        for (String privilege : privileges) {
+    //            sql = handlerPrivilegeStrToSql(privilege, userName, null);
+    //            if (sql != null) {
+    //                customExecute(conn, sql);
+    //            }
+    //        }
+  }
+
+  @Override
+  public void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String roleName = iotDBRole.getRoleName();
+    String sql = "create role " + roleName;
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+      List<String> privileges = iotDBRole.getPrivileges();
+      for (String privilege : privileges) {
+        sql = handlerPrivilegeStrToSql(privilege, null, roleName);
+        if (sql != null) {
+          sessionPool.executeNonQueryStatement(sql);
+        }
+      }
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
+        sessionPool.close();
+      }
     }
-
-    @Override
-    public void setIotDBUser(Connection connection, IotDBUser iotDBUser) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String userName = iotDBUser.getUserName();
-        String password = iotDBUser.getPassword();
-        String sql = "create user " + userName + " '" + password + "'";
-        try {
-            sessionPool.executeNonQueryStatement(sql);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SET_DB_USER_FAIL, ErrorCode.SET_DB_USER_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
-//        // 用户角色
-//        for (String role : iotDBUser.getRoles()) {
-//            paramValid(role);
-//            sql = "grant " + role + " to " + userName;
-//            customExecute(conn, sql);
-//        }
-//        // 用户授权
-//        List<String> privileges = iotDBUser.getPrivileges();
-//        for (String privilege : privileges) {
-//            sql = handlerPrivilegeStrToSql(privilege, userName, null);
-//            if (sql != null) {
-//                customExecute(conn, sql);
-//            }
-//        }
-    }
-
-    @Override
-    public void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String roleName = iotDBRole.getRoleName();
-        String sql = "create role " + roleName;
-        try {
-            sessionPool.executeNonQueryStatement(sql);
-            List<String> privileges = iotDBRole.getPrivileges();
-            for (String privilege : privileges) {
-                sql = handlerPrivilegeStrToSql(privilege, null, roleName);
-                if (sql != null) {
-                    sessionPool.executeNonQueryStatement(sql);
-                }
-            }
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SET_DB_ROLE_FAIL, ErrorCode.SET_DB_ROLE_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+  }
+
+  //    @Override
+  //    public SqlResultVO query(Connection connection, String sql) throws BaseException {
+  //        java.sql.Connection conn = getConnection(connection);
+  //        SqlResultVO sqlResultVO = sqlQuery(conn, sql);
+  //        closeConnection(conn);
+  //        return sqlResultVO;
+  //    }
+
+  @Override
+  public void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    try {
+      List<TSDataType> types = handleTypeStr(timeseries.getTypes());
+      List<Object> values = handleValueStr(timeseries.getValues(), types);
+      sessionPool.insertRecord(
+          deviceName, timeseries.getTime(), timeseries.getMeasurements(), types, values);
+    } catch (IoTDBConnectionException e) {
+      throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
+        sessionPool.close();
+      }
     }
-
-//    @Override
-//    public SqlResultVO query(Connection connection, String sql) throws BaseException {
-//        java.sql.Connection conn = getConnection(connection);
-//        SqlResultVO sqlResultVO = sqlQuery(conn, sql);
-//        closeConnection(conn);
-//        return sqlResultVO;
-//    }
-
-    @Override
-    public void insertTimeseries(Connection connection, String deviceName, Timeseries timeseries) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        try {
-            List<TSDataType> types = handleTypeStr(timeseries.getTypes());
-            List<Object> values = handleValueStr(timeseries.getValues(), types);
-            sessionPool.insertRecord(deviceName, timeseries.getTime(), timeseries.getMeasurements(), types, values);
-        } catch (IoTDBConnectionException e) {
-            throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            throw new BaseException(ErrorCode.INSERT_TS_FAIL, ErrorCode.INSERT_TS_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
-
+  }
+
+  @Override
+  public void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    try {
+      sessionPool.deleteTimeseries(timeseriesName);
+    } catch (IoTDBConnectionException e) {
+      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+      }
+      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    } finally {
+      if (sessionPool != null) {
+        sessionPool.close();
+      }
     }
-
-    @Override
-    public void deleteTimeseries(Connection connection, String timeseriesName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        try {
-            sessionPool.deleteTimeseries(timeseriesName);
-        } catch (IoTDBConnectionException e) {
-            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            if (e.getStatusCode() == 602) {
-                throw new BaseException(ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
-            }
-            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+  }
+
+  @Override
+  public SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException {
+    paramValid(deviceName);
+    java.sql.Connection conn = getConnection(connection);
+    String sql = "show timeseries " + deviceName;
+    SqlResultVO resultVO = sqlQuery(conn, sql);
+    closeConnection(conn);
+    return resultVO;
+  }
+
+  @Override
+  public List<Integer> getDevicesCount(Connection connection, List<String> groupNames)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<Integer> devicesCount = new ArrayList<>();
+    for (String groupName : groupNames) {
+      String sql = "count devices " + groupName;
+      String value = executeQueryOneValue(sessionPool, sql);
+      if (value == null) {
+        devicesCount.add(0);
+        continue;
+      }
+      Integer count = Integer.valueOf(value);
+      devicesCount.add(count);
     }
-
-    @Override
-    public SqlResultVO showTimeseries(Connection connection, String deviceName) throws BaseException {
-        paramValid(deviceName);
-        java.sql.Connection conn = getConnection(connection);
-        String sql = "show timeseries " + deviceName;
-        SqlResultVO resultVO = sqlQuery(conn, sql);
-        closeConnection(conn);
-        return resultVO;
-    }
-
-    @Override
-    public List<Integer> getDevicesCount(Connection connection, List<String> groupNames) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        List<Integer> devicesCount = new ArrayList<>();
-        for (String groupName : groupNames) {
-            String sql = "count devices " + groupName;
-            String value = executeQueryOneValue(sessionPool, sql);
-            if (value == null) {
-                devicesCount.add(0);
-                continue;
-            }
-            Integer count = Integer.valueOf(value);
-            devicesCount.add(count);
-        }
+    sessionPool.close();
+    return devicesCount;
+  }
+
+  @Override
+  public void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "set ttl to " + groupName + " " + l;
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(ErrorCode.NO_PRI_SET_TTL, ErrorCode.NO_PRI_SET_TTL_MSG);
+      }
+      throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
+    } finally {
+      sessionPool.close();
+    }
+  }
+
+  @Override
+  public void cancelGroupTtl(Connection connection, String groupName) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "unset ttl to " + groupName;
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+    } finally {
+      sessionPool.close();
+    }
+  }
+
+  @Override
+  public Integer getDeviceCount(Connection connection, String groupName) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "count devices " + groupName;
+    String value = executeQueryOneValue(sessionPool, sql);
+    if (value == null) {
+      return 0;
+    }
+    Integer count = Integer.valueOf(value);
+    return count;
+  }
+
+  @Override
+  public List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<Integer> lines = new ArrayList<>();
+    for (String deviceName : deviceNames) {
+      String sql = "count timeseries " + deviceName;
+      String value = executeQueryOneValue(sessionPool, sql);
+      if (value == null) {
+        lines.add(0);
+        continue;
+      }
+      Integer count = Integer.valueOf(value);
+      lines.add(count);
+    }
+    sessionPool.close();
+    return lines;
+  }
+
+  @Override
+  public void deleteTimeseriesByDevice(Connection connection, String deviceName)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "delete timeseries " + deviceName + ".*";
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
+      }
+      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+    }
+  }
+
+  @Override
+  public void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<String> typesStr = new ArrayList<>();
+    List<String> encodingsStr = new ArrayList<>();
+    List<String> measurements = new ArrayList<>();
+    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+      typesStr.add(deviceDTO.getDataType());
+      encodingsStr.add(deviceDTO.getEncoding());
+      measurements.add(deviceDTO.getTimeseries());
+    }
+    List<TSDataType> types = handleTypeStr(typesStr);
+    List<TSEncoding> encodings = handleEncodingStr(encodingsStr);
+    List<CompressionType> compressionTypes = new ArrayList<>();
+    for (int i = 0; i < types.size(); i++) {
+      compressionTypes.add(CompressionType.SNAPPY);
+    }
+    try {
+      sessionPool.createMultiTimeseries(
+          measurements, types, encodings, compressionTypes, null, null, null, null);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      if (e.getMessage().contains("No permissions")) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_CREATE_TIMESERIES, ErrorCode.NO_PRI_CREATE_TIMESERIES_MSG);
+      }
+      if (!e.getMessage().contains("PathAlreadyExistException")) {
+        logger.error(e.getMessage());
+        throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
+      }
+    } finally {
+      if (sessionPool != null) {
         sessionPool.close();
-        return devicesCount;
+      }
     }
-
-    @Override
-    public void saveGroupTtl(Connection connection, String groupName, long l) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "set ttl to " + groupName + " " + l;
-        try {
-            sessionPool.executeNonQueryStatement(sql);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            if (e.getStatusCode() == 602) {
-                throw new BaseException(ErrorCode.NO_PRI_SET_TTL, ErrorCode.NO_PRI_SET_TTL_MSG);
+  }
+
+  @Override
+  public Integer getMeasurementsCount(Connection connection, String deviceName)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "count timeseries " + deviceName;
+    String valueStr = executeQueryOneValue(sessionPool, sql);
+    return Integer.valueOf(valueStr);
+  }
+
+  @Override
+  public String getLastMeasurementValue(Connection connection, String timeseries)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    int index = timeseries.lastIndexOf(".");
+    String sql =
+        "select last_value("
+            + timeseries.substring(index + 1)
+            + ") from "
+            + timeseries.substring(0, index);
+    String value;
+    try {
+      value = executeQueryOneValue(sessionPool, sql);
+    } finally {
+      sessionPool.close();
+    }
+    return value;
+  }
+
+  @Override
+  public String getGroupTTL(Connection connection, String groupName) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "show ttl on " + groupName;
+    String queryField = "ttl";
+    String ttl = executeQueryOneLine(sessionPool, sql, queryField);
+    return ttl;
+  }
+
+  @Override
+  public List<String> getDevices(Connection connection, String groupName) throws BaseException {
+    paramValid(groupName);
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "show devices " + groupName;
+    List<String> devicesName = executeQueryOneColumn(sessionPool, sql);
+    return devicesName;
+  }
+
+  @Override
+  public List<String> getTimeseries(Connection connection, String deviceName) throws BaseException {
+    paramValid(deviceName);
+    SessionPool sessionPool = getSessionPool(connection);
+    String sql = "show timeseries " + deviceName;
+    SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, true);
+    List<String> metaDataList = sqlResultVO.getMetaDataList();
+    int index = -1;
+    if (metaDataList != null) {
+      for (int i = 0; i < metaDataList.size(); i++) {
+        if ("timeseries".equalsIgnoreCase(metaDataList.get(i))) {
+          index = i;
+          break;
+        }
+      }
+    }
+    if (index == -1) {
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    }
+    List<List<String>> valueList = sqlResultVO.getValueList();
+    List<String> timeseries = new ArrayList<>();
+    for (List<String> list : valueList) {
+      timeseries.add(list.get(index));
+    }
+    return timeseries;
+  }
+
+  @Override
+  public void setUserPrivileges(
+      Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    // 授权
+    List<String> privileges = privilegeInfoDTO.getPrivileges();
+    if (notNullAndNotZero(privileges)) {
+      grantOrRevoke("grant", privileges, userName, privilegeInfoDTO, sessionPool);
+    }
+    // 取消授权
+    List<String> cancelPrivileges = privilegeInfoDTO.getCancelPrivileges();
+    if (notNullAndNotZero(cancelPrivileges)) {
+      grantOrRevoke("revoke", cancelPrivileges, userName, privilegeInfoDTO, sessionPool);
+    }
+    cancelPathPrivileges(userName, privilegeInfoDTO, sessionPool);
+    sessionPool.close();
+  }
+
+  private void cancelPathPrivileges(
+      String userName, PrivilegeInfoDTO privilegeInfoDTO, SessionPool sessionPool) {
+    Integer type = privilegeInfoDTO.getType();
+    List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
+    List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
+    List<String> delTimeseriesPaths = privilegeInfoDTO.getDelTimeseriesPaths();
+    switch (type) {
+      case 1:
+        if (notNullAndNotZero(delGroupPaths)) {
+          Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
+          for (String delGroupPath : delGroupPaths) {
+            for (String privilegesStr : privileges) {
+              String sql =
+                  "revoke user "
+                      + userName
+                      + " privileges '"
+                      + privilegesStr
+                      + "' on root."
+                      + delGroupPath;
+              try {
+                sessionPool.executeNonQueryStatement(sql);
+              } catch (StatementExecutionException e) {
+                logger.error(e.getMessage());
+              } catch (IoTDBConnectionException e) {
+                logger.error(e.getMessage());
+              }
+            }
+          }
+        }
+        break;
+      case 2:
+        if (notNullAndNotZero(delDevicePaths)) {
+          Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
+          String onlyGroupPath = delGroupPaths.get(0);
+          for (String delDevicePath : delDevicePaths) {
+            for (String privilegesStr : privileges) {
+              String sql =
+                  "revoke user "
+                      + userName
+                      + " privileges '"
+                      + privilegesStr
+                      + "' on root."
+                      + onlyGroupPath
+                      + "."
+                      + delDevicePath;
+              try {
+                sessionPool.executeNonQueryStatement(sql);
+              } catch (StatementExecutionException e) {
+                logger.error(e.getMessage());
+              } catch (IoTDBConnectionException e) {
+                logger.error(e.getMessage());
+              }
+            }
+          }
+        }
+        break;
+      case 3:
+        if (notNullAndNotZero(delTimeseriesPaths)) {
+          Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
+          String onlyGroupPath = delGroupPaths.get(0);
+          String onlyDevicePath = delDevicePaths.get(0);
+          for (String delTimeseriesPath : delTimeseriesPaths) {
+            for (String privilegesStr : privileges) {
+              String sql =
+                  "revoke user "
+                      + userName
+                      + " privileges '"
+                      + privilegesStr
+                      + "' on root."
+                      + onlyGroupPath
+                      + "."
+                      + onlyDevicePath
+                      + "."
+                      + delTimeseriesPath;
+              try {
+                sessionPool.executeNonQueryStatement(sql);
+              } catch (StatementExecutionException e) {
+                logger.error(e.getMessage());
+              } catch (IoTDBConnectionException e) {
+                logger.error(e.getMessage());
+              }
             }
-            throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SET_TTL_FAIL, ErrorCode.SET_TTL_FAIL_MSG);
-        } finally {
-            sessionPool.close();
+          }
         }
+        break;
     }
-
-    @Override
-    public void cancelGroupTtl(Connection connection, String groupName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "unset ttl to " + groupName;
+  }
+
+  @Override
+  public RecordVO getRecords(Connection connection, String deviceName, String timeseriesName)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    RecordVO recordVO = new RecordVO();
+    List<Date> timeList = new ArrayList<>();
+    List<Long> valueList = new ArrayList<>();
+    String sql =
+        "select time,"
+            + timeseriesName
+            + " from "
+            + deviceName
+            + " order by time desc limit 200 offset 0";
+    try {
+      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord next = sessionDataSetWrapper.next();
+          Date date = new Date(next.getTimestamp());
+          timeList.add(date);
+          List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
+          Long value = Long.valueOf(fields.get(0).toString());
+          valueList.add(value);
+        }
+      }
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
+    }
+    recordVO.setTimeList(timeList);
+    recordVO.setValueList(valueList);
+    return recordVO;
+  }
+
+  @Override
+  public List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp)
+      throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<SqlResultVO> results;
+    String id_plus_timestamp;
+    try {
+      results = new ArrayList<>();
+      Integer id = connection.getId();
+      id_plus_timestamp = id + ":" + timestamp;
+      QUERY_STOP.put(id_plus_timestamp, true);
+      for (String sql : sqls) {
+        int firstSpaceIndex = sql.indexOf(" ");
+        String judge = sql.substring(0, firstSpaceIndex);
+        if ("show".equalsIgnoreCase(judge)
+            || "count".equalsIgnoreCase(judge)
+            || "list".equalsIgnoreCase(judge)) {
+          SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, false);
+          results.add(sqlResultVO);
+          continue;
+        }
+        if ("select".equalsIgnoreCase(judge)) {
+          SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, true);
+          results.add(sqlResultVO);
+          continue;
+        }
         try {
+          if (QUERY_STOP.get(id_plus_timestamp)) {
+            String sqlCheck = sql.toLowerCase();
+            if (sqlCheck != null && sqlCheck.contains("insert")) {
+              String s = sqlCheck;
+              String[] split = s.split("\\.");
+              if (split.length <= 2) {
+                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
+              }
+            }
+            if (sqlCheck != null && sqlCheck.contains("create timeseries")) {
+              String s = sqlCheck;
+              String[] split = s.split("\\.");
+              if (split.length <= 3) {
+                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
+              }
+            }
+            long start = System.currentTimeMillis();
             sessionPool.executeNonQueryStatement(sql);
+            long end = System.currentTimeMillis();
+            double time = (end - start + 0.0d) / 1000;
+            String queryTime = time + "s";
+            SqlResultVO sqlResultVO = new SqlResultVO();
+            sqlResultVO.setQueryTime(queryTime);
+            sqlResultVO.setLine(0L);
+            results.add(sqlResultVO);
+          }
         } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
+          logger.error(e.getMessage());
+          throw new BaseException(
+              ErrorCode.SQL_EP,
+              ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
         } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-        } finally {
-            sessionPool.close();
-        }
-    }
-
-    @Override
-    public Integer getDeviceCount(Connection connection, String groupName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "count devices " + groupName;
-        String value = executeQueryOneValue(sessionPool, sql);
-        if (value == null) {
-            return 0;
-        }
-        Integer count = Integer.valueOf(value);
-        return count;
-    }
-
-    @Override
-    public List<Integer> getTimeseriesCount(Connection connection, List<String> deviceNames) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        List<Integer> lines = new ArrayList<>();
-        for (String deviceName : deviceNames) {
-            String sql = "count timeseries " + deviceName;
-            String value = executeQueryOneValue(sessionPool, sql);
-            if (value == null) {
-                lines.add(0);
-                continue;
-            }
-            Integer count = Integer.valueOf(value);
-            lines.add(count);
-        }
+          logger.error(e.getMessage());
+          throw new BaseException(
+              ErrorCode.SQL_EP,
+              ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
+        }
+      }
+    } finally {
+      if (sessionPool != null) {
         sessionPool.close();
-        return lines;
+      }
     }
-
-    @Override
-    public void deleteTimeseriesByDevice(Connection connection, String deviceName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "delete timeseries " + deviceName + ".*";
+    QUERY_STOP.remove(id_plus_timestamp);
+    return results;
+  }
+
+  @Override
+  public void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    String userName = iotDBUser.getUserName();
+    String newPWD = iotDBUser.getPassword();
+    String sql = "alter user " + userName + " set password '" + newPWD + "'";
+    try {
+      sessionPool.executeNonQueryStatement(sql);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.UPDATE_PWD_FAIL, ErrorCode.UPDATE_PWD_FAIL_MSG);
+    } catch (IoTDBConnectionException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Override
+  public void stopQuery(Integer serverId, Long timestamp) throws BaseException {
+    String notStopKey = serverId + ":" + timestamp;
+    if (QUERY_STOP.containsKey(notStopKey)) {
+      QUERY_STOP.put(notStopKey, false);
+      return;
+    }
+    throw new BaseException(ErrorCode.NO_QUERY, ErrorCode.NO_QUERY_MSG);
+  }
+
+  private void grantOrRevoke(
+      String word,
+      List<String> privileges,
+      String userName,
+      PrivilegeInfoDTO privilegesInfo,
+      SessionPool sessionPool)
+      throws BaseException {
+    Integer type = privilegesInfo.getType();
+    //        String privilegesStr = String.join("','", privileges); 一起存会有bug
+    for (String privilegesStr : privileges) {
+      if (type == 0) {
+        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root";
         try {
-            sessionPool.executeNonQueryStatement(sql);
+          sessionPool.executeNonQueryStatement(sql);
         } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            if (e.getStatusCode() == 602) {
-                throw new BaseException(ErrorCode.NO_PRI_DELETE_TIMESERIES, ErrorCode.NO_PRI_DELETE_TIMESERIES_MSG);
-            }
-            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
+          logger.error(e.getMessage());
         } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.DELETE_TS_FAIL, ErrorCode.DELETE_TS_FAIL_MSG);
-        }
+          logger.error(e.getMessage());
+        }
+        continue;
+      }
+      if (type == 1) {
+        List<String> groupPaths = privilegesInfo.getGroupPaths();
+        if (notNullAndNotZero(groupPaths)) {
+          for (String groupPath : groupPaths) {
+            String sql =
+                word
+                    + " user "
+                    + userName
+                    + " privileges '"
+                    + privilegesStr
+                    + "' on root."
+                    + groupPath;
+            try {
+              sessionPool.executeNonQueryStatement(sql);
+            } catch (StatementExecutionException e) {
+              logger.error(e.getMessage());
+            } catch (IoTDBConnectionException e) {
+              logger.error(e.getMessage());
+            }
+          }
+        }
+        continue;
+      }
+      if (type == 2) {
+        List<String> groupPaths = privilegesInfo.getGroupPaths();
+        List<String> devicePaths = privilegesInfo.getDevicePaths();
+        if (notNullAndNotZero(groupPaths)
+            && groupPaths.size() == 1
+            && notNullAndNotZero(devicePaths)) {
+          String onlyGroupPath = groupPaths.get(0);
+          for (String devicePath : devicePaths) {
+            String sql =
+                word
+                    + " user "
+                    + userName
+                    + " privileges '"
+                    + privilegesStr
+                    + "' on root."
+                    + onlyGroupPath
+                    + "."
+                    + devicePath;
+            try {
+              sessionPool.executeNonQueryStatement(sql);
+            } catch (StatementExecutionException e) {
+              logger.error(e.getMessage());
+            } catch (IoTDBConnectionException e) {
+              logger.error(e.getMessage());
+            }
+          }
+        }
+        continue;
+      }
+      if (type == 3) {
+        List<String> groupPaths = privilegesInfo.getGroupPaths();
+        List<String> devicePaths = privilegesInfo.getDevicePaths();
+        List<String> timeseriesPaths = privilegesInfo.getTimeseriesPaths();
+        if (notNullAndNotZero(groupPaths)
+            && groupPaths.size() == 1
+            && notNullAndNotZero(devicePaths)
+            && devicePaths.size() == 1
+            && notNullAndNotZero(timeseriesPaths)) {
+          String onlyGroupPath = groupPaths.get(0);
+          String onlyDevicePath = devicePaths.get(0);
+          for (String timeseriesPath : timeseriesPaths) {
+            String sql =
+                word
+                    + " user "
+                    + userName
+                    + " privileges '"
+                    + privilegesStr
+                    + "' on root."
+                    + onlyGroupPath
+                    + "."
+                    + onlyDevicePath
+                    + "."
+                    + timeseriesPath;
+            try {
+              sessionPool.executeNonQueryStatement(sql);
+            } catch (StatementExecutionException e) {
+              logger.error(e.getMessage());
+            } catch (IoTDBConnectionException e) {
+              logger.error(e.getMessage());
+            }
+          }
+        }
+        continue;
+      }
+      throw new BaseException(ErrorCode.NO_TYPE, ErrorCode.NO_TYPE_MSG);
     }
+  }
 
-    @Override
-    public void createDeviceWithMeasurements(Connection connection, DeviceInfoDTO deviceInfoDTO) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        List<String> typesStr = new ArrayList<>();
-        List<String> encodingsStr = new ArrayList<>();
-        List<String> measurements = new ArrayList<>();
-        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
-            typesStr.add(deviceDTO.getDataType());
-            encodingsStr.add(deviceDTO.getEncoding());
-            measurements.add(deviceDTO.getTimeseries());
-        }
-        List<TSDataType> types = handleTypeStr(typesStr);
-        List<TSEncoding> encodings = handleEncodingStr(encodingsStr);
-        List<CompressionType> compressionTypes = new ArrayList<>();
-        for (int i = 0; i < types.size(); i++) {
-            compressionTypes.add(CompressionType.SNAPPY);
-        }
-        try {
-            sessionPool.createMultiTimeseries(measurements, types, encodings, compressionTypes, null, null, null, null);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            if (e.getMessage().contains("No permissions")) {
-                throw new BaseException(ErrorCode.NO_PRI_CREATE_TIMESERIES, ErrorCode.NO_PRI_CREATE_TIMESERIES_MSG);
-            }
-            if (!e.getMessage().contains("PathAlreadyExistException")) {
-                logger.error(e.getMessage());
-                throw new BaseException(ErrorCode.INSERT_DEV_FAIL, ErrorCode.INSERT_DEV_FAIL_MSG);
-            }
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
+  /** 判断集合不为空且长度大于0 */
+  private boolean notNullAndNotZero(List list) {
+    if (list != null && list.size() > 0) {
+      return true;
     }
-
-    @Override
-    public Integer getMeasurementsCount(Connection connection, String deviceName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "count timeseries " + deviceName;
-        String valueStr = executeQueryOneValue(sessionPool, sql);
-        return Integer.valueOf(valueStr);
+    return false;
+  }
+
+  private String executeQueryOneLine(SessionPool sessionPool, String sql, String queryField)
+      throws BaseException {
+    try {
+      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+      int index = -1;
+      for (int i = 0; i < columnNames.size(); i++) {
+        if (queryField.equals(columnNames.get(i))) {
+          index = i;
+        }
+      }
+      if (index == -1) {
+        throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+      }
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      if (batchSize > 0) {
+        if (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          return rowRecord.getFields().get(index).toString();
+        }
+      }
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
     }
-
-    @Override
-    public String getLastMeasurementValue(Connection connection, String timeseries) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        int index = timeseries.lastIndexOf(".");
-        String sql = "select last_value(" + timeseries.substring(index + 1) + ") from " + timeseries.substring(0, index);
-        String value;
-        try {
-            value = executeQueryOneValue(sessionPool, sql);
-        } finally {
-            sessionPool.close();
-        }
-        return value;
-    }
-
-    @Override
-    public String getGroupTTL(Connection connection, String groupName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "show ttl on " + groupName;
-        String queryField = "ttl";
-        String ttl = executeQueryOneLine(sessionPool, sql, queryField);
-        return ttl;
-    }
-
-    @Override
-    public List<String> getDevices(Connection connection, String groupName) throws BaseException {
-        paramValid(groupName);
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "show devices " + groupName;
-        List<String> devicesName = executeQueryOneColumn(sessionPool, sql);
-        return devicesName;
-    }
-
-    @Override
-    public List<String> getTimeseries(Connection connection, String deviceName) throws BaseException {
-        paramValid(deviceName);
-        SessionPool sessionPool = getSessionPool(connection);
-        String sql = "show timeseries " + deviceName;
-        SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, true);
-        List<String> metaDataList = sqlResultVO.getMetaDataList();
-        int index = -1;
-        if (metaDataList != null) {
-            for (int i = 0; i < metaDataList.size(); i++) {
-                if ("timeseries".equalsIgnoreCase(metaDataList.get(i))) {
-                    index = i;
-                    break;
-                }
-            }
-        }
-        if (index == -1) {
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        }
-        List<List<String>> valueList = sqlResultVO.getValueList();
-        List<String> timeseries = new ArrayList<>();
-        for (List<String> list : valueList) {
-            timeseries.add(list.get(index));
-        }
-        return timeseries;
+    throw new BaseException(ErrorCode.NO_GROUP, ErrorCode.NO_GROUP_MSG);
+  }
+
+  private SqlResultVO executeQuery(SessionPool sessionPool, String sql, Boolean closePool)
+      throws BaseException {
+    SqlResultVO sqlResultVO = new SqlResultVO();
+    List<List<String>> valuelist = new ArrayList<>();
+    try {
+      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      long start = System.currentTimeMillis();
+      List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+      sqlResultVO.setMetaDataList(columnNames);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      // 记录行数
+      long count = 0;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          List<String> strList = new ArrayList<>();
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          count++;
+          for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
+            strList.add(field.toString());
+          }
+          valuelist.add(strList);
+        }
+        long end = System.currentTimeMillis();
+        double time = (end - start + 0.0d) / 1000;
+        String queryTime = time + "s";
+        sqlResultVO.setQueryTime(queryTime);
+        sqlResultVO.setLine(count);
+      }
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } finally {
+      if (sessionPool != null && closePool) {
+        sessionPool.close();
+      }
     }
-
-    @Override
-    public void setUserPrivileges(Connection connection, String userName, PrivilegeInfoDTO privilegeInfoDTO) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        // 授权
-        List<String> privileges = privilegeInfoDTO.getPrivileges();
-        if (notNullAndNotZero(privileges)) {
-            grantOrRevoke("grant", privileges, userName, privilegeInfoDTO, sessionPool);
-        }
-        // 取消授权
-        List<String> cancelPrivileges = privilegeInfoDTO.getCancelPrivileges();
-        if (notNullAndNotZero(cancelPrivileges)) {
-            grantOrRevoke("revoke", cancelPrivileges, userName, privilegeInfoDTO, sessionPool);
-        }
-        cancelPathPrivileges(userName, privilegeInfoDTO, sessionPool);
+    sqlResultVO.setValueList(valuelist);
+    return sqlResultVO;
+  }
+
+  private SqlResultVO executeQuery(
+      SessionPool sessionPool, String sql, Boolean closePool, String notStopKey, boolean timeFlag)
+      throws BaseException {
+    SqlResultVO sqlResultVO = new SqlResultVO();
+    List<List<String>> valuelist = new ArrayList<>();
+    try {
+      SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      long start = System.currentTimeMillis();
+      List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+      sqlResultVO.setMetaDataList(columnNames);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      // 记录行数
+      long count = 0;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext() && QUERY_STOP.get(notStopKey)) {
+          List<String> strList = new ArrayList<>();
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          if (timeFlag) {
+            long timestamp = rowRecord.getTimestamp();
+            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+            Date date = new Date(timestamp);
+            String timeStr = simpleDateFormat.format(date);
+            strList.add(timeStr);
+          }
+          count++;
+          for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
+            strList.add(field.toString());
+          }
+          valuelist.add(strList);
+        }
+        long end = System.currentTimeMillis();
+        double time = (end - start + 0.0d) / 1000;
+        String queryTime = time + "s";
+        sqlResultVO.setQueryTime(queryTime);
+        sqlResultVO.setLine(count);
+      }
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_TIMESERIES_DATA, ErrorCode.NO_PRI_TIMESERIES_DATA_MSG);
+      }
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } finally {
+      if (sessionPool != null && closePool) {
         sessionPool.close();
+      }
     }
-
-    private void cancelPathPrivileges(String userName, PrivilegeInfoDTO privilegeInfoDTO, SessionPool sessionPool) {
-        Integer type = privilegeInfoDTO.getType();
-        List<String> delDevicePaths = privilegeInfoDTO.getDelDevicePaths();
-        List<String> delGroupPaths = privilegeInfoDTO.getDelGroupPaths();
-        List<String> delTimeseriesPaths = privilegeInfoDTO.getDelTimeseriesPaths();
-        switch (type) {
-            case 1:
-                if (notNullAndNotZero(delGroupPaths)) {
-                    Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
-                    for (String delGroupPath : delGroupPaths) {
-                        for (String privilegesStr : privileges) {
-                            String sql = "revoke user " + userName + " privileges '" + privilegesStr + "' on root."
-                                + delGroupPath;
-                            try {
-                                sessionPool.executeNonQueryStatement(sql);
-                            } catch (StatementExecutionException e) {
-                                logger.error(e.getMessage());
-                            } catch (IoTDBConnectionException e) {
-                                logger.error(e.getMessage());
-                            }
-                        }
-                    }
-                }
-                break;
-            case 2:
-                if (notNullAndNotZero(delDevicePaths)) {
-                    Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
-                    String onlyGroupPath = delGroupPaths.get(0);
-                    for (String delDevicePath : delDevicePaths) {
-                        for (String privilegesStr : privileges) {
-                            String sql = "revoke user " + userName + " privileges '" + privilegesStr + "' on root."
-                                + onlyGroupPath + "." + delDevicePath;
-                            try {
-                                sessionPool.executeNonQueryStatement(sql);
-                            } catch (StatementExecutionException e) {
-                                logger.error(e.getMessage());
-                            } catch (IoTDBConnectionException e) {
-                                logger.error(e.getMessage());
-                            }
-                        }
-                    }
-                }
-                break;
-            case 3:
-                if (notNullAndNotZero(delTimeseriesPaths)) {
-                    Set<String> privileges = SPECIAL_PRIVILEGES.keySet();
-                    String onlyGroupPath = delGroupPaths.get(0);
-                    String onlyDevicePath = delDevicePaths.get(0);
-                    for (String delTimeseriesPath : delTimeseriesPaths) {
-                        for (String privilegesStr : privileges) {
-                            String sql = "revoke user " + userName + " privileges '" + privilegesStr + "' on root."
-                                + onlyGroupPath + "." + onlyDevicePath + "." + delTimeseriesPath;
-                            try {
-                                sessionPool.executeNonQueryStatement(sql);
-                            } catch (StatementExecutionException e) {
-                                logger.error(e.getMessage());
-                            } catch (IoTDBConnectionException e) {
-                                logger.error(e.getMessage());
-                            }
-                        }
-                    }
-                }
-                break;
-        }
+    sqlResultVO.setValueList(valuelist);
+    return sqlResultVO;
+  }
+
+  private <T> CountDTO executeQuery(
+      Class<T> clazz,
+      SessionPool sessionPool,
+      String sql,
+      Integer pageSize,
+      Integer pageNum,
+      String keyword)
+      throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      List<T> results = new ArrayList<>();
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      int count = 0;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          count++;
+          if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+            T t = clazz.newInstance();
+            List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+            for (int i = 0; i < fields.size(); i++) {
+              Field field = clazz.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+              field.setAccessible(true);
+              field.set(t, fields.get(i).toString());
+            }
+            results.add(t);
+          }
+        }
+      }
+      CountDTO countDTO = new CountDTO();
+      countDTO.setObjects(results);
+      countDTO.setTotalCount(count);
+      Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+      countDTO.setTotalPage(totalPage);
+      return countDTO;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+    } catch (Exception e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
     }
-
-    @Override
-    public RecordVO getRecords(Connection connection, String deviceName, String timeseriesName) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        RecordVO recordVO = new RecordVO();
-        List<Date> timeList = new ArrayList<>();
-        List<Long> valueList = new ArrayList<>();
-        String sql = "select time," + timeseriesName + " from " + deviceName + " order by time desc limit 200 offset 0";
-        try {
-            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord next = sessionDataSetWrapper.next();
-                    Date date = new Date(next.getTimestamp());
-                    timeList.add(date);
-                    List<org.apache.iotdb.tsfile.read.common.Field> fields = next.getFields();
-                    Long value = Long.valueOf(fields.get(0).toString());
-                    valueList.add(value);
-                }
-            }
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_RECORD_FAIL, ErrorCode.GET_RECORD_FAIL_MSG);
-        }
-        recordVO.setTimeList(timeList);
-        recordVO.setValueList(valueList);
-        return recordVO;
+  }
+
+  private String executeQueryOneValue(SessionPool sessionPool, String sql) throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      String value = null;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+          value = fields.get(0).toString();
+          break;
+        }
+      }
+      return value;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      if (e.getStatusCode() == 602 && sql != null && sql.contains("select")) {
+        throw new BaseException(
+            ErrorCode.NO_PRI_READ_TIMESERIES, ErrorCode.NO_PRI_READ_TIMESERIES_MSG);
+      }
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
     }
-
-    @Override
-    public List<SqlResultVO> queryAll(Connection connection, List<String> sqls, Long timestamp) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        List<SqlResultVO> results;
-        String id_plus_timestamp;
-        try {
-            results = new ArrayList<>();
-            Integer id = connection.getId();
-            id_plus_timestamp = id + ":" + timestamp;
-            QUERY_STOP.put(id_plus_timestamp, true);
-            for (String sql : sqls) {
-                int firstSpaceIndex = sql.indexOf(" ");
-                String judge = sql.substring(0, firstSpaceIndex);
-                if ("show".equalsIgnoreCase(judge) || "count".equalsIgnoreCase(judge) || "list".equalsIgnoreCase(judge)) {
-                    SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, false);
-                    results.add(sqlResultVO);
-                    continue;
-                }
-                if ("select".equalsIgnoreCase(judge)) {
-                    SqlResultVO sqlResultVO = executeQuery(sessionPool, sql, false, id_plus_timestamp, true);
-                    results.add(sqlResultVO);
-                    continue;
-                }
-                try {
-                    if (QUERY_STOP.get(id_plus_timestamp)) {
-                        String sqlCheck = sql.toLowerCase();
-                        if (sqlCheck != null && sqlCheck.contains("insert")) {
-                            String s = sqlCheck;
-                            String[] split = s.split("\\.");
-                            if (split.length <= 2) {
-                                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
-                            }
-                        }
-                        if (sqlCheck != null && sqlCheck.contains("create timeseries")) {
-                            String s = sqlCheck;
-                            String[] split = s.split("\\.");
-                            if (split.length <= 3) {
-                                throw new BaseException(ErrorCode.NO_SUPPORT_SQL, ErrorCode.NO_SUPPORT_SQL_MSG);
-                            }
-                        }
-                        long start = System.currentTimeMillis();
-                        sessionPool.executeNonQueryStatement(sql);
-                        long end = System.currentTimeMillis();
-                        double time = (end - start + 0.0d) / 1000;
-                        String queryTime = time + "s";
-                        SqlResultVO sqlResultVO = new SqlResultVO();
-                        sqlResultVO.setQueryTime(queryTime);
-                        sqlResultVO.setLine(0L);
-                        results.add(sqlResultVO);
-                    }
-                } catch (StatementExecutionException e) {
-                    logger.error(e.getMessage());
-                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
-                } catch (IoTDBConnectionException e) {
-                    logger.error(e.getMessage());
-                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG + ":" + sql + "执行出错,错误信息[" + e.getMessage() + "]");
-                }
-            }
-        } finally {
-            if (sessionPool != null) {
-                sessionPool.close();
-            }
-        }
-        QUERY_STOP.remove(id_plus_timestamp);
-        return results;
+  }
+
+  private CountDTO executeQueryOneColumn(
+      SessionPool sessionPool, String sql, Integer pageSize, Integer pageNum) throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      List<String> values = new ArrayList<>();
+      int count = 0;
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          count++;
+          if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
+            List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+            values.add(fields.get(0).toString());
+          }
+        }
+      }
+      CountDTO countDTO = new CountDTO();
+      countDTO.setObjects(values);
+      countDTO.setTotalCount(count);
+      Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+      countDTO.setTotalPage(totalPage);
+      return countDTO;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
     }
-
-    @Override
-    public void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException {
-        SessionPool sessionPool = getSessionPool(connection);
-        String userName = iotDBUser.getUserName();
-        String newPWD = iotDBUser.getPassword();
-        String sql = "alter user " + userName + " set password '" + newPWD + "'";
-        try {
-            sessionPool.executeNonQueryStatement(sql);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.UPDATE_PWD_FAIL, ErrorCode.UPDATE_PWD_FAIL_MSG);
-        } catch (IoTDBConnectionException e) {
-            e.printStackTrace();
-        }
+  }
+
+  private List<String> executeQueryOneColumn(SessionPool sessionPool, String sql)
+      throws BaseException {
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      Callable call = () -> sessionPool.executeQueryStatement(sql);
+      ExecutorService service = Executors.newFixedThreadPool(1);
+      Future submit = service.submit(call);
+      sessionDataSetWrapper = (SessionDataSetWrapper) submit.get(60, TimeUnit.SECONDS);
+      int batchSize = sessionDataSetWrapper.getBatchSize();
+      List<String> values = new ArrayList<>();
+      if (batchSize > 0) {
+        while (sessionDataSetWrapper.hasNext()) {
+          RowRecord rowRecord = sessionDataSetWrapper.next();
+          List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
+          values.add(fields.get(0).toString());
+        }
+      }
+      return values;
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(
+          ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+      throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
+    } catch (ExecutionException e) {
+      e.printStackTrace();
+      if (e.getMessage().contains("600")) {
+        throw new BaseException(ErrorCode.WRONG_USER, ErrorCode.WRONG_USER_MSG);
+      }
+      throw new BaseException(ErrorCode.CONN_REFUSED, ErrorCode.CONN_REFUSED_MSG);
+    } catch (TimeoutException e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
     }
-
-    @Override
-    public void stopQuery(Integer serverId, Long timestamp) throws BaseException {
-        String notStopKey = serverId + ":" + timestamp;
-        if (QUERY_STOP.containsKey(notStopKey)) {
-            QUERY_STOP.put(notStopKey, false);
-            return;
-        }
-        throw new BaseException(ErrorCode.NO_QUERY, ErrorCode.NO_QUERY_MSG);
-    }
-
-
-    private void grantOrRevoke(String word, List<String> privileges, String userName, PrivilegeInfoDTO privilegesInfo, SessionPool sessionPool)
-        throws BaseException {
-        Integer type = privilegesInfo.getType();
-//        String privilegesStr = String.join("','", privileges); 一起存会有bug
-        for (String privilegesStr : privileges) {
-            if (type == 0) {
-                String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root";
-                try {
-                    sessionPool.executeNonQueryStatement(sql);
-                } catch (StatementExecutionException e) {
-                    logger.error(e.getMessage());
-                } catch (IoTDBConnectionException e) {
-                    logger.error(e.getMessage());
-                }
-                continue;
-            }
-            if (type == 1) {
-                List<String> groupPaths = privilegesInfo.getGroupPaths();
-                if (notNullAndNotZero(groupPaths)) {
-                    for (String groupPath : groupPaths) {
-                        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root."
-                            + groupPath;
-                        try {
-                            sessionPool.executeNonQueryStatement(sql);
-                        } catch (StatementExecutionException e) {
-                            logger.error(e.getMessage());
-                        } catch (IoTDBConnectionException e) {
-                            logger.error(e.getMessage());
-                        }
-                    }
-                }
-                continue;
-            }
-            if (type == 2) {
-                List<String> groupPaths = privilegesInfo.getGroupPaths();
-                List<String> devicePaths = privilegesInfo.getDevicePaths();
-                if (notNullAndNotZero(groupPaths) && groupPaths.size() == 1 && notNullAndNotZero(devicePaths)) {
-                    String onlyGroupPath = groupPaths.get(0);
-                    for (String devicePath : devicePaths) {
-                        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root."
-                            + onlyGroupPath + "." + devicePath;
-                        try {
-                            sessionPool.executeNonQueryStatement(sql);
-                        } catch (StatementExecutionException e) {
-                            logger.error(e.getMessage());
-                        } catch (IoTDBConnectionException e) {
-                            logger.error(e.getMessage());
-                        }
-                    }
-                }
-                continue;
-            }
-            if (type == 3) {
-                List<String> groupPaths = privilegesInfo.getGroupPaths();
-                List<String> devicePaths = privilegesInfo.getDevicePaths();
-                List<String> timeseriesPaths = privilegesInfo.getTimeseriesPaths();
-                if (notNullAndNotZero(groupPaths) && groupPaths.size() == 1 && notNullAndNotZero(devicePaths)
-                    && devicePaths.size() == 1 && notNullAndNotZero(timeseriesPaths)) {
-                    String onlyGroupPath = groupPaths.get(0);
-                    String onlyDevicePath = devicePaths.get(0);
-                    for (String timeseriesPath : timeseriesPaths) {
-                        String sql = word + " user " + userName + " privileges '" + privilegesStr + "' on root."
-                            + onlyGroupPath + "." + onlyDevicePath + "." + timeseriesPath;
-                        try {
-                            sessionPool.executeNonQueryStatement(sql);
-                        } catch (StatementExecutionException e) {
-                            logger.error(e.getMessage());
-                        } catch (IoTDBConnectionException e) {
-                            logger.error(e.getMessage());
-                        }
-                    }
-                }
-                continue;
-            }
-            throw new BaseException(ErrorCode.NO_TYPE, ErrorCode.NO_TYPE_MSG);
-        }
+  }
+
+  private List<PrivilegeInfo> privilegesStrSwitchToObject(
+      SessionPool sessionPool, List<String> privileges) throws BaseException {
+    List<PrivilegeInfo> results = new ArrayList<>();
+    List<String> pathStr = new ArrayList<>();
+    List<List<String>> privilegeStr = new ArrayList<>();
+    HashMap<String, Boolean> rootPrivileges = new HashMap();
+    // 遍历集合 将路径和权限集合分别装 过程中 将root相关内容处理
+    for (int i = 0; i < privileges.size(); i++) {
+      String[] split = privileges.get(i).split(":");
+      String[] s = split[1].trim().split(" ");
+      String path = split[0].trim();
+      // 为root特殊处理
+      if ("root".equals(path)) {
+        for (String s1 : s) {
+          if (rootPrivileges.containsKey(s1)) {
+            continue;
+          }
+          rootPrivileges.put(s1, true);
+        }
+        continue;
+      }
+      List<String> list = new ArrayList<>();
+      pathStr.add(path);
+      // 其他粒度下 只需要存储SPECIAL_PRIVILEGES四种权限
+      for (String s1 : s) {
+        if (SPECIAL_PRIVILEGES.containsKey(s1)) {
+          list.add(s1);
+          continue;
+        }
+        // 除了root这一层级 其他此权限不生效 不添加进root权限集合
+        if (NO_NEED_PRIVILEGES.equals(s1)) {
+          continue;
+        }
+        if (rootPrivileges.containsKey(s1)) {
+          continue;
+        }
+        rootPrivileges.put(s1, true);
+      }
+      privilegeStr.add(list);
     }
-
-
-    /**
-     * 判断集合不为空且长度大于0
-     */
-    private boolean notNullAndNotZero(List list) {
-        if (list != null && list.size() > 0) {
-            return true;
-        }
-        return false;
+    // 先处理root 生成对象
+    Set<String> strings = rootPrivileges.keySet();
+    List<String> rootPrivilege = Arrays.asList(strings.toArray(new String[0]));
+    if (rootPrivilege != null && rootPrivilege.size() > 0) {
+      PrivilegeInfo privilegeInfo = new PrivilegeInfo();
+      privilegeInfo.setType(0);
+      privilegeInfo.setPrivileges(rootPrivilege);
+      results.add(privilegeInfo);
     }
-
-    private String executeQueryOneLine(SessionPool sessionPool, String sql, String queryField) throws BaseException {
-        try {
-            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-            int index = -1;
-            for (int i = 0; i < columnNames.size(); i++) {
-                if (queryField.equals(columnNames.get(i))) {
-                    index = i;
-                }
-            }
-            if (index == -1) {
-                throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-            }
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            if (batchSize > 0) {
-                if (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    return rowRecord.getFields().get(index).toString();
-                }
-            }
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        }
-        throw new BaseException(ErrorCode.NO_GROUP, ErrorCode.NO_GROUP_MSG);
+    // 处理非root  String存储形式 "权限1 权限2 权限3.." List存储相同并集下的path路径
+    Map<String, List<String>> privilegeOne = new HashMap<>();
+    Map<String, List<String>> privilegeTwo = new HashMap<>();
+    Map<String, List<String>> privilegeThree = new HashMap<>();
+    for (int i = 0; i < pathStr.size(); i++) {
+      String s = pathStr.get(i);
+      List<String> list = privilegeStr.get(i);
+      String str = String.join(" ", list);
+      // 通过路径获取所属粒度
+      int type = findType(sessionPool, s);
+      if (type == 1) {
+        // 判断相同的权限集合 放入同一list
+        if (privilegeOne.containsKey(str)) {
+          List<String> typeList = privilegeOne.get(str);
+          typeList.add(s);
+          continue;
+        }
+        ArrayList<String> newStr = new ArrayList();
+        newStr.add(s);
+        privilegeOne.put(str, newStr);
+        continue;
+      }
+      if (type == 2) {
+        // 判断相同的权限集合 放入同一list
+        if (privilegeTwo.containsKey(str)) {
+          List<String> typeList = privilegeTwo.get(str);
+          // 相同粒度 同一范围下做前缀判断 相同则为一个并集
+          int existEnd = typeList.get(0).lastIndexOf(".");
+          int end = s.lastIndexOf(".");
+          if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
+            typeList.add(s);
+            continue;
+          }
+        }
+        ArrayList<String> newStr = new ArrayList();
+        newStr.add(s);
+        privilegeTwo.put(str, newStr);
+        continue;
+      }
+      if (type == 3) {
+        if (privilegeThree.containsKey(str)) {
+          List<String> typeList = privilegeThree.get(str);
+          int existEnd = typeList.get(0).lastIndexOf(".");
+          int end = s.lastIndexOf(".");
+          if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
+            typeList.add(s);
+            continue;
+          }
+        }
+        ArrayList<String> newStr = new ArrayList();
+        newStr.add(s);
+        privilegeThree.put(str, newStr);
+      }
     }
-
-    private SqlResultVO executeQuery(SessionPool sessionPool, String sql, Boolean closePool) throws BaseException {
-        SqlResultVO sqlResultVO = new SqlResultVO();
-        List<List<String>> valuelist = new ArrayList<>();
-        try {
-            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            long start = System.currentTimeMillis();
-            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-            sqlResultVO.setMetaDataList(columnNames);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            // 记录行数
-            long count = 0;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    List<String> strList = new ArrayList<>();
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    count++;
-                    for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
-                        strList.add(field.toString());
-                    }
-                    valuelist.add(strList);
-                }
-                long end = System.currentTimeMillis();
-                double time = (end - start + 0.0d) / 1000;
-                String queryTime = time + "s";
-                sqlResultVO.setQueryTime(queryTime);
-                sqlResultVO.setLine(count);
-            }
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        } finally {
-            if (sessionPool != null && closePool) {
-                sessionPool.close();
-            }
-        }
-        sqlResultVO.setValueList(valuelist);
-        return sqlResultVO;
+    Set<String> oneKeys = privilegeOne.keySet();
+    Set<String> twoKeys = privilegeTwo.keySet();
+    Set<String> threeKeys = privilegeThree.keySet();
+    // 封装成PrivilegeInfo返回 字符串处理
+    for (String oneKey : oneKeys) {
+      PrivilegeInfo oneInfo = new PrivilegeInfo();
+      List<String> groupPath = new ArrayList<>();
+      List<String> list = privilegeOne.get(oneKey);
+      for (String s : list) {
+        String groupName = s.replaceFirst("root.", "");
+        groupPath.add(groupName);
+      }
+      List<String> privilegesOne = Arrays.asList(oneKey.split(" "));
+      String sql = "show storage group";
+      List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
+      List<String> allGroupPaths = new ArrayList<>();
+      for (String s : allGroupPathsStr) {
+        String field = s.replaceFirst("root.", "");
+        allGroupPaths.add(field);
+      }
+      // 展示数据
+      oneInfo.setType(1);
+      oneInfo.setPrivileges(privilegesOne);
+      // allxxx内容为前端编辑修改时需要的数据
+      oneInfo.setGroupPaths(groupPath);
+      oneInfo.setAllGroupPaths(allGroupPaths);
+      results.add(oneInfo);
     }
-
-    private SqlResultVO executeQuery(SessionPool sessionPool, String sql, Boolean closePool, String notStopKey, boolean timeFlag) throws BaseException {
-        SqlResultVO sqlResultVO = new SqlResultVO();
-        List<List<String>> valuelist = new ArrayList<>();
-        try {
-            SessionDataSetWrapper sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            long start = System.currentTimeMillis();
-            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-            sqlResultVO.setMetaDataList(columnNames);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            // 记录行数
-            long count = 0;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext() && QUERY_STOP.get(notStopKey)) {
-                    List<String> strList = new ArrayList<>();
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    if (timeFlag) {
-                        long timestamp = rowRecord.getTimestamp();
-                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
-                        Date date = new Date(timestamp);
-                        String timeStr = simpleDateFormat.format(date);
-                        strList.add(timeStr);
-                    }
-                    count++;
-                    for (org.apache.iotdb.tsfile.read.common.Field field : rowRecord.getFields()) {
-                        strList.add(field.toString());
-                    }
-                    valuelist.add(strList);
-                }
-                long end = System.currentTimeMillis();
-                double time = (end - start + 0.0d) / 1000;
-                String queryTime = time + "s";
-                sqlResultVO.setQueryTime(queryTime);
-                sqlResultVO.setLine(count);
-            }
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            if (e.getStatusCode() == 602) {
-                throw new BaseException(ErrorCode.NO_PRI_TIMESERIES_DATA, ErrorCode.NO_PRI_TIMESERIES_DATA_MSG);
-            }
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        } finally {
-            if (sessionPool != null && closePool) {
-                sessionPool.close();
-            }
-        }
-        sqlResultVO.setValueList(valuelist);
-        return sqlResultVO;
+    for (String twoKey : twoKeys) {
+      PrivilegeInfo twoInfo = new PrivilegeInfo();
+      List<String> groupPath = new ArrayList<>();
+      List<String> devicePath = new ArrayList<>();
+      List<String> list = privilegeTwo.get(twoKey);
+      // 得到 组名、设备名、测点名  便于后续字符串操作
+      PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
+      groupPath.add(pathVO.getGroupName());
+      for (String s : list) {
+        String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
+        devicePath.add(deviceName);
+      }
+      List<String> privilegesTwo = Arrays.asList(twoKey.split(" "));
+      String sql = "show storage group";
+      List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
+      List<String> allGroupPaths = new ArrayList<>();
+      for (String s : allGroupPathsStr) {
+        String field = s.replaceFirst("root.", "");
+        allGroupPaths.add(field);
+      }
+      int end = list.get(0).lastIndexOf(".");
+      sql = "show devices " + list.get(0).substring(0, end) + ".*";
+      List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
+      List<String> allDevicePaths = new ArrayList<>();
+      for (String s : allDevicePathsStr) {
+        String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
+        allDevicePaths.add(field);
+      }
+      // 展示数据
+      twoInfo.setType(2);
+      twoInfo.setPrivileges(privilegesTwo);
+      twoInfo.setGroupPaths(groupPath);
+      twoInfo.setDevicePaths(devicePath);
+      // allxxx内容为前端编辑修改时需要的数据
+      twoInfo.setAllGroupPaths(allGroupPaths);
+      twoInfo.setAllDevicePaths(allDevicePaths);
+      results.add(twoInfo);
     }
-
-
-    private <T> CountDTO executeQuery(Class<T> clazz, SessionPool sessionPool, String sql, Integer pageSize, Integer pageNum, String keyword)
-        throws BaseException {
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            List<T> results = new ArrayList<>();
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            int count = 0;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    count++;
-                    if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-                        T t = clazz.newInstance();
-                        List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
-                        List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-                        for (int i = 0; i < fields.size(); i++) {
-                            Field field = clazz.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
-                            field.setAccessible(true);
-                            field.set(t, fields.get(i).toString());
-                        }
-                        results.add(t);
-                    }
-                }
-            }
-            CountDTO countDTO = new CountDTO();
-            countDTO.setObjects(results);
-            countDTO.setTotalCount(count);
-            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
-            countDTO.setTotalPage(totalPage);
-            return countDTO;
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
-        } catch (Exception e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-        }
+    for (String threeKey : threeKeys) {
+      PrivilegeInfo threeInfo = new PrivilegeInfo();
+      List<String> groupPath = new ArrayList<>();
+      List<String> devicePath = new ArrayList<>();
+      List<String> timeseriesPath = new ArrayList<>();
+      List<String> list = privilegeThree.get(threeKey);
+      // 得到 组名、设备名、测点名  便于后续字符串操作
+      PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
+      groupPath.add(pathVO.getGroupName());
+      devicePath.add(pathVO.getDeviceName());
+      for (String s : list) {
+        String timeseriesName =
+            s.replaceFirst(
+                "root." + pathVO.getGroupName() + "." + pathVO.getDeviceName() + ".", "");
+        timeseriesPath.add(timeseriesName);
+      }
+      List<String> privilegesOne = Arrays.asList(threeKey.split(" "));
+      String sql = "show storage group";
+      List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
+      List<String> allGroupPaths = new ArrayList<>();
+      for (String s : allGroupPathsStr) {
+        String field = s.replaceFirst("root.", "");
+        allGroupPaths.add(field);
+      }
+      sql = "show devices root." + pathVO.getGroupName() + ".*";
+      List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
+      List<String> allDevicePaths = new ArrayList<>();
+      for (String s : allDevicePathsStr) {
+        String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
+        allDevicePaths.add(deviceName);
+      }
+      int end = list.get(0).lastIndexOf(".");
+      sql = "show timeseries " + list.get(0).substring(0, end) + ".*";
+      List<String> allTimeseriesPathsStr = executeQueryOneColumn(sessionPool, sql);
+      List<String> allTimeseriesPaths = new ArrayList<>();
+      for (String s : allTimeseriesPathsStr) {
+        String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
+        allTimeseriesPaths.add(field);
+      }
+      // 展示数据
+      threeInfo.setType(3);
+      threeInfo.setPrivileges(privilegesOne);
+      threeInfo.setGroupPaths(groupPath);
+      threeInfo.setDevicePaths(devicePath);
+      threeInfo.setTimeseriesPaths(timeseriesPath);
+      // allxxx内容为前端编辑修改时需要的数据
+      threeInfo.setAllGroupPaths(allGroupPaths);
+      threeInfo.setAllDevicePaths(allDevicePaths);
+      threeInfo.setAllTimeseriesPaths(allTimeseriesPaths);
+      results.add(threeInfo);
     }
-
-    private String executeQueryOneValue(SessionPool sessionPool, String sql) throws BaseException {
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            String value = null;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
-                    value = fields.get(0).toString();
-                    break;
-                }
-            }
-            return value;
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            if (e.getStatusCode() == 602 && sql != null && sql.contains("select")) {
-                throw new BaseException(ErrorCode.NO_PRI_READ_TIMESERIES, ErrorCode.NO_PRI_READ_TIMESERIES_MSG);
-            }
-            throw new BaseException(ErrorCode.GET_SQL_ONE_VALUE_FAIL, ErrorCode.GET_SQL_ONE_VALUE_FAIL_MSG);
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-        }
+    return results;
+  }
+
+  private PathVO splitPathToPathVO(SessionPool sessionPool, String s) throws BaseException {
+    PathVO pathVO = new PathVO();
+    while (!"root".equals(s)) {
+      String sql = "count devices " + s;
+      Integer isDevice = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+      sql = "count storage group " + s;
+      Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+      // 为测点
+      if (isDevice == 0 && isGroup == 0) {
+        int mid = s.lastIndexOf(".");
+        String timeseriesName = s.substring(mid + 1);
+        pathVO.setTimeseriesName(timeseriesName);
+        s = s.substring(0, mid);
+        continue;
+      }
+      // 既是存储组也是实体
+      if (isDevice == 1 && isGroup == 1) {
+        String deviceName = s.replaceFirst("root.", "");
+        String groupName = s.replaceFirst("root.", "");
+        pathVO.setGroupName(groupName);
+        pathVO.setDeviceName(deviceName);
+        break;
+      }
+      // 是存储组 判断是否还为实体
+      if (isDevice > 1 && isGroup == 1) {
+        sql = "show devices " + s;
+        List<String> list = executeQueryOneColumn(sessionPool, sql);
+        if (list.contains(s)) {
+          String deviceName = s.replaceFirst("root.", "");
+          String groupName = s.replaceFirst("root.", "");
+          pathVO.setGroupName(groupName);
+          pathVO.setDeviceName(deviceName);
+          break;
+        }
+        String groupName = s.replaceFirst("root.", "");
+        pathVO.setGroupName(groupName);
+      }
+      // 为存储组
+      if (isDevice == 0 && isGroup == 1) {
+        String groupName = s.replaceFirst("root.", "");
+        pathVO.setGroupName(groupName);
+        break;
+      }
+      // 实体 实体之下还可以有实体 需要遍历有多少层级
+      if (isDevice >= 1 && isGroup == 0) {
+        String oldS = s;
+        while (true) {
+          int mid = s.lastIndexOf(".");
+          s = s.substring(0, mid);
+          sql = "count storage group " + s;
+          isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+          if (isGroup > 0) {
+            String deviceName = oldS.replaceFirst(s + ".", "");
+            String groupName = s.replaceFirst("root.", "");
+            pathVO.setGroupName(groupName);
+            pathVO.setDeviceName(deviceName);
+            break;
+          }
+        }
+        break;
+      }
     }
-
-    private CountDTO executeQueryOneColumn(SessionPool sessionPool, String sql, Integer pageSize, Integer pageNum) throws BaseException {
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            List<String> values = new ArrayList<>();
-            int count = 0;
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    count++;
-                    if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-                        List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
-                        values.add(fields.get(0).toString());
-                    }
-                }
-            }
-            CountDTO countDTO = new CountDTO();
-            countDTO.setObjects(values);
-            countDTO.setTotalCount(count);
-            Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
-            countDTO.setTotalPage(totalPage);
-            return countDTO;
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-        }
+    return pathVO;
+  }
+
+  private int findType(SessionPool sessionPool, String s) throws BaseException {
+    // 主要用于判断s路径是否已经不存在 iotdb存在已删除路径的权限还会展示出来的问题
+    String sql = "count timeseries " + s;
+    SessionDataSetWrapper sessionDataSetWrapper = null;
+    try {
+      sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
+    } catch (IoTDBConnectionException e) {
+      logger.error(e.getMessage());
+      return -1;
+    } catch (StatementExecutionException e) {
+      logger.error(e.getMessage());
+      return -1;
+    } finally {
+      if (sessionDataSetWrapper != null) {
+        sessionDataSetWrapper.close();
+      }
     }
-
-    private List<String> executeQueryOneColumn(SessionPool sessionPool, String sql) throws BaseException {
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            Callable call = () -> sessionPool.executeQueryStatement(sql);
-            ExecutorService service = Executors.newFixedThreadPool(1);
-            Future submit = service.submit(call);
-            sessionDataSetWrapper = (SessionDataSetWrapper) submit.get(60, TimeUnit.SECONDS);
-            int batchSize = sessionDataSetWrapper.getBatchSize();
-            List<String> values = new ArrayList<>();
-            if (batchSize > 0) {
-                while (sessionDataSetWrapper.hasNext()) {
-                    RowRecord rowRecord = sessionDataSetWrapper.next();
-                    List<org.apache.iotdb.tsfile.read.common.Field> fields = rowRecord.getFields();
-                    values.add(fields.get(0).toString());
-                }
-            }
-            return values;
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_SQL_ONE_COLUMN_FAIL, ErrorCode.GET_SQL_ONE_COLUMN_FAIL_MSG);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
-        } catch (ExecutionException e) {
-            e.printStackTrace();
-            if (e.getMessage().contains("600")) {
-                throw new BaseException(ErrorCode.WRONG_USER, ErrorCode.WRONG_USER_MSG);
-            }
-            throw new BaseException(ErrorCode.CONN_REFUSED, ErrorCode.CONN_REFUSED_MSG);
-        } catch (TimeoutException e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.TIME_OUT, ErrorCode.TIME_OUT_MSG);
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-        }
+    sql = "count storage group " + s;
+    Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+    if (isGroup == 1) {
+      return 1;
     }
-
-
-    private List<PrivilegeInfo> privilegesStrSwitchToObject(SessionPool sessionPool, List<String> privileges) throws BaseException {
-        List<PrivilegeInfo> results = new ArrayList<>();
-        List<String> pathStr = new ArrayList<>();
-        List<List<String>> privilegeStr = new ArrayList<>();
-        HashMap<String, Boolean> rootPrivileges = new HashMap();
-        // 遍历集合 将路径和权限集合分别装 过程中 将root相关内容处理
-        for (int i = 0; i < privileges.size(); i++) {
-            String[] split = privileges.get(i).split(":");
-            String[] s = split[1].trim().split(" ");
-            String path = split[0].trim();
-            //为root特殊处理
-            if ("root".equals(path)) {
-                for (String s1 : s) {
-                    if (rootPrivileges.containsKey(s1)) {
-                        continue;
-                    }
-                    rootPrivileges.put(s1, true);
-                }
-                continue;
-            }
-            List<String> list = new ArrayList<>();
-            pathStr.add(path);
-            // 其他粒度下 只需要存储SPECIAL_PRIVILEGES四种权限
-            for (String s1 : s) {
-                if (SPECIAL_PRIVILEGES.containsKey(s1)) {
-                    list.add(s1);
-                    continue;
-                }
-                // 除了root这一层级 其他此权限不生效 不添加进root权限集合
-                if (NO_NEED_PRIVILEGES.equals(s1)) {
-                    continue;
-                }
-                if (rootPrivileges.containsKey(s1)) {
-                    continue;
-                }
-                rootPrivileges.put(s1, true);
-            }
-            privilegeStr.add(list);
-        }
-        // 先处理root 生成对象
-        Set<String> strings = rootPrivileges.keySet();
-        List<String> rootPrivilege = Arrays.asList(strings.toArray(new String[0]));
-        if (rootPrivilege != null && rootPrivilege.size() > 0) {
-            PrivilegeInfo privilegeInfo = new PrivilegeInfo();
-            privilegeInfo.setType(0);
-            privilegeInfo.setPrivileges(rootPrivilege);
-            results.add(privilegeInfo);
-        }
-        // 处理非root  String存储形式 "权限1 权限2 权限3.." List存储相同并集下的path路径
-        Map<String, List<String>> privilegeOne = new HashMap<>();
-        Map<String, List<String>> privilegeTwo = new HashMap<>();
-        Map<String, List<String>> privilegeThree = new HashMap<>();
-        for (int i = 0; i < pathStr.size(); i++) {
-            String s = pathStr.get(i);
-            List<String> list = privilegeStr.get(i);
-            String str = String.join(" ", list);
-            // 通过路径获取所属粒度
-            int type = findType(sessionPool, s);
-            if (type == 1) {
-                // 判断相同的权限集合 放入同一list
-                if (privilegeOne.containsKey(str)) {
-                    List<String> typeList = privilegeOne.get(str);
-                    typeList.add(s);
-                    continue;
-                }
-                ArrayList<String> newStr = new ArrayList();
-                newStr.add(s);
-                privilegeOne.put(str, newStr);
-                continue;
-            }
-            if (type == 2) {
-                // 判断相同的权限集合 放入同一list
-                if (privilegeTwo.containsKey(str)) {
-                    List<String> typeList = privilegeTwo.get(str);
-                    // 相同粒度 同一范围下做前缀判断 相同则为一个并集
-                    int existEnd = typeList.get(0).lastIndexOf(".");
-                    int end = s.lastIndexOf(".");
-                    if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
-                        typeList.add(s);
-                        continue;
-                    }
-                }
-                ArrayList<String> newStr = new ArrayList();
-                newStr.add(s);
-                privilegeTwo.put(str, newStr);
-                continue;
-            }
-            if (type == 3) {
-                if (privilegeThree.containsKey(str)) {
-                    List<String> typeList = privilegeThree.get(str);
-                    int existEnd = typeList.get(0).lastIndexOf(".");
-                    int end = s.lastIndexOf(".");
-                    if (typeList.get(0).substring(0, existEnd).equals(s.substring(0, end))) {
-                        typeList.add(s);
-                        continue;
-                    }
-                }
-                ArrayList<String> newStr = new ArrayList();
-                newStr.add(s);
-                privilegeThree.put(str, newStr);
-            }
-        }
-        Set<String> oneKeys = privilegeOne.keySet();
-        Set<String> twoKeys = privilegeTwo.keySet();
-        Set<String> threeKeys = privilegeThree.keySet();
-        // 封装成PrivilegeInfo返回 字符串处理
-        for (String oneKey : oneKeys) {
-            PrivilegeInfo oneInfo = new PrivilegeInfo();
-            List<String> groupPath = new ArrayList<>();
-            List<String> list = privilegeOne.get(oneKey);
-            for (String s : list) {
-                String groupName = s.replaceFirst("root.", "");
-                groupPath.add(groupName);
-            }
-            List<String> privilegesOne = Arrays.asList(oneKey.split(" "));
-            String sql = "show storage group";
-            List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
-            List<String> allGroupPaths = new ArrayList<>();
-            for (String s : allGroupPathsStr) {
-                String field = s.replaceFirst("root.", "");
-                allGroupPaths.add(field);
-            }
-            // 展示数据
-            oneInfo.setType(1);
-            oneInfo.setPrivileges(privilegesOne);
-            // allxxx内容为前端编辑修改时需要的数据
-            oneInfo.setGroupPaths(groupPath);
-            oneInfo.setAllGroupPaths(allGroupPaths);
-            results.add(oneInfo);
-        }
-        for (String twoKey : twoKeys) {
-            PrivilegeInfo twoInfo = new PrivilegeInfo();
-            List<String> groupPath = new ArrayList<>();
-            List<String> devicePath = new ArrayList<>();
-            List<String> list = privilegeTwo.get(twoKey);
-            // 得到 组名、设备名、测点名  便于后续字符串操作
-            PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
-            groupPath.add(pathVO.getGroupName());
-            for (String s : list) {
-                String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
-                devicePath.add(deviceName);
-            }
-            List<String> privilegesTwo = Arrays.asList(twoKey.split(" "));
-            String sql = "show storage group";
-            List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
-            List<String> allGroupPaths = new ArrayList<>();
-            for (String s : allGroupPathsStr) {
-                String field = s.replaceFirst("root.", "");
-                allGroupPaths.add(field);
-            }
-            int end = list.get(0).lastIndexOf(".");
-            sql = "show devices " + list.get(0).substring(0, end) + ".*";
-            List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
-            List<String> allDevicePaths = new ArrayList<>();
-            for (String s : allDevicePathsStr) {
-                String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
-                allDevicePaths.add(field);
-            }
-            // 展示数据
-            twoInfo.setType(2);
-            twoInfo.setPrivileges(privilegesTwo);
-            twoInfo.setGroupPaths(groupPath);
-            twoInfo.setDevicePaths(devicePath);
-            // allxxx内容为前端编辑修改时需要的数据
-            twoInfo.setAllGroupPaths(allGroupPaths);
-            twoInfo.setAllDevicePaths(allDevicePaths);
-            results.add(twoInfo);
-        }
-        for (String threeKey : threeKeys) {
-            PrivilegeInfo threeInfo = new PrivilegeInfo();
-            List<String> groupPath = new ArrayList<>();
-            List<String> devicePath = new ArrayList<>();
-            List<String> timeseriesPath = new ArrayList<>();
-            List<String> list = privilegeThree.get(threeKey);
-            // 得到 组名、设备名、测点名  便于后续字符串操作
-            PathVO pathVO = splitPathToPathVO(sessionPool, list.get(0));
-            groupPath.add(pathVO.getGroupName());
-            devicePath.add(pathVO.getDeviceName());
-            for (String s : list) {
-                String timeseriesName = s.replaceFirst("root." + pathVO.getGroupName() + "." + pathVO.getDeviceName() + ".", "");
-                timeseriesPath.add(timeseriesName);
-            }
-            List<String> privilegesOne = Arrays.asList(threeKey.split(" "));
-            String sql = "show storage group";
-            List<String> allGroupPathsStr = executeQueryOneColumn(sessionPool, sql);
-            List<String> allGroupPaths = new ArrayList<>();
-            for (String s : allGroupPathsStr) {
-                String field = s.replaceFirst("root.", "");
-                allGroupPaths.add(field);
-            }
-            sql = "show devices root." + pathVO.getGroupName() + ".*";
-            List<String> allDevicePathsStr = executeQueryOneColumn(sessionPool, sql);
-            List<String> allDevicePaths = new ArrayList<>();
-            for (String s : allDevicePathsStr) {
-                String deviceName = s.replaceFirst("root." + pathVO.getGroupName() + ".", "");
-                allDevicePaths.add(deviceName);
-            }
-            int end = list.get(0).lastIndexOf(".");
-            sql = "show timeseries " + list.get(0).substring(0, end) + ".*";
-            List<String> allTimeseriesPathsStr = executeQueryOneColumn(sessionPool, sql);
-            List<String> allTimeseriesPaths = new ArrayList<>();
-            for (String s : allTimeseriesPathsStr) {
-                String field = s.replaceFirst(list.get(0).substring(0, end) + ".", "");
-                allTimeseriesPaths.add(field);
-            }
-            // 展示数据
-            threeInfo.setType(3);
-            threeInfo.setPrivileges(privilegesOne);
-            threeInfo.setGroupPaths(groupPath);
-            threeInfo.setDevicePaths(devicePath);
-            threeInfo.setTimeseriesPaths(timeseriesPath);
-            // allxxx内容为前端编辑修改时需要的数据
-            threeInfo.setAllGroupPaths(allGroupPaths);
-            threeInfo.setAllDevicePaths(allDevicePaths);
-            threeInfo.setAllTimeseriesPaths(allTimeseriesPaths);
-            results.add(threeInfo);
-        }
-        return results;
-    }
-
-    private PathVO splitPathToPathVO(SessionPool sessionPool, String s) throws BaseException {
-        PathVO pathVO = new PathVO();
-        while (!"root".equals(s)) {
-            String sql = "count devices " + s;
-            Integer isDevice = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-            sql = "count storage group " + s;
-            Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-            // 为测点
-            if (isDevice == 0 && isGroup == 0) {
-                int mid = s.lastIndexOf(".");
-                String timeseriesName = s.substring(mid + 1);
-                pathVO.setTimeseriesName(timeseriesName);
-                s = s.substring(0, mid);
-                continue;
-            }
-            // 既是存储组也是实体
-            if (isDevice == 1 && isGroup == 1) {
-                String deviceName = s.replaceFirst("root.", "");
-                String groupName = s.replaceFirst("root.", "");
-                pathVO.setGroupName(groupName);
-                pathVO.setDeviceName(deviceName);
-                break;
-            }
-            // 是存储组 判断是否还为实体
-            if (isDevice > 1 && isGroup == 1) {
-                sql = "show devices " + s;
-                List<String> list = executeQueryOneColumn(sessionPool, sql);
-                if (list.contains(s)) {
-                    String deviceName = s.replaceFirst("root.", "");
-                    String groupName = s.replaceFirst("root.", "");
-                    pathVO.setGroupName(groupName);
-                    pathVO.setDeviceName(deviceName);
-                    break;
-                }
-                String groupName = s.replaceFirst("root.", "");
-                pathVO.setGroupName(groupName);
-            }
-            // 为存储组
-            if (isDevice == 0 && isGroup == 1) {
-                String groupName = s.replaceFirst("root.", "");
-                pathVO.setGroupName(groupName);
-                break;
-            }
-            // 实体 实体之下还可以有实体 需要遍历有多少层级
-            if (isDevice >= 1 && isGroup == 0) {
-                String oldS = s;
-                while (true) {
-                    int mid = s.lastIndexOf(".");
-                    s = s.substring(0, mid);
-                    sql = "count storage group " + s;
-                    isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-                    if (isGroup > 0) {
-                        String deviceName = oldS.replaceFirst(s + ".", "");
-                        String groupName = s.replaceFirst("root.", "");
-                        pathVO.setGroupName(groupName);
-                        pathVO.setDeviceName(deviceName);
-                        break;
-                    }
-                }
-                break;
-            }
-        }
-        return pathVO;
+    // 无效路径 既不是root 也不是存储组 不展示到页面
+    if (isGroup > 1) {
+      return -1;
     }
-
-    private int findType(SessionPool sessionPool, String s) throws BaseException {
-        // 主要用于判断s路径是否已经不存在 iotdb存在已删除路径的权限还会展示出来的问题
-        String sql = "count timeseries " + s;
-        SessionDataSetWrapper sessionDataSetWrapper = null;
-        try {
-            sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
-        } catch (IoTDBConnectionException e) {
-            logger.error(e.getMessage());
-            return -1;
-        } catch (StatementExecutionException e) {
-            logger.error(e.getMessage());
-            return -1;
-        } finally {
-            if (sessionDataSetWrapper != null) {
-                sessionDataSetWrapper.close();
-            }
-        }
-        sql = "count storage group " + s;
-        Integer isGroup = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-        if (isGroup == 1) {
-            return 1;
-        }
-        // 无效路径 既不是root 也不是存储组 不展示到页面
-        if (isGroup > 1) {
-            return -1;
-        }
-        sql = "count devices " + s;
-        Integer isDevices = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
-        if (isDevices == 1) {
-            return 2;
-        }
-        return 3;
-    }
-
-    private List<TSEncoding> handleEncodingStr(List<String> encoding) {
-        List<TSEncoding> list = new ArrayList<>();
-        for (String s : encoding) {
-            switch (s) {
-                case "PLAIN":
-                    list.add(TSEncoding.PLAIN);
-                    break;
-                case "PLAIN_DICTIONARY":
-                    list.add(TSEncoding.PLAIN_DICTIONARY);
-                    break;
-                case "RLE":
-                    list.add(TSEncoding.RLE);
-                    break;
-                case "DIFF":
-                    list.add(TSEncoding.DIFF);
-                    break;
-                case "TS_2DIFF":
-                    list.add(TSEncoding.TS_2DIFF);
-                    break;
-                case "BITMAP":
-                    list.add(TSEncoding.BITMAP);
-                    break;
-                case "GORILLA_V1":
-                    list.add(TSEncoding.GORILLA_V1);
-                    break;
-                case "REGULAR":
-                    list.add(TSEncoding.REGULAR);
-                    break;
-                case "GORILLA":
-                    list.add(TSEncoding.GORILLA);
-                    break;
-            }
-        }
-        return list;
-    }
-
-    private List<Object> handleValueStr(List<String> values, List<TSDataType> types) throws BaseException {
-        List<Object> list = new ArrayList<>();
-        for (int i = 0; i < types.size(); i++) {
-            TSDataType type = types.get(i);
-            if (type == TSDataType.BOOLEAN) {
-                Integer booleanNum = Integer.valueOf(values.get(i));
-                Boolean flag = null;
-                if (booleanNum == 0) {
-                    flag = false;
-                }
-                if (booleanNum == 1) {
-                    flag = true;
-                }
-                if (flag != null) {
-                    list.add(flag);
-                    continue;
-                }
-                throw new BaseException(ErrorCode.DB_BOOL_WRONG, ErrorCode.DB_BOOL_WRONG_MSG);
-            }
-            if (type == TSDataType.INT32 || type == TSDataType.INT64) {
-                Integer intNum = Integer.valueOf(values.get(i));
-                list.add(intNum);
-                continue;
-            }
-            if (type == TSDataType.FLOAT) {
-                Float floatNum = Float.valueOf(values.get(i));
-                list.add(floatNum);
-                continue;
-            }
-            if (type == TSDataType.DOUBLE) {
-                Double doubleNum = Double.valueOf(values.get(i));
-                list.add(doubleNum);
-                continue;
-            }
-            list.add(values.get(i));
-        }
-        return list;
-    }
-
-    private List<TSDataType> handleTypeStr(List<String> types) throws BaseException {
-        List<TSDataType> list = new ArrayList<>();
-        for (String type : types) {
-            TSDataType tsDataType;
-            switch (type) {
-                case "BOOLEAN":
-                    tsDataType = TSDataType.BOOLEAN;
-                    break;
-                case "INT32":
-                    tsDataType = TSDataType.INT32;
-                    break;
-                case "INT64":
-                    tsDataType = TSDataType.INT64;
-                    break;
-                case "FLOAT":
-                    tsDataType = TSDataType.FLOAT;
-                    break;
-                case "DOUBLE":
-                    tsDataType = TSDataType.DOUBLE;
-                    break;
-                case "TEXT":
-                    tsDataType = TSDataType.TEXT;
-                    break;
-                default:
-                    throw new BaseException(ErrorCode.DB_DATATYPE_WRONG, ErrorCode.DB_DATATYPE_WRONG_MSG);
-            }
-            list.add(tsDataType);
-        }
-        return list;
+    sql = "count devices " + s;
+    Integer isDevices = Integer.valueOf(executeQueryOneValue(sessionPool, sql));
+    if (isDevices == 1) {
+      return 2;
     }
-
-
-    public static java.sql.Connection getConnection(Connection connection) throws BaseException {
-        String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
-        String url = "jdbc:iotdb://" + connection.getHost() + ":" + connection.getPort() + "/";
-        String username = connection.getUsername();
-        String password = connection.getPassword();
-        java.sql.Connection conn;
-        try {
-            Class.forName(driver);
-            conn = DriverManager.getConnection(url, username, password);
-        } catch (ClassNotFoundException e) {
-            throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
-        } catch (SQLException e) {
-            throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
-        }
-        return conn;
+    return 3;
+  }
+
+  private List<TSEncoding> handleEncodingStr(List<String> encoding) {
+    List<TSEncoding> list = new ArrayList<>();
+    for (String s : encoding) {
+      switch (s) {
+        case "PLAIN":
+          list.add(TSEncoding.PLAIN);
+          break;
+        case "PLAIN_DICTIONARY":
+          list.add(TSEncoding.PLAIN_DICTIONARY);
+          break;
+        case "RLE":
+          list.add(TSEncoding.RLE);
+          break;
+        case "DIFF":
+          list.add(TSEncoding.DIFF);
+          break;
+        case "TS_2DIFF":
+          list.add(TSEncoding.TS_2DIFF);
+          break;
+        case "BITMAP":
+          list.add(TSEncoding.BITMAP);
+          break;
+        case "GORILLA_V1":
+          list.add(TSEncoding.GORILLA_V1);
+          break;
+        case "REGULAR":
+          list.add(TSEncoding.REGULAR);
+          break;
+        case "GORILLA":
+          list.add(TSEncoding.GORILLA);
+          break;
+      }
     }
-
-    public static SessionPool getSessionPool(Connection connection) throws BaseException {
-        String host = connection.getHost();
-        Integer port = connection.getPort();
-        String username = connection.getUsername();
-        String password = connection.getPassword();
-        SessionPool sessionPool = null;
-        try {
-            sessionPool = new SessionPool(host, port, username, password, 3);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
-        }
-        return sessionPool;
-    }
-//    public static SessionPool getSession(Connection connection) throws BaseException {
-//        if(sessionPool == null){
-//            host = connection.getHost();
-//            port = connection.getPort();
-//            username = connection.getUsername();
-//            password = connection.getPassword();
-//            sessionPool = new SessionPool(host,port,username,password,3);
-//            return sessionPool;
-//        }
-//        if(host == connection.getHost() && port.equals(connection.getPort()) && username == connection.getUsername() && password == connection.getPassword()){
-//            return sessionPool;
-//        }
-//        sessionPool.close();
-//        host = connection.getHost();
-//        port = connection.getPort();
-//        username = connection.getUsername();
-//        password = connection.getPassword();
-//        sessionPool = new SessionPool(host,port,username,password,3);
-//        return sessionPool;
-//    }
-
-    private void closeConnection(java.sql.Connection conn) throws BaseException {
+    return list;
+  }
+
+  private List<Object> handleValueStr(List<String> values, List<TSDataType> types)
+      throws BaseException {
+    List<Object> list = new ArrayList<>();
+    for (int i = 0; i < types.size(); i++) {
+      TSDataType type = types.get(i);
+      if (type == TSDataType.BOOLEAN) {
+        Integer booleanNum = Integer.valueOf(values.get(i));
+        Boolean flag = null;
+        if (booleanNum == 0) {
+          flag = false;
+        }
+        if (booleanNum == 1) {
+          flag = true;
+        }
+        if (flag != null) {
+          list.add(flag);
+          continue;
+        }
+        throw new BaseException(ErrorCode.DB_BOOL_WRONG, ErrorCode.DB_BOOL_WRONG_MSG);
+      }
+      if (type == TSDataType.INT32 || type == TSDataType.INT64) {
+        Integer intNum = Integer.valueOf(values.get(i));
+        list.add(intNum);
+        continue;
+      }
+      if (type == TSDataType.FLOAT) {
+        Float floatNum = Float.valueOf(values.get(i));
+        list.add(floatNum);
+        continue;
+      }
+      if (type == TSDataType.DOUBLE) {
+        Double doubleNum = Double.valueOf(values.get(i));
+        list.add(doubleNum);
+        continue;
+      }
+      list.add(values.get(i));
+    }
+    return list;
+  }
+
+  private List<TSDataType> handleTypeStr(List<String> types) throws BaseException {
+    List<TSDataType> list = new ArrayList<>();
+    for (String type : types) {
+      TSDataType tsDataType;
+      switch (type) {
+        case "BOOLEAN":
+          tsDataType = TSDataType.BOOLEAN;
+          break;
+        case "INT32":
+          tsDataType = TSDataType.INT32;
+          break;
+        case "INT64":
+          tsDataType = TSDataType.INT64;
+          break;
+        case "FLOAT":
+          tsDataType = TSDataType.FLOAT;
+          break;
+        case "DOUBLE":
+          tsDataType = TSDataType.DOUBLE;
+          break;
+        case "TEXT":
+          tsDataType = TSDataType.TEXT;
+          break;
+        default:
+          throw new BaseException(ErrorCode.DB_DATATYPE_WRONG, ErrorCode.DB_DATATYPE_WRONG_MSG);
+      }
+      list.add(tsDataType);
+    }
+    return list;
+  }
+
+  public static java.sql.Connection getConnection(Connection connection) throws BaseException {
+    String driver = "org.apache.iotdb.jdbc.IoTDBDriver";
+    String url = "jdbc:iotdb://" + connection.getHost() + ":" + connection.getPort() + "/";
+    String username = connection.getUsername();
+    String password = connection.getPassword();
+    java.sql.Connection conn;
+    try {
+      Class.forName(driver);
+      conn = DriverManager.getConnection(url, username, password);
+    } catch (ClassNotFoundException e) {
+      throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
+    } catch (SQLException e) {
+      throw new BaseException(ErrorCode.GET_DBCONN_FAIL, ErrorCode.GET_DBCONN_FAIL_MSG);
+    }
+    return conn;
+  }
+
+  public static SessionPool getSessionPool(Connection connection) throws BaseException {
+    String host = connection.getHost();
+    Integer port = connection.getPort();
+    String username = connection.getUsername();
+    String password = connection.getPassword();
+    SessionPool sessionPool = null;
+    try {
+      sessionPool = new SessionPool(host, port, username, password, 3);
+    } catch (Exception e) {
+      throw new BaseException(ErrorCode.GET_SESSION_FAIL, ErrorCode.GET_SESSION_FAIL_MSG);
+    }
+    return sessionPool;
+  }
+  //    public static SessionPool getSession(Connection connection) throws BaseException {
+  //        if(sessionPool == null){
+  //            host = connection.getHost();
+  //            port = connection.getPort();
+  //            username = connection.getUsername();
+  //            password = connection.getPassword();
+  //            sessionPool = new SessionPool(host,port,username,password,3);
+  //            return sessionPool;
+  //        }
+  //        if(host == connection.getHost() && port.equals(connection.getPort()) && username ==
+  // connection.getUsername() && password == connection.getPassword()){
+  //            return sessionPool;
+  //        }
+  //        sessionPool.close();
+  //        host = connection.getHost();
+  //        port = connection.getPort();
+  //        username = connection.getUsername();
+  //        password = connection.getPassword();
+  //        sessionPool = new SessionPool(host,port,username,password,3);
+  //        return sessionPool;
+  //    }
+
+  private void closeConnection(java.sql.Connection conn) throws BaseException {
+    try {
+      if (conn != null) {
+        conn.close();
+      }
+    } catch (SQLException e) {
+      throw new BaseException(ErrorCode.CLOSE_DBCONN_FAIL, ErrorCode.CLOSE_DBCONN_FAIL_MSG);
+    }
+  }
+
+  private String handlerPrivilegeStrToSql(String privilege, String userName, String roleName) {
+    int i = privilege.indexOf(":");
+    String path = privilege.substring(0, i).trim();
+    String[] privileges = privilege.substring(i + 1).trim().split(" ");
+    int len = privileges.length;
+    if (len == 0) {
+      return null;
+    }
+    StringBuilder str = new StringBuilder();
+    if (userName != null) {
+      str.append("grant user " + userName + " privileges ");
+    } else {
+      str.append("grant role " + roleName + " privileges ");
+    }
+    for (int j = 0; i < len - 1; j++) {
+      str.append("'" + privileges[j] + "',");
+    }
+    str.append("'" + privileges[len - 1] + "' on " + path);
+    return str.toString();
+  }
+
+  private SqlResultVO sqlQuery(java.sql.Connection conn, String sql) throws BaseException {
+    PreparedStatement statement = null;
+    ResultSet resultSet = null;
+    try {
+      statement = conn.prepareStatement(sql);
+      resultSet = statement.executeQuery();
+      ResultSetMetaData metaData = resultSet.getMetaData();
+      int columnCount = metaData.getColumnCount();
+      SqlResultVO sqlResultVO = new SqlResultVO();
+      List<String> metaDataList = new ArrayList<>();
+      for (int i = 0; i < columnCount; i++) {
+        metaDataList.add(metaData.getColumnLabel(i + 1));
+      }
+      sqlResultVO.setMetaDataList(metaDataList);
+      List<List<String>> valuelist = new ArrayList<>();
+      while (resultSet.next()) {
+        List<String> strList = new ArrayList<>();
+        for (int i = 0; i < columnCount; i++) {
+          strList.add(resultSet.getString(i + 1));
+        }
+        valuelist.add(strList);
+      }
+      sqlResultVO.setValueList(valuelist);
+      return sqlResultVO;
+    } catch (SQLException e) {
+      throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
+    } finally {
+      if (resultSet != null) {
         try {
-            if (conn != null) {
-                conn.close();
-            }
+          resultSet.close();
         } catch (SQLException e) {
-            throw new BaseException(ErrorCode.CLOSE_DBCONN_FAIL, ErrorCode.CLOSE_DBCONN_FAIL_MSG);
+          throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
         }
-    }
-
-    private String handlerPrivilegeStrToSql(String privilege, String userName, String roleName) {
-        int i = privilege.indexOf(":");
-        String path = privilege.substring(0, i).trim();
-        String[] privileges = privilege.substring(i + 1).trim().split(" ");
-        int len = privileges.length;
-        if (len == 0) {
-            return null;
-        }
-        StringBuilder str = new StringBuilder();
-        if (userName != null) {
-            str.append("grant user " + userName + " privileges ");
-        } else {
-            str.append("grant role " + roleName + " privileges ");
-        }
-        for (int j = 0; i < len - 1; j++) {
-            str.append("'" + privileges[j] + "',");
-        }
-        str.append("'" + privileges[len - 1] + "' on " + path);
-        return str.toString();
-    }
-
-
-    private SqlResultVO sqlQuery(java.sql.Connection conn, String sql) throws BaseException {
-        PreparedStatement statement = null;
-        ResultSet resultSet = null;
+      }
+      if (statement != null) {
         try {
-            statement = conn.prepareStatement(sql);
-            resultSet = statement.executeQuery();
-            ResultSetMetaData metaData = resultSet.getMetaData();
-            int columnCount = metaData.getColumnCount();
-            SqlResultVO sqlResultVO = new SqlResultVO();
-            List<String> metaDataList = new ArrayList<>();
-            for (int i = 0; i < columnCount; i++) {
-                metaDataList.add(metaData.getColumnLabel(i + 1));
-            }
-            sqlResultVO.setMetaDataList(metaDataList);
-            List<List<String>> valuelist = new ArrayList<>();
-            while (resultSet.next()) {
-                List<String> strList = new ArrayList<>();
-                for (int i = 0; i < columnCount; i++) {
-                    strList.add(resultSet.getString(i + 1));
-                }
-                valuelist.add(strList);
-            }
-            sqlResultVO.setValueList(valuelist);
-            return sqlResultVO;
+          statement.close();
         } catch (SQLException e) {
-            throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-        } finally {
-            if (resultSet != null) {
-                try {
-                    resultSet.close();
-                } catch (SQLException e) {
-                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-                }
-            }
-            if (statement != null) {
-                try {
-                    statement.close();
-                } catch (SQLException e) {
-                    throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
-                }
-            }
-            closeConnection(conn);
+          throw new BaseException(ErrorCode.SQL_EP, ErrorCode.SQL_EP_MSG);
         }
+      }
+      closeConnection(conn);
     }
-
-    /**
-     * 防止sql注入对参数进行校验不能有空格
-     *
-     * @param field 拼接sql的字段
-     */
-    private void paramValid(String field) throws BaseException {
-        if (field != null) {
-            if (!field.matches("^[^ ]+$")) {
-                throw new BaseException(ErrorCode.SQL_PARAM_WRONG, ErrorCode.SQL_PARAM_WRONG_MSG);
-            }
-        }
+  }
+
+  /**
+   * 防止sql注入对参数进行校验不能有空格
+   *
+   * @param field 拼接sql的字段
+   */
+  private void paramValid(String field) throws BaseException {
+    if (field != null) {
+      if (!field.matches("^[^ ]+$")) {
+        throw new BaseException(ErrorCode.SQL_PARAM_WRONG, ErrorCode.SQL_PARAM_WRONG_MSG);
+      }
     }
-
-}
\ No newline at end of file
+  }
+}
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
index 52a6f65..4cc0ba2 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/MeasurementServiceImpl.java
@@ -19,8 +19,6 @@
 
 package org.apache.iotdb.admin.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.mapper.MeasurementMapper;
@@ -28,6 +26,9 @@ import org.apache.iotdb.admin.model.dto.DeviceDTO;
 import org.apache.iotdb.admin.model.dto.DeviceInfoDTO;
 import org.apache.iotdb.admin.model.entity.Measurement;
 import org.apache.iotdb.admin.service.MeasurementService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -37,106 +38,113 @@ import java.util.ArrayList;
 import java.util.List;
 
 @Service
-public class MeasurementServiceImpl extends ServiceImpl<MeasurementMapper, Measurement> implements MeasurementService {
+public class MeasurementServiceImpl extends ServiceImpl<MeasurementMapper, Measurement>
+    implements MeasurementService {
 
-    @Autowired
-    private MeasurementMapper measurementMapper;
+  @Autowired private MeasurementMapper measurementMapper;
 
-    private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
+  private static final Logger logger = LoggerFactory.getLogger(IotDBServiceImpl.class);
 
-    @Override
-    public void deleteMeasurementInfo(String host, String groupName) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.like("measurement_name", groupName);
-        try {
-            measurementMapper.delete(queryWrapper);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.DELETE_MEASUREMENT_INFO_FAIL, ErrorCode.DELETE_MEASUREMENT_INFO_FAIL_MSG);
-        }
+  @Override
+  public void deleteMeasurementInfo(String host, String groupName) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.like("measurement_name", groupName);
+    try {
+      measurementMapper.delete(queryWrapper);
+    } catch (Exception e) {
+      throw new BaseException(
+          ErrorCode.DELETE_MEASUREMENT_INFO_FAIL, ErrorCode.DELETE_MEASUREMENT_INFO_FAIL_MSG);
     }
+  }
 
-    @Override
-    public void deleteMeasurementInfoByDeviceName(String host, String deviceName) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.like("measurement_name", deviceName);
-        try {
-            measurementMapper.delete(queryWrapper);
-        } catch (Exception e) {
-            throw new BaseException(ErrorCode.DELETE_MEASUREMENT_INFO_FAIL, ErrorCode.DELETE_MEASUREMENT_INFO_FAIL_MSG);
-        }
+  @Override
+  public void deleteMeasurementInfoByDeviceName(String host, String deviceName)
+      throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.like("measurement_name", deviceName);
+    try {
+      measurementMapper.delete(queryWrapper);
+    } catch (Exception e) {
+      throw new BaseException(
+          ErrorCode.DELETE_MEASUREMENT_INFO_FAIL, ErrorCode.DELETE_MEASUREMENT_INFO_FAIL_MSG);
     }
+  }
 
-    @Override
-    public void setMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException {
-        List<String> descriptions = new ArrayList<>();
-        List<String> measurements = new ArrayList<>();
-        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
-            descriptions.add(deviceDTO.getDescription());
-            measurements.add(deviceDTO.getTimeseries());
-        }
-        for (int i = 0; i < measurements.size(); i++) {
-            Measurement mea = new Measurement();
-            mea.setDescription(descriptions.get(i));
-            mea.setMeasurementName(measurements.get(i));
-            mea.setHost(host);
-            int flag = measurementMapper.insert(mea);
-            if (flag <= 0) {
-                throw new BaseException(ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
-            }
-        }
+  @Override
+  public void setMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException {
+    List<String> descriptions = new ArrayList<>();
+    List<String> measurements = new ArrayList<>();
+    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+      descriptions.add(deviceDTO.getDescription());
+      measurements.add(deviceDTO.getTimeseries());
+    }
+    for (int i = 0; i < measurements.size(); i++) {
+      Measurement mea = new Measurement();
+      mea.setDescription(descriptions.get(i));
+      mea.setMeasurementName(measurements.get(i));
+      mea.setHost(host);
+      int flag = measurementMapper.insert(mea);
+      if (flag <= 0) {
+        throw new BaseException(
+            ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
+      }
     }
+  }
 
-    @Override
-    public String getDescription(String host, String timeseries) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("host", host);
-        queryWrapper.eq("measurement_name", timeseries);
-        Measurement measurement = null;
-        try {
-            measurement = measurementMapper.selectOne(queryWrapper);
-        } catch (Exception e) {
-            logger.error(e.getMessage());
-            throw new BaseException(ErrorCode.GET_MSM_DES_FAIL, ErrorCode.GET_MSM_DES_FAIL_MSG);
-        }
-        if (measurement != null) {
-            return measurement.getDescription();
-        }
-        return null;
+  @Override
+  public String getDescription(String host, String timeseries) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("host", host);
+    queryWrapper.eq("measurement_name", timeseries);
+    Measurement measurement = null;
+    try {
+      measurement = measurementMapper.selectOne(queryWrapper);
+    } catch (Exception e) {
+      logger.error(e.getMessage());
+      throw new BaseException(ErrorCode.GET_MSM_DES_FAIL, ErrorCode.GET_MSM_DES_FAIL_MSG);
     }
+    if (measurement != null) {
+      return measurement.getDescription();
+    }
+    return null;
+  }
 
-    @Override
-    public void updateMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO) throws BaseException {
-        List<String> descriptions = new ArrayList<>();
-        List<String> measurements = new ArrayList<>();
-        for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
-            descriptions.add(deviceDTO.getDescription());
-            measurements.add(deviceDTO.getTimeseries());
-        }
-        for (int i = 0; i < measurements.size(); i++) {
-            QueryWrapper queryWrapper = new QueryWrapper();
-            queryWrapper.eq("host", host);
-            queryWrapper.eq("measurement_name", measurements.get(i));
-            Measurement existMeasurement = measurementMapper.selectOne(queryWrapper);
-            // 未创建的测点
-            if (existMeasurement == null) {
-                Measurement mea = new Measurement();
-                mea.setDescription(descriptions.get(i));
-                mea.setMeasurementName(measurements.get(i));
-                mea.setHost(host);
-                int flag = measurementMapper.insert(mea);
-                if (flag <= 0) {
-                    throw new BaseException(ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
-                }
-                continue;
-            }
-            // 已创建的测点更新描述
-            existMeasurement.setDescription(descriptions.get(i));
-            int flag = measurementMapper.updateById(existMeasurement);
-            if (flag <= 0) {
-                throw new BaseException(ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
-            }
+  @Override
+  public void updateMeasurementsInfo(String host, DeviceInfoDTO deviceInfoDTO)
+      throws BaseException {
+    List<String> descriptions = new ArrayList<>();
+    List<String> measurements = new ArrayList<>();
+    for (DeviceDTO deviceDTO : deviceInfoDTO.getDeviceDTOList()) {
+      descriptions.add(deviceDTO.getDescription());
+      measurements.add(deviceDTO.getTimeseries());
+    }
+    for (int i = 0; i < measurements.size(); i++) {
+      QueryWrapper queryWrapper = new QueryWrapper();
+      queryWrapper.eq("host", host);
+      queryWrapper.eq("measurement_name", measurements.get(i));
+      Measurement existMeasurement = measurementMapper.selectOne(queryWrapper);
+      // 未创建的测点
+      if (existMeasurement == null) {
+        Measurement mea = new Measurement();
+        mea.setDescription(descriptions.get(i));
+        mea.setMeasurementName(measurements.get(i));
+        mea.setHost(host);
+        int flag = measurementMapper.insert(mea);
+        if (flag <= 0) {
+          throw new BaseException(
+              ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
         }
+        continue;
+      }
+      // 已创建的测点更新描述
+      existMeasurement.setDescription(descriptions.get(i));
+      int flag = measurementMapper.updateById(existMeasurement);
+      if (flag <= 0) {
+        throw new BaseException(
+            ErrorCode.SET_MEASUREMENT_INFO_FAIL, ErrorCode.SET_MEASUREMENT_INFO_FAIL_MSG);
+      }
     }
+  }
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
index 76dd6ae..a8b9490 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/QueryServiceImpl.java
@@ -19,14 +19,15 @@
 
 package org.apache.iotdb.admin.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.iotdb.admin.common.exception.BaseException;
 import org.apache.iotdb.admin.common.exception.ErrorCode;
 import org.apache.iotdb.admin.mapper.QueryMapper;
 import org.apache.iotdb.admin.model.entity.Query;
 import org.apache.iotdb.admin.model.vo.QueryVO;
 import org.apache.iotdb.admin.service.QueryService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -37,73 +38,71 @@ import java.util.List;
 @Service
 public class QueryServiceImpl extends ServiceImpl<QueryMapper, Query> implements QueryService {
 
-    @Autowired
-    private QueryMapper queryMapper;
+  @Autowired private QueryMapper queryMapper;
 
-    @Override
-    public void save(Integer serverId, Query inputQuery) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("connection_id", serverId);
-        queryWrapper.eq("query_name", inputQuery.getQueryName());
-        Query query = queryMapper.selectOne(queryWrapper);
-        if (query == null) {
-            Query newQuery = new Query();
-            newQuery.setConnectionId(serverId);
-            newQuery.setQueryName(inputQuery.getQueryName());
-            newQuery.setSqls(inputQuery.getSqls());
-            queryMapper.insert(newQuery);
-            return;
-        }
-        throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
+  @Override
+  public void save(Integer serverId, Query inputQuery) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("connection_id", serverId);
+    queryWrapper.eq("query_name", inputQuery.getQueryName());
+    Query query = queryMapper.selectOne(queryWrapper);
+    if (query == null) {
+      Query newQuery = new Query();
+      newQuery.setConnectionId(serverId);
+      newQuery.setQueryName(inputQuery.getQueryName());
+      newQuery.setSqls(inputQuery.getSqls());
+      queryMapper.insert(newQuery);
+      return;
     }
+    throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
+  }
 
-    @Override
-    public void update(Integer serverId, Query inputQuery) throws BaseException {
-        QueryWrapper queryWrapper = new QueryWrapper();
-        queryWrapper.eq("id", inputQuery.getId());
-        Query query = queryMapper.selectOne(queryWrapper);
-        if (query != null) {
-            query.setQueryName(inputQuery.getQueryName());
-            query.setSqls(inputQuery.getSqls());
-            queryMapper.updateById(query);
-            return;
-        }
-        throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
+  @Override
+  public void update(Integer serverId, Query inputQuery) throws BaseException {
+    QueryWrapper queryWrapper = new QueryWrapper();
+    queryWrapper.eq("id", inputQuery.getId());
+    Query query = queryMapper.selectOne(queryWrapper);
+    if (query != null) {
+      query.setQueryName(inputQuery.getQueryName());
+      query.setSqls(inputQuery.getSqls());
+      queryMapper.updateById(query);
+      return;
     }
+    throw new BaseException(ErrorCode.QUERY_EXIST, ErrorCode.QUERY_EXIST_MSG);
+  }
 
-    @Override
-    public List<QueryVO> getQueryList(Integer serverId) {
-        QueryWrapper<Query> queryWrapper = new QueryWrapper();
-        queryWrapper.eq("connection_id", serverId);
-        List<Query> queries = queryMapper.selectList(queryWrapper);
-        List<QueryVO> queryVOList = new ArrayList<>();
-        for (Query query : queries) {
-            QueryVO queryVO = new QueryVO();
-            BeanUtils.copyProperties(query, queryVO);
-            queryVOList.add(queryVO);
-        }
-        return queryVOList;
+  @Override
+  public List<QueryVO> getQueryList(Integer serverId) {
+    QueryWrapper<Query> queryWrapper = new QueryWrapper();
+    queryWrapper.eq("connection_id", serverId);
+    List<Query> queries = queryMapper.selectList(queryWrapper);
+    List<QueryVO> queryVOList = new ArrayList<>();
+    for (Query query : queries) {
+      QueryVO queryVO = new QueryVO();
+      BeanUtils.copyProperties(query, queryVO);
+      queryVOList.add(queryVO);
     }
+    return queryVOList;
+  }
 
-    @Override
-    public void deleteQuery(Integer queryId) throws BaseException {
-        QueryWrapper<Query> queryWrapper = new QueryWrapper();
-        queryWrapper.eq("id", queryId);
-        int flag = queryMapper.delete(queryWrapper);
-        if (flag <= 0) {
-            throw new BaseException(ErrorCode.QUERY_NOT_EXIST, ErrorCode.QUERY_NOT_EXIST_MSG);
-        }
+  @Override
+  public void deleteQuery(Integer queryId) throws BaseException {
+    QueryWrapper<Query> queryWrapper = new QueryWrapper();
+    queryWrapper.eq("id", queryId);
+    int flag = queryMapper.delete(queryWrapper);
+    if (flag <= 0) {
+      throw new BaseException(ErrorCode.QUERY_NOT_EXIST, ErrorCode.QUERY_NOT_EXIST_MSG);
     }
+  }
 
-    @Override
-    public Query getQuery(Integer queryId) throws BaseException {
-        QueryWrapper<Query> queryWrapper = new QueryWrapper();
-        queryWrapper.eq("id", queryId);
-        Query query = queryMapper.selectOne(queryWrapper);
-        if (query == null) {
-            throw new BaseException(ErrorCode.QUERY_NOT_EXIST, ErrorCode.QUERY_NOT_EXIST_MSG);
-        }
-        return query;
+  @Override
+  public Query getQuery(Integer queryId) throws BaseException {
+    QueryWrapper<Query> queryWrapper = new QueryWrapper();
+    queryWrapper.eq("id", queryId);
+    Query query = queryMapper.selectOne(queryWrapper);
+    if (query == null) {
+      throw new BaseException(ErrorCode.QUERY_NOT_EXIST, ErrorCode.QUERY_NOT_EXIST_MSG);
     }
-
... 1097 lines suppressed ...


[iotdb-web-workbench] 12/34: fix(css)fix run lint-css error

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 42a5b2a85b854c5e870bf17c0f86e9c2902b70d1
Author: huangrui <hu...@163.com>
AuthorDate: Tue Sep 14 17:59:02 2021 +0800

    fix(css)fix run lint-css error
---
 frontend/.eslintrc.js                              |  2 +-
 frontend/.prettierrc.js                            |  2 +-
 frontend/.stylelintrc.js                           | 11 ++-
 frontend/babel.config.js                           |  2 +-
 frontend/public/iconfont.js                        | 19 +++++
 frontend/public/index.html                         | 34 ++++----
 frontend/src/App.vue                               | 36 ++++----
 frontend/src/components/Echarts.vue                | 34 ++++----
 frontend/src/components/FormTable.vue              | 34 ++++----
 frontend/src/components/HelloWorld.vue             | 34 ++++----
 frontend/src/components/StandTable.vue             | 38 ++++-----
 frontend/src/directive/icon.js                     |  2 +-
 frontend/src/directive/index.js                    |  2 +-
 frontend/src/i18n/cn.js                            |  2 +-
 frontend/src/i18n/de.js                            |  2 +-
 frontend/src/i18n/en.js                            |  2 +-
 frontend/src/i18n/index.js                         |  2 +-
 frontend/src/main.js                               |  2 +-
 frontend/src/router/index.js                       |  2 +-
 frontend/src/shims-vue.d.ts                        | 19 +++++
 frontend/src/store/dataBaseM/index.js              |  2 +-
 frontend/src/store/index.js                        | 19 +++++
 frontend/src/store/moduleA/index.js                |  2 +-
 frontend/src/store/storage/index.js                |  2 +-
 frontend/src/styles/element.scss                   | 16 ++--
 frontend/src/styles/reset.scss                     | 17 ++--
 frontend/src/styles/variables.scss                 |  4 +-
 frontend/src/util/api_axios.js                     |  2 +-
 frontend/src/util/axios.js                         |  2 +-
 frontend/src/views/About/index.vue                 | 40 ++++-----
 .../views/DataBaseM/components/dataListTree.vue    | 36 ++++----
 .../src/views/DataBaseM/components/iconTypes.vue   | 34 ++++----
 .../src/views/DataBaseM/hooks/useElementResize.js  |  2 +-
 frontend/src/views/DataBaseM/index.vue             | 34 ++++----
 frontend/src/views/Device/api/index.js             |  2 +-
 frontend/src/views/Device/index.vue                | 38 ++++-----
 frontend/src/views/DeviceMessage/api/index.js      |  2 +-
 .../src/views/DeviceMessage/components/action.vue  | 34 ++++----
 frontend/src/views/DeviceMessage/index.vue         | 40 ++++-----
 frontend/src/views/Home.vue                        | 34 ++++----
 frontend/src/views/Login/index.vue                 | 34 ++++----
 frontend/src/views/Root/hooks/useLangSwitch.js     |  2 +-
 frontend/src/views/Root/index.vue                  | 34 ++++----
 frontend/src/views/Source/components/empty.vue     | 34 ++++----
 frontend/src/views/Source/components/newSource.vue | 35 ++++----
 frontend/src/views/Source/index.vue                | 98 ++++++++++------------
 frontend/src/views/SqlSerch/api/index.js           |  2 +-
 .../src/views/SqlSerch/components/codemirror.vue   | 38 ++++-----
 .../src/views/SqlSerch/components/eltooltip.vue    | 36 ++++----
 .../src/views/SqlSerch/components/formserch.vue    | 36 ++++----
 .../views/SqlSerch/components/formserchData.vue    | 36 ++++----
 .../src/views/SqlSerch/components/sqlDrawer.vue    | 34 ++++----
 frontend/src/views/SqlSerch/hooks/codemirror.js    |  2 +-
 frontend/src/views/SqlSerch/hooks/function.js      |  2 +-
 frontend/src/views/SqlSerch/hooks/keywords.js      |  2 +-
 frontend/src/views/SqlSerch/hooks/selectList.js    |  2 +-
 .../src/views/SqlSerch/hooks/useElementResize.js   |  2 +-
 frontend/src/views/SqlSerch/index.vue              | 46 +++++-----
 frontend/src/views/storage/index.vue               | 36 ++++----
 frontend/src/views/storage/newStorage.vue          | 36 ++++----
 frontend/tests/unit/example.spec.js                | 19 +++++
 frontend/vue.config.js                             |  2 +-
 62 files changed, 641 insertions(+), 570 deletions(-)

diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js
index 6dee65b..7a37c58 100644
--- a/frontend/.eslintrc.js
+++ b/frontend/.eslintrc.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/.prettierrc.js b/frontend/.prettierrc.js
index 39027d1..b5e0015 100644
--- a/frontend/.prettierrc.js
+++ b/frontend/.prettierrc.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/.stylelintrc.js b/frontend/.stylelintrc.js
index fc0b58d..19a618d 100644
--- a/frontend/.stylelintrc.js
+++ b/frontend/.stylelintrc.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -19,5 +19,12 @@
 
 module.exports = {
   extends: ['stylelint-config-standard-scss', 'stylelint-config-prettier'],
-  rules: {},
+  rules: {
+    'selector-pseudo-class-no-unknown': [
+      true,
+      {
+        ignorePseudoClasses: ['deep'],
+      },
+    ],
+  },
 };
diff --git a/frontend/babel.config.js b/frontend/babel.config.js
index 742f9ca..399e97a 100644
--- a/frontend/babel.config.js
+++ b/frontend/babel.config.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/public/iconfont.js b/frontend/public/iconfont.js
index d8c0b2d..b628be0 100644
--- a/frontend/public/iconfont.js
+++ b/frontend/public/iconfont.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 !(function (a) {
   var l,
     h,
diff --git a/frontend/public/index.html b/frontend/public/index.html
index bfb0338..1dc756a 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
 
 <!DOCTYPE html>
 <html lang="">
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index a5ba243..0e6121c 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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>
   <router-view />
@@ -25,7 +25,7 @@
 #app {
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
-  color: #222222;
+  color: #222;
   font-family: PingFang SC, Arial, sans-serif;
   text-align: center;
   height: 100vh;
diff --git a/frontend/src/components/Echarts.vue b/frontend/src/components/Echarts.vue
index f9855b6..9f3b65c 100644
--- a/frontend/src/components/Echarts.vue
+++ b/frontend/src/components/Echarts.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="myChart" class="echartsBox"></div>
diff --git a/frontend/src/components/FormTable.vue b/frontend/src/components/FormTable.vue
index efd8c44..790f4ca 100644
--- a/frontend/src/components/FormTable.vue
+++ b/frontend/src/components/FormTable.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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 :model="formData" :rules="rules" :inline="inline" :label-position="labelPosition" :class="(inline ? 'demo-form-inline' : '', 'form_style')">
diff --git a/frontend/src/components/HelloWorld.vue b/frontend/src/components/HelloWorld.vue
index 197a6f1..23e479a 100644
--- a/frontend/src/components/HelloWorld.vue
+++ b/frontend/src/components/HelloWorld.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="hello">欢迎加入IoTDB前端开发</div>
diff --git a/frontend/src/components/StandTable.vue b/frontend/src/components/StandTable.vue
index 479d3ef..940be68 100644
--- a/frontend/src/components/StandTable.vue
+++ b/frontend/src/components/StandTable.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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>
@@ -220,13 +220,13 @@ export default {
   justify-content: space-between;
   padding: 10px 30px;
   .el-pagination {
-    padding: 4px 5px 0px 5px;
+    padding: 4px 5px 0 5px;
   }
 }
 .export_button {
   height: 30px;
   line-height: 0px;
-  min-height: 0px !important;
+  min-height: 0 !important;
 }
 </style>
 <style lang="scss">
diff --git a/frontend/src/directive/icon.js b/frontend/src/directive/icon.js
index ab5fcd2..1521e2b 100644
--- a/frontend/src/directive/icon.js
+++ b/frontend/src/directive/icon.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/directive/index.js b/frontend/src/directive/index.js
index 4464bed..e6b8bcf 100644
--- a/frontend/src/directive/index.js
+++ b/frontend/src/directive/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/i18n/cn.js b/frontend/src/i18n/cn.js
index 5f39d31..22e1279 100644
--- a/frontend/src/i18n/cn.js
+++ b/frontend/src/i18n/cn.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/i18n/de.js b/frontend/src/i18n/de.js
index 83e16b5..16d7473 100644
--- a/frontend/src/i18n/de.js
+++ b/frontend/src/i18n/de.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/i18n/en.js b/frontend/src/i18n/en.js
index 9ff584f..d557bd9 100644
--- a/frontend/src/i18n/en.js
+++ b/frontend/src/i18n/en.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js
index 6a09651..5a55432 100644
--- a/frontend/src/i18n/index.js
+++ b/frontend/src/i18n/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 4f5b46e..85c2b05 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index afa0ff9..9280615 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/shims-vue.d.ts b/frontend/src/shims-vue.d.ts
index 1c8caa6..69648d8 100644
--- a/frontend/src/shims-vue.d.ts
+++ b/frontend/src/shims-vue.d.ts
@@ -1 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 declare module 'codemirror'
\ No newline at end of file
diff --git a/frontend/src/store/dataBaseM/index.js b/frontend/src/store/dataBaseM/index.js
index fb5b3c2..96940a7 100644
--- a/frontend/src/store/dataBaseM/index.js
+++ b/frontend/src/store/dataBaseM/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js
index 57ae3bf..70697d4 100644
--- a/frontend/src/store/index.js
+++ b/frontend/src/store/index.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { createStore } from 'vuex';
 import moduleA from './moduleA';
 import axios from '@/util/axios.js';
diff --git a/frontend/src/store/moduleA/index.js b/frontend/src/store/moduleA/index.js
index 6c83b0b..0eac2a0 100644
--- a/frontend/src/store/moduleA/index.js
+++ b/frontend/src/store/moduleA/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/store/storage/index.js b/frontend/src/store/storage/index.js
index 316ac3c..cf5ec21 100644
--- a/frontend/src/store/storage/index.js
+++ b/frontend/src/store/storage/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/styles/element.scss b/frontend/src/styles/element.scss
index 893ee8e..44c3229 100644
--- a/frontend/src/styles/element.scss
+++ b/frontend/src/styles/element.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -40,6 +40,11 @@
   }
 }
 .el-tree--highlight-current .el-tree-node {
+  .el-tree-node__content {
+    border-style: solid;
+    border-color: transparent;
+    border-width: 10px 16px;
+  }
   &.is-current {
     & > .el-tree-node__content {
       border-style: solid;
@@ -59,11 +64,6 @@
       }
     }
   }
-  .el-tree-node__content {
-    border-style: solid;
-    border-color: transparent;
-    border-width: 10px 16px;
-  }
 }
 .el-dialog {
   margin: 0 auto;
@@ -104,7 +104,7 @@
   font-size: 12px !important;
 }
 .el-table th {
-  color: #222222 !important;
+  color: #222 !important;
 }
 
 .el-input__icon {
diff --git a/frontend/src/styles/reset.scss b/frontend/src/styles/reset.scss
index 1b34ca9..dd282b0 100644
--- a/frontend/src/styles/reset.scss
+++ b/frontend/src/styles/reset.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -102,7 +102,10 @@ video {
   padding: 0;
   border: 0;
   font-size: 100%;
-  font: inherit;
+  font-weight: inherit;
+  font-variant: inherit;
+  font-style: inherit;
+  font-family: inherit;
   vertical-align: baseline;
 }
 // HTML5 display-role reset for older browsers
@@ -130,10 +133,10 @@ blockquote,
 q {
   quotes: none;
 }
-blockquote:before,
-blockquote:after,
-q:before,
-q:after {
+blockquote::before,
+blockquote::after,
+q::before,
+q::after {
   content: '';
   content: none;
 }
diff --git a/frontend/src/styles/variables.scss b/frontend/src/styles/variables.scss
index 8396746..8a2ad81 100644
--- a/frontend/src/styles/variables.scss
+++ b/frontend/src/styles/variables.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/util/api_axios.js b/frontend/src/util/api_axios.js
index a3c2a57..0110590 100644
--- a/frontend/src/util/api_axios.js
+++ b/frontend/src/util/api_axios.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/util/axios.js b/frontend/src/util/axios.js
index 4d88491..ee22353 100644
--- a/frontend/src/util/axios.js
+++ b/frontend/src/util/axios.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/About/index.vue b/frontend/src/views/About/index.vue
index 44039a2..ff64a97 100644
--- a/frontend/src/views/About/index.vue
+++ b/frontend/src/views/About/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="about">
@@ -159,7 +159,7 @@ export default {
           font-size: 30px;
           font-weight: 500;
           line-height: 38px;
-          color: #222222;
+          color: #222;
           margin-bottom: 30px;
         }
         .line-4,
@@ -167,7 +167,7 @@ export default {
           font-size: 14px;
           font-weight: 400;
           line-height: 22px;
-          color: #222222;
+          color: #222;
           margin-bottom: 20px;
         }
         .line-6 {
@@ -190,7 +190,7 @@ export default {
         .line-7 {
           font-size: 14px;
           line-height: 22px;
-          color: #222222;
+          color: #222;
         }
       }
       .right {
diff --git a/frontend/src/views/DataBaseM/components/dataListTree.vue b/frontend/src/views/DataBaseM/components/dataListTree.vue
index 5d2bced..40769b2 100644
--- a/frontend/src/views/DataBaseM/components/dataListTree.vue
+++ b/frontend/src/views/DataBaseM/components/dataListTree.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="data-list-tree">
@@ -376,7 +376,7 @@ export default {
     }
     .icon-1 {
       top: 2px;
-      right: 0px;
+      right: 0;
       position: absolute;
     }
     .icon-2 {
diff --git a/frontend/src/views/DataBaseM/components/iconTypes.vue b/frontend/src/views/DataBaseM/components/iconTypes.vue
index 3922abd..7fce25a 100644
--- a/frontend/src/views/DataBaseM/components/iconTypes.vue
+++ b/frontend/src/views/DataBaseM/components/iconTypes.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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>
   <span class="iconTypes">
diff --git a/frontend/src/views/DataBaseM/hooks/useElementResize.js b/frontend/src/views/DataBaseM/hooks/useElementResize.js
index 24db48e..389a352 100644
--- a/frontend/src/views/DataBaseM/hooks/useElementResize.js
+++ b/frontend/src/views/DataBaseM/hooks/useElementResize.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/DataBaseM/index.vue b/frontend/src/views/DataBaseM/index.vue
index 8749b2c..9a39edf 100644
--- a/frontend/src/views/DataBaseM/index.vue
+++ b/frontend/src/views/DataBaseM/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="databasem">
diff --git a/frontend/src/views/Device/api/index.js b/frontend/src/views/Device/api/index.js
index c3047d0..c1431a1 100644
--- a/frontend/src/views/Device/api/index.js
+++ b/frontend/src/views/Device/api/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/Device/index.vue b/frontend/src/views/Device/index.vue
index 0a96df4..e6c0ec3 100644
--- a/frontend/src/views/Device/index.vue
+++ b/frontend/src/views/Device/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="padding: 20px">
@@ -428,7 +428,7 @@ export default {
   color: #606266;
 }
 .addbutton {
-  color: #ffffff;
+  color: #fff;
   margin-left: 20px;
   padding: 10px 30px;
   background-color: $theme-color;
@@ -448,7 +448,7 @@ export default {
 }
 .footer {
   position: absolute;
-  bottom: 0px;
+  bottom: 0;
   left: 50%;
   background: #fff;
   height: 52px;
diff --git a/frontend/src/views/DeviceMessage/api/index.js b/frontend/src/views/DeviceMessage/api/index.js
index 063f2b0..44a9aa7 100644
--- a/frontend/src/views/DeviceMessage/api/index.js
+++ b/frontend/src/views/DeviceMessage/api/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/DeviceMessage/components/action.vue b/frontend/src/views/DeviceMessage/components/action.vue
index d31db76..093d89b 100644
--- a/frontend/src/views/DeviceMessage/components/action.vue
+++ b/frontend/src/views/DeviceMessage/components/action.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="id" class="echartsBox"></div>
diff --git a/frontend/src/views/DeviceMessage/index.vue b/frontend/src/views/DeviceMessage/index.vue
index 8ea44c6..eaaf9ae 100644
--- a/frontend/src/views/DeviceMessage/index.vue
+++ b/frontend/src/views/DeviceMessage/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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>
@@ -346,7 +346,7 @@ $cursor: pointer;
 }
 .drawer {
   // width: 84%;
-  bottom: 0px;
+  bottom: 0;
   background: #fff;
   position: absolute;
   z-index: 9;
@@ -388,9 +388,9 @@ $cursor: pointer;
   font-size: 14px;
 }
 .creatButton {
-  padding: 0px 40px;
+  padding: 0 40px;
   height: 35px;
-  min-height: 0px !important;
+  min-height: 0 !important;
   background: #409eff;
   color: #fff;
   margin-top: 3px;
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index 8305887..4c1f608 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="home">
diff --git a/frontend/src/views/Login/index.vue b/frontend/src/views/Login/index.vue
index 174019e..0e7a246 100644
--- a/frontend/src/views/Login/index.vue
+++ b/frontend/src/views/Login/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="login">
diff --git a/frontend/src/views/Root/hooks/useLangSwitch.js b/frontend/src/views/Root/hooks/useLangSwitch.js
index 14dda60..b72338e 100644
--- a/frontend/src/views/Root/hooks/useLangSwitch.js
+++ b/frontend/src/views/Root/hooks/useLangSwitch.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/Root/index.vue b/frontend/src/views/Root/index.vue
index 5becb33..06d4934 100644
--- a/frontend/src/views/Root/index.vue
+++ b/frontend/src/views/Root/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="root">
diff --git a/frontend/src/views/Source/components/empty.vue b/frontend/src/views/Source/components/empty.vue
index cb7a0f2..8ca2ee5 100644
--- a/frontend/src/views/Source/components/empty.vue
+++ b/frontend/src/views/Source/components/empty.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="empty-page">
diff --git a/frontend/src/views/Source/components/newSource.vue b/frontend/src/views/Source/components/newSource.vue
index 1096971..9d65f59 100644
--- a/frontend/src/views/Source/components/newSource.vue
+++ b/frontend/src/views/Source/components/newSource.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="new-source">
@@ -295,7 +295,6 @@ export default {
   .source-form {
     .eg {
       font-size: 12px;
-
       color: rgba(34, 34, 34, 0.4);
     }
   }
diff --git a/frontend/src/views/Source/index.vue b/frontend/src/views/Source/index.vue
index 237fd7c..79bd136 100644
--- a/frontend/src/views/Source/index.vue
+++ b/frontend/src/views/Source/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="source-detail-container">
@@ -1162,30 +1162,30 @@ export default {
   }
   .icon-del {
     position: absolute;
-    top: 0px;
+    top: 0;
     right: 40px;
     color: #d32d2fff;
   }
   .del-user {
     right: 0;
   }
+  .icon {
+    cursor: pointer;
+  }
   .info-box {
     padding: 10px 20px 14px;
     position: relative;
+    font-size: 16px;
+    font-weight: 500;
+    color: #222;
     .icon {
       position: absolute;
       top: 19px;
     }
-
     .icon-edit {
       right: 60px;
       color: $theme-color;
     }
-  }
-  .info-box {
-    font-size: 16px;
-    font-weight: 500;
-    color: #222222;
     .title {
       margin: 10px 0 20px;
     }
@@ -1197,10 +1197,19 @@ export default {
       }
     }
   }
-  .icon {
-    cursor: pointer;
+  .info-head {
+    height: 40px;
+    line-height: 40px;
+    background: #f6f6f8;
+    font-size: 14px;
+    color: #222;
+    padding-left: 20px;
+    .icon {
+      font-size: 16px;
+      cursor: pointer;
+      margin-right: 4px;
+    }
   }
-
   .permission-box {
     .permit-content {
       display: flex;
@@ -1213,15 +1222,10 @@ export default {
           height: 17px;
           font-size: 12px;
           font-weight: 400;
-          line-height: 20px;
-          font-size: 12px;
-          color: #d32d2fff;
           line-height: 16px;
           margin-left: 10px;
-          padding: 3px 8px;
           color: rgba(34, 34, 34, 0.65);
           padding: 0 8px 10px 16px;
-
           button {
             float: right;
             font-size: 12px;
@@ -1262,16 +1266,12 @@ export default {
       .right-part {
         flex: 1;
         position: relative;
-        &:deep(.el-input__suffix .el-input__icon) {
-          line-height: 42px !important;
-        }
         .auth-add-btn {
           position: absolute;
           right: 10px;
           top: 6px;
           z-index: 1000;
         }
-
         .tabs {
           position: relative;
         }
@@ -1289,10 +1289,6 @@ export default {
             display: none;
           }
         }
-        &:deep(.el-checkbox__input.is-disabled + span.el-checkbox__label) {
-          color: #222222;
-          cursor: default;
-        }
         &:deep(.el-checkbox__label) {
           font-size: 12px !important;
           font-weight: 400;
@@ -1300,6 +1296,13 @@ export default {
         &:deep(.el-input .el-input__inner) {
           font-size: 12px !important;
         }
+        &:deep(.el-input__suffix .el-input__icon) {
+          line-height: 42px !important;
+        }
+        &:deep(.el-checkbox__input.is-disabled + span.el-checkbox__label) {
+          color: #222;
+          cursor: default;
+        }
         .el-select {
           width: 100%;
         }
@@ -1313,7 +1316,6 @@ export default {
           font-size: 12px;
           color: #d32d2fff;
           line-height: 16px;
-          margin-left: 10px;
           background: rgba(211, 45, 47, 0.04);
           padding: 3px 8px;
           margin: 16px 18px 16px 14px;
@@ -1330,7 +1332,6 @@ export default {
           }
           .user-name {
             max-width: calc(100% - 50px);
-
             overflow: hidden;
             text-overflow: ellipsis;
             white-space: nowrap;
@@ -1359,19 +1360,6 @@ export default {
       }
     }
   }
-  .info-head {
-    height: 40px;
-    line-height: 40px;
-    background: #f6f6f8;
-    font-size: 14px;
-    color: #222222;
-    padding-left: 20px;
-    .icon {
-      font-size: 16px;
-      cursor: pointer;
-      margin-right: 4px;
-    }
-  }
   .storage-box {
     .group-table {
       width: 100%;
diff --git a/frontend/src/views/SqlSerch/api/index.js b/frontend/src/views/SqlSerch/api/index.js
index 926405f..9ff6fb6 100644
--- a/frontend/src/views/SqlSerch/api/index.js
+++ b/frontend/src/views/SqlSerch/api/index.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/SqlSerch/components/codemirror.vue b/frontend/src/views/SqlSerch/components/codemirror.vue
index a933303..153ac1f 100644
--- a/frontend/src/views/SqlSerch/components/codemirror.vue
+++ b/frontend/src/views/SqlSerch/components/codemirror.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="font_fmiy">
@@ -148,7 +148,7 @@ export default {
 </script>
 <style lang="scss">
 .CodeMirror-linenumber {
-  padding: 5px 3px 5px 0px !important;
+  padding: 5px 3px 5px 0 !important;
 }
 pre.CodeMirror-line {
   padding: 5px 20px !important;
@@ -164,7 +164,7 @@ pre.CodeMirror-line {
 .font_fmiy {
   .CodeMirror-line {
     font-size: 11px !important;
-    font-family: 'PingFang SC, Arial, sans-serif' !important;
+    font-family: PingFang SC, Arial, sans-serif !important;
   }
 }
 </style>
diff --git a/frontend/src/views/SqlSerch/components/eltooltip.vue b/frontend/src/views/SqlSerch/components/eltooltip.vue
index 83e5d2a..462bde7 100644
--- a/frontend/src/views/SqlSerch/components/eltooltip.vue
+++ b/frontend/src/views/SqlSerch/components/eltooltip.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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-tooltip class="item" effect="light" :content="$t(label)" placement="top">
@@ -35,5 +35,3 @@ export default {
   },
 };
 </script>
-
-<style></style>
diff --git a/frontend/src/views/SqlSerch/components/formserch.vue b/frontend/src/views/SqlSerch/components/formserch.vue
index 2ed9972..01a177c 100644
--- a/frontend/src/views/SqlSerch/components/formserch.vue
+++ b/frontend/src/views/SqlSerch/components/formserch.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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>
@@ -82,7 +82,7 @@ export default {
 <style lang="scss" scoped>
 .serch_div {
   font-size: 14px;
-  padding: 20px 20px 0px 20px;
+  padding: 20px 20px 0 20px;
   background: #fff;
   &.maxheight {
     height: 65vh;
diff --git a/frontend/src/views/SqlSerch/components/formserchData.vue b/frontend/src/views/SqlSerch/components/formserchData.vue
index 0cf2597..a5ba50b 100644
--- a/frontend/src/views/SqlSerch/components/formserchData.vue
+++ b/frontend/src/views/SqlSerch/components/formserchData.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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>
@@ -178,7 +178,7 @@ export default {
   font-size: 12px;
   justify-content: space-between;
   border-bottom: 1px solid #ebeef5;
-  padding: 10px 0px;
+  padding: 10px 0;
   cursor: pointer;
   span {
     flex: 1;
diff --git a/frontend/src/views/SqlSerch/components/sqlDrawer.vue b/frontend/src/views/SqlSerch/components/sqlDrawer.vue
index bddb6ac..83b8d6c 100644
--- a/frontend/src/views/SqlSerch/components/sqlDrawer.vue
+++ b/frontend/src/views/SqlSerch/components/sqlDrawer.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="drawer">
diff --git a/frontend/src/views/SqlSerch/hooks/codemirror.js b/frontend/src/views/SqlSerch/hooks/codemirror.js
index 4b88ec5..5619571 100644
--- a/frontend/src/views/SqlSerch/hooks/codemirror.js
+++ b/frontend/src/views/SqlSerch/hooks/codemirror.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/SqlSerch/hooks/function.js b/frontend/src/views/SqlSerch/hooks/function.js
index 02f567f..00a62e7 100644
--- a/frontend/src/views/SqlSerch/hooks/function.js
+++ b/frontend/src/views/SqlSerch/hooks/function.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/SqlSerch/hooks/keywords.js b/frontend/src/views/SqlSerch/hooks/keywords.js
index 369b333..1c3767e 100644
--- a/frontend/src/views/SqlSerch/hooks/keywords.js
+++ b/frontend/src/views/SqlSerch/hooks/keywords.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/SqlSerch/hooks/selectList.js b/frontend/src/views/SqlSerch/hooks/selectList.js
index e293e10..f259bea 100644
--- a/frontend/src/views/SqlSerch/hooks/selectList.js
+++ b/frontend/src/views/SqlSerch/hooks/selectList.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/SqlSerch/hooks/useElementResize.js b/frontend/src/views/SqlSerch/hooks/useElementResize.js
index d308c19..5e4a2bd 100644
--- a/frontend/src/views/SqlSerch/hooks/useElementResize.js
+++ b/frontend/src/views/SqlSerch/hooks/useElementResize.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
diff --git a/frontend/src/views/SqlSerch/index.vue b/frontend/src/views/SqlSerch/index.vue
index 8baba7b..60c8252 100644
--- a/frontend/src/views/SqlSerch/index.vue
+++ b/frontend/src/views/SqlSerch/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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-container>
@@ -423,7 +423,7 @@ export default {
 .footer {
   &.el-footer {
     padding: 0;
-    height: 0px !important;
+    height: 0 !important;
   }
   .divider {
     // width: 1px;
@@ -438,9 +438,9 @@ export default {
   .tabs {
     height: 30px;
     background: #efefef;
-    box-shadow: 0px 0px 2px #d2d2d2;
+    box-shadow: 0 0 2px #d2d2d2;
     .frist_span {
-      color: #cccccc;
+      color: #ccc;
       font-size: 11px;
       margin-left: 20px;
     }
@@ -477,12 +477,12 @@ export default {
   height: 100%;
 }
 .tabs_nav .el-tabs__item {
-  padding: 5px 0px !important;
+  padding: 5px 0 !important;
   width: 100px;
   font-size: 11px !important;
 }
 .tabs_nav_aside .el-tabs__item {
-  padding: 7px 0px !important;
+  padding: 7px 0 !important;
   width: 60px;
   font-size: 11px !important;
 }
@@ -492,7 +492,7 @@ export default {
   overflow: hidden;
   line-height: 15px;
   position: absolute;
-  top: 0px;
+  top: 0;
   &.green {
     color: #00c300;
   }
diff --git a/frontend/src/views/storage/index.vue b/frontend/src/views/storage/index.vue
index da7faec..89a516c 100644
--- a/frontend/src/views/storage/index.vue
+++ b/frontend/src/views/storage/index.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="storage-container">
@@ -297,7 +297,7 @@ export default {
         color: $theme-color;
       }
       .icon:last-child {
-        margin-right: 0px;
+        margin-right: 0;
         color: #d32d2fff;
       }
     }
diff --git a/frontend/src/views/storage/newStorage.vue b/frontend/src/views/storage/newStorage.vue
index 6efdc90..1761039 100644
--- a/frontend/src/views/storage/newStorage.vue
+++ b/frontend/src/views/storage/newStorage.vue
@@ -1,21 +1,21 @@
 <!--
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
--->
+  - Licensed to the Apache Software Foundation (ASF) under one
+  - or more contributor license agreements.  See the NOTICE file
+  - distributed with this work for additional information
+  - regarding copyright ownership.  The ASF licenses this file
+  - to you under the Apache License, Version 2.0 (the
+  - "License"); you may not use this file except in compliance
+  - with the License.  You may obtain a copy of the License at
+  -
+  -   http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing,
+  - software distributed under the License is distributed on an
+  - "AS IS" BASIS, WITHOUT 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="new-storage-container">
@@ -246,7 +246,7 @@ export default {
       position: absolute;
       width: 100px;
       top: 46px;
-      left: 0px;
+      left: 0;
     }
   }
 
diff --git a/frontend/tests/unit/example.spec.js b/frontend/tests/unit/example.spec.js
index a3a7340..8eed9c6 100644
--- a/frontend/tests/unit/example.spec.js
+++ b/frontend/tests/unit/example.spec.js
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import { expect } from 'chai';
 import { shallowMount } from '@vue/test-utils';
 import HelloWorld from '@/components/HelloWorld.vue';
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index f038053..9ba20b1 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -7,7 +7,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an


[iotdb-web-workbench] 24/34: Adding builder for Maven to run properly

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 08ab290d89f6fd426428c38f8c16a0af5e6e7059
Author: Markus Schmidgall <ma...@googlemail.com>
AuthorDate: Tue Sep 21 10:53:25 2021 +0200

    Adding builder for Maven to run properly
---
 backend/Dockerfile | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/backend/Dockerfile b/backend/Dockerfile
index 10b3078..62723a4 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-FROM hub.segma.tech/library/java:8-jre-centos7-apollo
+FROM maven:3.8.2-amazoncorretto-8 as builder
 
 WORKDIR /app
 
@@ -25,6 +25,12 @@ COPY . .
 
 RUN mvn package
 
+
+
+FROM hub.segma.tech/library/java:8-jre-centos7-apollo
+
+COPY --from=builder /app/target/workbench-1.0.0.jar /app/workbench-1.0.0.jar
+
 EXPOSE 8080
 
 ENTRYPOINT ["java", "-jar", "/app/workbench-1.0.0.jar"]


[iotdb-web-workbench] 23/34: add Docker support for frontend and backend with docker compose

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 9c824a38148a99a789fdab663de4d86185b9c1bb
Author: Niklas Merz <ni...@apache.org>
AuthorDate: Tue Sep 21 10:30:59 2021 +0200

    add Docker support for frontend and backend with docker compose
    
    Co-authored-by: Markus Schmidgall <Ma...@googlemail.com>
---
 README.md                                |  3 +++
 backend/Dockerfile                       | 10 ++++++++--
 backend/Dockerfile => docker-compose.yml | 17 ++++++++++++++---
 {backend => frontend}/Dockerfile         | 25 ++++++++++++++++++++++---
 4 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 3a5cfff..6d6c312 100644
--- a/README.md
+++ b/README.md
@@ -25,3 +25,6 @@
 
 This code repo is a web based workbench for [Apache IoTDB](https://iotdb.apache.org)
 
+## Docker
+
+`docker-compose up -d`
\ No newline at end of file
diff --git a/backend/Dockerfile b/backend/Dockerfile
index f6e39cc..10b3078 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -19,6 +19,12 @@
 
 FROM hub.segma.tech/library/java:8-jre-centos7-apollo
 
-COPY target/service-1.0.0.jar /app/app.jar
+WORKDIR /app
 
-ENTRYPOINT ["java", "-jar", "/app/app.jar"]
+COPY . .
+
+RUN mvn package
+
+EXPOSE 8080
+
+ENTRYPOINT ["java", "-jar", "/app/workbench-1.0.0.jar"]
diff --git a/backend/Dockerfile b/docker-compose.yml
similarity index 78%
copy from backend/Dockerfile
copy to docker-compose.yml
index f6e39cc..7100e25 100644
--- a/backend/Dockerfile
+++ b/docker-compose.yml
@@ -17,8 +17,19 @@
 # under the License.
 #
 
-FROM hub.segma.tech/library/java:8-jre-centos7-apollo
+version: "3.8"
 
-COPY target/service-1.0.0.jar /app/app.jar
+services:
+  backend:
+    build: ./backend
+    restart: always
+    ports:
+      - 8081:8080
 
-ENTRYPOINT ["java", "-jar", "/app/app.jar"]
+  frontend:
+    build: ./frontend
+    restart: always
+    ports:
+      - 8080:8080
+    depends_on:
+      - backend
\ No newline at end of file
diff --git a/backend/Dockerfile b/frontend/Dockerfile
similarity index 56%
copy from backend/Dockerfile
copy to frontend/Dockerfile
index f6e39cc..356bc44 100644
--- a/backend/Dockerfile
+++ b/frontend/Dockerfile
@@ -17,8 +17,27 @@
 # under the License.
 #
 
-FROM hub.segma.tech/library/java:8-jre-centos7-apollo
+FROM node:lts-alpine
 
-COPY target/service-1.0.0.jar /app/app.jar
+# From official Vue Documentation https://vuejs.org/v2/cookbook/dockerize-vuejs-app.html
 
-ENTRYPOINT ["java", "-jar", "/app/app.jar"]
+# install simple http server for serving static content
+RUN npm install -g http-server
+
+# make the 'app' folder the current working directory
+WORKDIR /app
+
+# copy both 'package.json' and 'package-lock.json' (if available)
+COPY package*.json ./
+
+# install project dependencies
+RUN npm install
+
+# copy project files and folders to the current working directory (i.e. 'app' folder)
+COPY . .
+
+# build app for production with minification
+RUN npm run build
+
+EXPOSE 8080
+CMD [ "http-server", "dist" ]
\ No newline at end of file


[iotdb-web-workbench] 20/34: Merge pull request #7 from apache/HTHou-patch-1

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 076edae3ac78d9f335402422f84ec34dadc8dcd5
Merge: b1f00b9 5dc612e
Author: Jialin Qiao <qj...@mails.tsinghua.edu.cn>
AuthorDate: Wed Oct 6 16:42:52 2021 +0800

    Merge pull request #7 from apache/HTHou-patch-1

 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[iotdb-web-workbench] 31/34: feat(add the feature of metric)

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit dd8d83de0aaad2290c57d07124751f6a33acc148
Author: 470058871@qq.com <47...@qq.com>
AuthorDate: Wed Jun 1 14:43:48 2022 +0800

    feat(add the feature of metric)
---
 frontend/package-lock.json                         |  16 +-
 frontend/public/index.html                         |   3 +
 frontend/src/App.vue                               |  43 +-
 frontend/src/components/FormTable.vue              |   2 +-
 frontend/src/components/StandTable.vue             |  24 +-
 frontend/src/components/TreeSelect.vue             |  18 +
 .../useElementResize.js.js}                        |   0
 .../variables.scss => hooks/useLanguageWatch.js}   |  53 +-
 frontend/src/i18n/cn.js                            |  95 +++-
 frontend/src/i18n/de.js                            |  95 +++-
 frontend/src/i18n/en.js                            |  93 ++-
 frontend/src/main.js                               |   8 +
 frontend/src/plugins/element_plus.js               |  23 +-
 frontend/src/plugins/event_bus.js                  |  18 +
 frontend/src/plugins/index.js                      |  18 +
 frontend/src/router/index.js                       |  17 +
 frontend/src/store/index.js                        |  18 +
 frontend/src/styles/element.scss                   |  62 +-
 frontend/src/styles/variables.scss                 |   5 +-
 frontend/src/util/axios.js                         |   2 +-
 frontend/src/util/constant.js                      |  18 +
 frontend/src/util/export.js                        |  18 +
 frontend/src/util/setOperation.js                  |  18 +
 frontend/src/views/About/index.vue                 |  15 +-
 frontend/src/views/Control/api/index.js            |  81 +++
 .../src/views/Control/components/indicator.vue     |  77 +++
 .../views/Control/components/indicatorChart.vue    | 115 ++++
 .../src/views/Control/components/indicatorList.vue | 370 ++++++++++++
 .../views/Control/components/indicatorPanel.vue    | 414 ++++++++++++++
 frontend/src/views/Control/components/query.vue    | 536 ++++++++++++++++++
 frontend/src/views/Control/hooks/useInitChart.js   | 625 +++++++++++++++++++++
 frontend/src/views/Control/index.vue               | 420 ++++++++++++++
 .../views/DataBaseM/components/dataListTree.vue    | 154 +++--
 frontend/src/views/DataBaseM/index.vue             |   6 +-
 frontend/src/views/Device/index.vue                |  24 +-
 frontend/src/views/DeviceMessage/index.vue         |  73 ++-
 frontend/src/views/Login/index.vue                 |  19 +-
 frontend/src/views/Root/index.vue                  |  34 +-
 frontend/src/views/Source/components/dataModal.vue |  37 +-
 .../src/views/Source/components/dataModalAll.vue   | 180 +++---
 .../src/views/Source/components/permitDialog.vue   |  22 +-
 .../views/Source/components/role/AuthManage.vue    |  18 +
 .../views/Source/components/role/DataManage.vue    |  18 +
 .../Source/components/role/DialogGrantUser.vue     |  18 +
 .../src/views/Source/components/role/Index.vue     |  18 +
 .../views/Source/components/role/PowerManage.vue   |  18 +
 .../src/views/Source/components/role/RoleInfo.vue  |  23 +-
 .../src/views/Source/components/role/RoleList.vue  |  22 +-
 frontend/src/views/Source/index.vue                |  73 ++-
 frontend/src/views/SqlSerch/index.vue              | 148 +++--
 frontend/src/views/storage/index.vue               |   9 +-
 frontend/src/views/storage/newStorage.vue          |   2 +-
 frontend/vue.config.js                             |  30 +-
 53 files changed, 3932 insertions(+), 334 deletions(-)

diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 2d17ab8..9c43d69 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -2233,7 +2233,7 @@
         },
         "ansi-styles": {
           "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/ansi-styles/-/ansi-styles-4.3.0.tgz",
           "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
           "dev": true,
           "optional": true,
@@ -2243,7 +2243,7 @@
         },
         "chalk": {
           "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/chalk/-/chalk-4.1.2.tgz",
           "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
           "dev": true,
           "optional": true,
@@ -2254,7 +2254,7 @@
         },
         "color-convert": {
           "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/color-convert/-/color-convert-2.0.1.tgz",
           "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dev": true,
           "optional": true,
@@ -2264,21 +2264,21 @@
         },
         "color-name": {
           "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/color-name/-/color-name-1.1.4.tgz",
           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true,
           "optional": true
         },
         "has-flag": {
           "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/has-flag/-/has-flag-4.0.0.tgz",
           "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
           "dev": true,
           "optional": true
         },
         "loader-utils": {
           "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/loader-utils/-/loader-utils-2.0.2.tgz",
           "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
           "dev": true,
           "optional": true,
@@ -2299,7 +2299,7 @@
         },
         "supports-color": {
           "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/supports-color/-/supports-color-7.2.0.tgz",
           "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
           "dev": true,
           "optional": true,
@@ -2309,7 +2309,7 @@
         },
         "vue-loader-v16": {
           "version": "npm:vue-loader@16.8.3",
-          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
+          "resolved": "http://nexus.cisdigital.cn/repository/npm/vue-loader/-/vue-loader-16.8.3.tgz",
           "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
           "dev": true,
           "optional": true,
diff --git a/frontend/public/index.html b/frontend/public/index.html
index 81ad929..22403d5 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -4,6 +4,9 @@
     <meta charset="utf-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
     <meta name="viewport" content="width=device-width,initial-scale=1.0" />
+    <meta http-equiv="pragram" content="no-cache">
+    <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
+    <meta http-equiv="expires" content="0">
     <link rel="icon" href="<%= BASE_URL %>iotdb.ico" />
     <title><%= htmlWebpackPlugin.options.title %></title>
     <script type="text/javascript" src="<%= BASE_URL %>iconfont.js"></script>
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 98d7f19..aa67e8b 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -18,9 +18,50 @@
 -->
 
 <template>
-  <router-view />
+  <el-config-provider :locale="language">
+    <router-view />
+  </el-config-provider>
 </template>
 
+<script>
+import { ref, watch, nextTick } from 'vue';
+import { ElConfigProvider } from 'element-plus';
+import { useI18n } from 'vue-i18n';
+import enLocale from 'element-plus/lib/locale/lang/en';
+import deLocale from 'element-plus/lib/locale/lang/de';
+import zhLocale from 'element-plus/lib/locale/lang/zh-cn';
+
+export default {
+  name: 'App',
+  components: {
+    ElConfigProvider,
+  },
+  setup() {
+    const map = {
+      [enLocale.name]: enLocale,
+      [deLocale.name]: deLocale,
+      [zhLocale.name]: zhLocale,
+    };
+    let { locale } = useI18n();
+    let language = ref(map[locale.value]);
+    function useLanguageWatch(refValue, callback) {
+      let { locale } = useI18n();
+      watch(locale, () => {
+        refValue.value = map[locale.value];
+        nextTick(() => {
+          refValue.value = callback();
+        });
+      });
+    }
+    useLanguageWatch(language, () => {
+      return map[locale.value];
+    });
+    return {
+      language,
+    };
+  },
+};
+</script>
 <style lang="scss">
 #app {
   -webkit-font-smoothing: antialiased;
diff --git a/frontend/src/components/FormTable.vue b/frontend/src/components/FormTable.vue
index 18f2525..8ea8711 100644
--- a/frontend/src/components/FormTable.vue
+++ b/frontend/src/components/FormTable.vue
@@ -23,7 +23,7 @@ IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or imp
         :suffix-icon="item.suffixIcon"
         :prefix-icon="item.prefixIcon"
       >
-        <template #prepend v-if="item.inputHeader">{{ formData[item.inputHeaderText] }}</template>
+        <template #prepend v-if="item.inputHeader">{{ typeof item.inputHeaderText === 'function' ? item.inputHeaderText(formData, item) : formData[item.inputHeaderText] }}</template>
       </el-input>
       <el-select
         v-if="item.type === 'SELECT'"
diff --git a/frontend/src/components/StandTable.vue b/frontend/src/components/StandTable.vue
index d3b77ac..ce4d1b8 100644
--- a/frontend/src/components/StandTable.vue
+++ b/frontend/src/components/StandTable.vue
@@ -30,7 +30,10 @@ IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or imp
             <svg v-if="iconArr.icon[item.icon]" :class="['icon', { 'icon-time': item.icon === 'TIME' }]" @click="sqlClick" aria-hidden="true">
               <use :xlink:href="`#icon-${iconArr.icon[item.icon]}`"></use>
             </svg>
-            <span :style="{ 'margin-left': iconArr.icon[item.icon] ? '5px' : '' }">{{ $t(item.label) }}</span>
+            <span :style="{ 'margin-left': iconArr.icon[item.icon] ? '5px' : '' }" :class="[{ closable: !!item.closable }]" :title="$t(item.label)"
+              >{{ $t(item.label) }}
+              <span class="el-icon-close" v-on:click="item.closable(item)"></span>
+            </span>
             <i :class="item.icon" style="margin-left: 4px" @click="iconEvent(item.iconNum)"></i>
           </template>
           <template #default="scope">
@@ -40,7 +43,7 @@ IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or imp
               :size="item.size"
               :class="{ borderRed: (scope.row.namecopy || !scope.row[item.prop]) && scope.row.border && item.border }"
               :placeholder="$t('device.inputTip') + $t(item.label)"
-              @blur="item.event(scope, scope.row, scope.row[item.prop], $event)"
+              @blur="item.event(scope, scope.row, scope.row[item.prop], $event, item)"
             >
             </el-input>
             <el-input
@@ -382,6 +385,23 @@ export default {
   line-height: 0px;
   min-height: 0 !important;
 }
+.el-icon-close {
+  display: none;
+  position: absolute;
+  top: 5px;
+  cursor: pointer;
+}
+.closable {
+  &:hover > .el-icon-close {
+    display: inline-block;
+    position: absolute;
+    top: 5px;
+    cursor: pointer;
+  }
+}
+:deep(.el-table) th > .cell {
+  white-space: nowrap;
+}
 </style>
 <style lang="scss">
 .borderRed {
diff --git a/frontend/src/components/TreeSelect.vue b/frontend/src/components/TreeSelect.vue
index 0f1df81..7141802 100644
--- a/frontend/src/components/TreeSelect.vue
+++ b/frontend/src/components/TreeSelect.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <template>
   <div class="tree-select-wraper">
     <el-select v-model="mineStatus" :placeholder="placeholder" multiple collapse-tags @change="changeSelect" style="width: 100%">
diff --git a/frontend/src/views/DataBaseM/hooks/useElementResize.js b/frontend/src/hooks/useElementResize.js.js
similarity index 100%
rename from frontend/src/views/DataBaseM/hooks/useElementResize.js
rename to frontend/src/hooks/useElementResize.js.js
diff --git a/frontend/src/styles/variables.scss b/frontend/src/hooks/useLanguageWatch.js
similarity index 72%
copy from frontend/src/styles/variables.scss
copy to frontend/src/hooks/useLanguageWatch.js
index 230d8c9..4b8e8f5 100644
--- a/frontend/src/styles/variables.scss
+++ b/frontend/src/hooks/useLanguageWatch.js
@@ -1,22 +1,31 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-$theme-color: #16c493ff;
-$border-color: #EEF0F5;
-$danger-color: #FB5151;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 { watch, nextTick } from 'vue';
+import { useI18n } from 'vue-i18n';
+function useLanguageWatch(refValue, callback) {
+  let { locale } = useI18n();
+  watch(locale, () => {
+    refValue.value = [];
+    nextTick(() => {
+      refValue.value = callback();
+    });
+  });
+}
+
+export default useLanguageWatch;
diff --git a/frontend/src/i18n/cn.js b/frontend/src/i18n/cn.js
index 6148354..03d2620 100644
--- a/frontend/src/i18n/cn.js
+++ b/frontend/src/i18n/cn.js
@@ -25,9 +25,9 @@ const cn = {
     about: {
       'line-2': '关于我们',
       'line-3': 'IoTDB的可视化管理工具',
-      'line-4': 'IoTDB Admin是IoTDB的可视化管理工具,可对IoTDB的数据进行增删改查、权限控制等,简化IoTDB的使用及学习成本。',
+      'line-4': 'IoTDB WorkBench是IoTDB的可视化管理工具,可对IoTDB的数据进行增删改查、权限控制等,简化IoTDB的使用及学习成本。',
       'line-5': `在我们心中IoTDB是最棒的时序数据库之一,我们将一直不遗余力地推动国产时序数据库IoTDB的应用和发展,为本土开源能力的提高、开源生态的发展,贡献自己的力量,欢迎大家加入IoTDB
-      Admin的开发及维护,期待你的加入:`,
+      WorkBench的开发及维护,期待你的加入:`,
       'line-6-text': '微信扫一扫',
       'line-7': '版本号: V0.12',
       'back-btn': '返回工作页面',
@@ -45,6 +45,18 @@ const cn = {
       tip: '提示',
       deleteSuccess: '删除成功',
       add: '新增',
+      placeHolder: '请输入',
+      selectPlaceholder: '请选择',
+      survival: '存活',
+      death: '死机',
+      port: '端口',
+      refresh: '刷新',
+      startTime: '开始时间',
+      endTime: '结束时间',
+      all: '全部',
+      success: '成功',
+      fail: '失败',
+      query: '查询',
     },
     databasem: {
       newStoreGroup: '新建存储组',
@@ -65,6 +77,7 @@ const cn = {
       nodatasource: '目前还没有数据连接,请',
       newQueryWindow: '查询',
       feedback: '问题反馈',
+      monitorManagement: '监控管理',
     },
     loginPage: {
       account: '账号',
@@ -74,13 +87,13 @@ const cn = {
       forgetPassWord: '忘记密码',
       signIn: '登录',
       forgetPassword: '忘记密码',
-      forgetPasswordTip: '请联系系统管理员',
+      forgetPasswordTip: '请联系系统管理员 WeChat:loveher147',
       accountEmptyTip: '账号不能为空',
       accountContentTip: '用户名必须由字母、数字、下划线组成,不能以数字和下划线开始',
       accountLengthTip: '用户名必须大于等于3个字符,小于等于32字符',
       passwordEmptyTip: '密码不能为空',
       passwordLenghtTip: '密码必须大于等于6位,请检查密码位数',
-      welcomeLogin: '欢迎登录IoTDB数据库管理系统',
+      welcomeLogin: '欢迎登录 IoTDB WorkBench',
       loginErrorTip: '用户名或密码不正确,请重新输入',
     },
 
@@ -415,6 +428,80 @@ const cn = {
       deleteArry: '批量删除',
       importTip: '导入成功',
     },
+    controlPage: {
+      dataList: '数据列表',
+      address: '主机或 IP 地址',
+      storage: '存储组数量',
+      entity: '实体数量',
+      physics: '物理量数量',
+      total: '数据总量',
+      monitor: '监控指标',
+      search: '查询统计',
+      allMode: '全部模式',
+      devMode: '开发者模式',
+      opeMode: '运维者模式',
+      chartBtn: '图表面板',
+      listBtn: '列表面板',
+      jvm: 'JVM指标',
+      cpu: 'CPU指标',
+      memory: '内存指标',
+      store: '存储指标',
+      write: '写入指标',
+      isearch: '查询指标',
+      iName: '指标名称',
+      iType: '指标类型',
+      zxjg: '最新结果发生时间',
+      zxzb: '最新指标结果',
+      sql: 'SQL语句',
+      runTime: '运行时间',
+      exeTime: '执行时间(s)',
+      slowSearch: '慢查询',
+      lastTime: '最近一次运行时间',
+      runCount: '运行次数',
+      querySentence: '查询语句',
+      exeResult: '执行结果',
+      downloadLog: '日志下载',
+      totalUseTime: '总耗时 (ms)',
+      garmmarUseTime: '语法耗时 (ms)',
+      ybyUseTime: '预编译耗时 (ms)',
+      yhbyUseTime: '优化编译耗时 (ms)',
+      exeUseTime: '执行耗时 (ms)',
+
+      JVMThread: 'JVM 指标-线程',
+      JVMRecycle: 'JVM 指标-垃圾回收',
+      JVMMemory: 'JVM 指标-内存',
+      JVMClasses: 'JVM 指标-classes',
+
+      selectMetrics: '请选择指标类型',
+
+      GCEchart: 'GC发生次数及耗时(以分钟计算最近15分钟)',
+      JVMClassEchart: 'JVM卸载/加载的class数量',
+      YGCEchart: 'YGC发生原因及耗时',
+      FGCEchart: 'FGC发生原因及耗时',
+      JAVATypeEchart: 'java各类型线程数',
+      JAVATimeEchart: 'java各时间段线程数',
+      MemoryEchart: '内存使用大小',
+      BufferEchart: '缓冲区使用大小',
+      CPUEchart: 'CPU time占比',
+      IOEchart: '磁盘 IO 吞吐',
+      FileCountEchart: '文件数量统计',
+      FileSizeEchart: '文件大小统计',
+      WriteEchart: '写入成功失败统计及耗时',
+      SearchEchart: '查询成功失败统计',
+      ApiEchart: '接口耗时',
+      ApiQPSEchart: '接口 QPS',
+
+      fgcCount: 'fgc次数',
+      ygcCount: 'ygc次数',
+      fgcTime: 'fgc耗时',
+      ygcTime: 'ygc耗时',
+
+      Ptotal: '共',
+      Pentries: '条',
+      EachPage: '每页',
+      slow: '慢',
+      nodata: '无数据',
+    },
   },
 };
 
diff --git a/frontend/src/i18n/de.js b/frontend/src/i18n/de.js
index f8cde1d..6634c75 100644
--- a/frontend/src/i18n/de.js
+++ b/frontend/src/i18n/de.js
@@ -25,7 +25,7 @@ const de = {
     about: {
       'line-2': 'Über uns',
       'line-3': 'Visual management tool für IoTDB',
-      'line-4': `IoTDB Admin ist eine browserbasiertes Verwaltungsoberfläche für IoTDB, dass alle nötigen Operationen wie das Hinzufügen, Löschen, Verändern oder Abfragen von Werten ermöglicht. Ausserdem wird die Zugriffskontrolle unterstützt. Es vereinfacht die Benutzung von IoTDB deutlich und ist einfach zu verwenden.`,
+      'line-4': `IoTDB WorkBench ist eine browserbasiertes Verwaltungsoberfläche für IoTDB, dass alle nötigen Operationen wie das Hinzufügen, Löschen, Verändern oder Abfragen von Werten ermöglicht. Ausserdem wird die Zugriffskontrolle unterstützt. Es vereinfacht die Benutzung von IoTDB deutlich und ist einfach zu verwenden.`,
       'line-5': `IoTDB ist unserer Meinung nach eine der besten Zeitreihendatenbanken. Wir werden stets versuchen die Entwicklung und Anwendung dieser Zeitreihendatenbank zu unterstützen. Wir heissen jeden herzlich Willkommen mitzumachen. Ihr könnt uns kontaktieren unter:`,
       'line-6-text': 'Wechat scannen',
       'line-7': 'Version: 0.12',
@@ -34,7 +34,7 @@ const de = {
     common: {
       submit: 'Absenden',
       cancel: 'Abbrechen',
-      detail: 'Details',
+      detail: 'Weitere Informationen',
       delete: 'Löschen',
       edit: 'Bearbeiten',
       operation: 'Oeration',
@@ -44,6 +44,18 @@ const de = {
       tip: 'Tips',
       deleteSuccess: 'Löschen erfolgreich',
       add: 'neu hinzugefügt',
+      placeHolder: 'Bitte geben Sie ein',
+      selectPlaceholder: 'Wählen Sie',
+      survival: 'Überleben',
+      death: 'Tot',
+      port: 'Hafen',
+      refresh: 'Auffrischen',
+      startTime: 'Startzeit',
+      endTime: 'Endzeit',
+      all: 'Alle',
+      success: 'Erfolgreich',
+      fail: 'Fehlgeschlagen',
+      query: 'Abfragen',
     },
     databasem: {
       newStoreGroup: 'Neue Speichergruppe ("storage group")',
@@ -64,6 +76,7 @@ const de = {
       newQueryWindow: 'Query',
       nodatasource: 'Aktuell existiert keine Datenquelle',
       feedback: 'Problem Feedback',
+      monitorManagement: 'Überwachungsverwaltung',
     },
     loginPage: {
       account: 'Account',
@@ -73,13 +86,13 @@ const de = {
       forgetPassWord: 'Passwort vergessen',
       signIn: 'Anmelden',
       forgetPassword: 'Passwort vergessen',
-      forgetPasswordTip: 'Bitte kontaktieren Sie Ihren Administrator!',
+      forgetPasswordTip: 'Bitte kontaktieren Sie Ihren Administrator WeChat:loveher147',
       accountEmptyTip: 'Benutzername darf nicht leer sein',
       accountContentTip: 'Der Benutzername muss aus mindestens 3 Buchstaben, Zahlen oder Unterstrichen bestehen und muss mit einem Buchstaben beginnen',
       accountLengthTip: 'Der Benutzername muss zwischen 3 und 32 Zeichen lang sein',
       passwordEmptyTip: 'Passwort darf nicht leer sein',
       passwordLenghtTip: 'Das Passwort muss mindestens 6 Zeichen lang sein',
-      welcomeLogin: 'Willkommen bei der IoTDB Admin Oberfläche',
+      welcomeLogin: 'Willkommen bei IoTDB WorkBench',
       loginErrorTip: 'Benutzername oder Passwort falsch',
     },
 
@@ -405,6 +418,80 @@ const de = {
       deleteArry: 'Stapel löschen',
       importTip: 'Import erfolgreich',
     },
+    controlPage: {
+      dataList: 'Datenliste',
+      address: 'Host Oder IP Adresse',
+      storage: 'Anzahl Der Lagergruppen',
+      entity: 'Anzahl Der Unternehmen',
+      physics: 'Physik',
+      total: 'Gesamtmenge',
+      monitor: 'Überwachungsindikatoren',
+      search: 'Abfragestatistik',
+      allMode: 'Alle Modi',
+      devMode: 'Entwicklermodus',
+      opeMode: 'Modus Betreiber',
+      chartBtn: 'Diagramm Bedienfeld',
+      listBtn: 'Gruppe Liste',
+      jvm: 'JVM Zeiger',
+      cpu: 'CPU Zeiger',
+      memory: 'Speicherindikator',
+      store: 'Massenspeicherindikatoren',
+      write: 'Schreib Zeiger',
+      isearch: 'Abfragekriterien',
+
+      iName: 'Zeigerbezeichnung',
+      iType: 'Zeigertypen',
+      zxjg: 'Zuletzt aufgetretene Ergebnisse',
+      zxzb: 'Aktuelle Kennzahlergebnisse',
+      sql: 'SQL Anweisungen',
+      runTime: 'Laufzeit',
+      exeTime: 'Ausführungszeit(s)',
+      slowSearch: 'Langsames Abfragen',
+      lastTime: 'Letzte Ausführung',
+      runCount: 'Anzahl der Ausführungen',
+      querySentence: 'Abfrageanweisungen',
+      exeResult: 'Ausführungsergebnisse',
+      downloadLog: 'Protokolle Herunterladen',
+      totalUseTime: 'Gesamte verstrichene Zeit (ms)',
+      garmmarUseTime: 'Syntax zeitaufwändig (ms)',
+      ybyUseTime: 'Kompilierungszeit (ms)',
+      yhbyUseTime: 'Kompilierungszeit optimieren (ms)',
+      exeUseTime: 'Ausführungszeit (ms)',
+
+      JVMThread: 'JVM Zeiger–Threads',
+      JVMRecycle: 'JVM Zeiger–Rückgewinnung',
+      JVMMemory: 'JVM Zeiger–Speicher',
+      JVMClasses: 'JVM Zeiger-Classes',
+
+      selectMetrics: 'Wählen Sie Einen Zeigertyp Aus',
+
+      GCEchart: 'GC Vorkommen und Zeitaufwand (in Minuten, fast 15 Minuten)',
+      JVMClassEchart: 'Anzahl der class, die JVM entladen/ geladen',
+      YGCEchart: 'Gründe und Zeitaufwand für YGC Ausfälle',
+      FGCEchart: 'Gründe und Zeitaufwand für FGC Ausfälle',
+      JAVATypeEchart: 'Anzahl der java Threads pro Typ',
+      JAVATimeEchart: 'Threads pro Zeitraum in java',
+      MemoryEchart: 'Speichernutzung',
+      BufferEchart: 'Puffernutzungsgröße',
+      CPUEchart: 'CPU-Zeit in Prozent',
+      IOEchart: 'Festplatten-E/ A-Durchsatz',
+      FileCountEchart: 'Anzahl der Dateien, Statistik',
+      FileSizeEchart: 'Dateigröße Statistiken',
+      WriteEchart: 'Statistiken und Zeitaufwand für erfolgreiche Schreibvorgänge',
+      SearchEchart: 'Statistiken zu erfolgreichen Abfragen',
+      ApiEchart: 'Schnittstelle zeitaufwändig',
+      ApiQPSEchart: 'Schnittstelle QPS',
+
+      fgcCount: 'fgc Anzahl',
+      ygcCount: 'ygc Anzahl',
+      fgcTime: 'fgc Zeit',
+      ygcTime: 'ygc Zeit',
+      Ptotal: 'gesamt',
+      Pentries: 'Einträge',
+      EachPage: 'Jede Seite',
+      slow: 'Langsam',
+      nodata: 'Keine Daten',
+    },
   },
 };
 
diff --git a/frontend/src/i18n/en.js b/frontend/src/i18n/en.js
index e860d25..87113a6 100644
--- a/frontend/src/i18n/en.js
+++ b/frontend/src/i18n/en.js
@@ -25,7 +25,7 @@ const en = {
     about: {
       'line-2': 'About Us',
       'line-3': 'Visual Management Tool Of IoTDB',
-      'line-4': `IoTDB Admin Is A GUI Interface Of IoTDB, Providing All The Adding, Deleting, Altering And Querying Operations. Besides That, Accessing Control Is Also Built. It Extremely Simplifies The Use Of IoTDB And Has Very Little Learning Cost. `,
+      'line-4': `IoTDB WorkBench Is A GUI Interface Of IoTDB, Providing All The Adding, Deleting, Altering And Querying Operations. Besides That, Accessing Control Is Also Built. It Extremely Simplifies The Use Of IoTDB And Has Very Little Learning Cost. `,
       'line-5': `IoTDB Is One Of The Best Time Series Database In Our Opinion. We Will Always Try Our Best To Advance The Development And Application Of Time Series Database, Making Contribution To Rise Of Native Open Source Ability And Ecosystem Development.Welcome Everyone Of You To Join Us, Waiting For You! Contact Us:`,
       'line-6-text': 'Scan Wechat',
       'line-7': 'Version: 0.12',
@@ -44,6 +44,18 @@ const en = {
       tip: 'Tips',
       deleteSuccess: 'Delete Success',
       add: 'Add',
+      placeHolder: 'Please Input',
+      selectPlaceholder: 'Please Select',
+      survival: 'Survival',
+      death: 'Die',
+      port: 'Prot',
+      refresh: 'Refresh',
+      startTime: 'Start Time',
+      endTime: 'End Time',
+      all: 'All',
+      success: 'Success',
+      fail: 'Fail',
+      query: 'Query',
     },
     databasem: {
       newStoreGroup: 'New Storage Group',
@@ -64,6 +76,7 @@ const en = {
       newQueryWindow: 'Query',
       nodatasource: 'It Is Has No Data Source At Present, Please',
       feedback: 'Problem Feedback',
+      monitorManagement: 'Monitor Management',
     },
     loginPage: {
       account: 'Account',
@@ -73,13 +86,13 @@ const en = {
       forgetPassWord: 'Forget Password',
       signIn: 'Sign In',
       forgetPassword: 'Forget Password',
-      forgetPasswordTip: 'Please Contact System Administrator',
+      forgetPasswordTip: 'Please Contact System Administrator WeChat:loveher147',
       accountEmptyTip: 'Account Can Not Be Empty',
       accountContentTip: 'The User Name Must Be Made Up Of Letters, Numbers, Underscores, And Cannot Start With Numbers And Underscores',
       accountLengthTip: 'The User Name Must Be Greater Than Or Equal To 3 Characters And Less Than Or Equal To 32 Characters',
       passwordEmptyTip: 'Password Can Not Be Empty',
       passwordLenghtTip: 'Password Must Be Greater Than Or Equal To 6 Digits. Please Check The Number Of Digits',
-      welcomeLogin: 'Welcome To IoTDB Admin',
+      welcomeLogin: 'Welcome To IoTDB WorkBench',
       loginErrorTip: 'Incorrect User Name Or Password, Please Re-enter',
     },
 
@@ -412,6 +425,80 @@ const en = {
       deleteArry: 'Batch Delete',
       importTip: 'Import Succeeded',
     },
+    controlPage: {
+      dataList: 'DataList',
+      address: 'Host Or IP Address',
+      storage: 'Number Of Storage Groups',
+      entity: 'Number Of Entities',
+      physics: 'Physics',
+      total: 'Total Quantity',
+      monitor: 'Monitoring Indicators',
+      search: 'Query Statistics',
+      allMode: 'All Modes',
+      devMode: 'Developer Mode',
+      opeMode: 'Operator Mode',
+      chartBtn: 'Chart Panel',
+      listBtn: 'List Panel',
+      jvm: 'JVM Metric',
+      cpu: 'CPU Metric',
+      memory: 'Memory Metric',
+      store: 'Store Metric',
+      write: 'Write Metric',
+      isearch: 'Search Metric',
+
+      iName: 'Metric Name',
+      iType: 'Metric Type',
+      zxjg: 'Latest Result Occurrence Time',
+      zxzb: 'Latest Metric results',
+      sql: 'SQL Statement',
+      runTime: 'Run Time',
+      exeTime: 'Execution Time(s)',
+      slowSearch: 'Slow Search',
+      lastTime: 'The Last Running Time',
+      runCount: 'Running Times',
+      querySentence: 'Query Statement',
+      exeResult: 'Execution Result',
+      downloadLog: 'Download Log',
+      totalUseTime: 'Total Time Consumption (ms)',
+      garmmarUseTime: 'Grammar Time Consuming (ms)',
+      ybyUseTime: 'Pre Compilation Time Consuming (ms)',
+      yhbyUseTime: 'Optimizing Compilation Time (ms)',
+      exeUseTime: 'Execution Time Consuming (ms)',
+
+      JVMThread: 'JVM Metrics-threads',
+      JVMRecycle: 'JVM Metrics-Recycling',
+      JVMMemory: 'JVM Metrics-Memory',
+      JVMClasses: 'JVM Metrics-Classes',
+
+      selectMetrics: 'Please Select Indicators',
+
+      GCEchart: 'Number Of GC Occurrences And Elapsed Time (Calculated In The Last 15 Minutes)',
+      JVMClassEchart: 'Number Of Classes Unloaded/Loaded By The JVM',
+      YGCEchart: 'Causes And Time Consuming Of YGC',
+      FGCEchart: 'Causes And Time Consuming Of FGC',
+      JAVATypeEchart: 'Number Of Java Threads Of Each Type',
+      JAVATimeEchart: 'Number Of Java Threads In Each Time Period',
+      MemoryEchart: 'Memory Usage Size',
+      BufferEchart: 'Cache Usage Size',
+      CPUEchart: 'CPU Time Proportion',
+      IOEchart: 'Disk I/O Throughput',
+      FileCountEchart: 'File Quantity Statistics',
+      FileSizeEchart: 'File Size Statistics',
+      WriteEchart: 'Write Success And Failure Statistics And Time Consumption',
+      SearchEchart: 'Query Success And Failure Statistics',
+      ApiEchart: 'Interface Time Consuming',
+      ApiQPSEchart: 'Interface QPS',
+
+      fgcCount: 'fgc Times',
+      ygcCount: 'ygc Times',
+      fgcTime: 'fgc Time Consuming',
+      ygcTime: 'ygc Time Consuming',
+      Ptotal: 'Total',
+      Pentries: 'Entries',
+      EachPage: 'EachPage',
+      slow: 'Slow',
+      nodata: 'No Data',
+    },
   },
 };
 
diff --git a/frontend/src/main.js b/frontend/src/main.js
index 3b786c0..ff0fe2a 100644
--- a/frontend/src/main.js
+++ b/frontend/src/main.js
@@ -28,6 +28,14 @@ import i18nFile from '@/i18n/index.js';
 import '@/styles/reset.scss';
 import '@/styles/element.scss';
 
+const VUE_APP_VERSION = require('../package.json').version;
+const vers = window.localStorage.getItem('appVersion');
+if (VUE_APP_VERSION != vers) {
+  localStorage.clear();
+  window.localStorage.setItem('appVersion', VUE_APP_VERSION);
+  location.reload();
+}
+
 i18n(i18nFile.global.t);
 const app = createApp(App);
 directive(app);
diff --git a/frontend/src/plugins/element_plus.js b/frontend/src/plugins/element_plus.js
index d2aee8a..6787d5e 100644
--- a/frontend/src/plugins/element_plus.js
+++ b/frontend/src/plugins/element_plus.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 import 'element-plus/packages/theme-chalk/src/base.scss';
 import {
   ElLoading,
@@ -79,13 +97,15 @@ import {
   // ElMessageBox,
   // ElMessage,
   ElPopconfirm,
-  // ElNotification
+  // ElNotification,
+  ElConfigProvider,
 } from 'element-plus';
 
 export default {
   install: (Vue) => {
     Vue.use(ElPopconfirm);
     Vue.use(ElPagination);
+    Vue.use(ElLoading);
     // Vue.use(ElDrawer);
     Vue.use(ElDialog);
     // Vue.use(ElAutocomplete);
@@ -160,6 +180,7 @@ export default {
     // Vue.use(ElBacktop);
     // Vue.use(ElPageHeader);
     // Vue.use(ElCascaderPanel);
+    Vue.use(ElConfigProvider);
     // Vue.prototype.$message = ElMessage;
     // Vue.prototype.$alert = ElMessageBox.alert;
     // Vue.prototype.$confirm = ElMessageBox.confirm;
diff --git a/frontend/src/plugins/event_bus.js b/frontend/src/plugins/event_bus.js
index fe6fa93..b9f7666 100644
--- a/frontend/src/plugins/event_bus.js
+++ b/frontend/src/plugins/event_bus.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 import mitt from 'mitt';
 const emitter = mitt();
 
diff --git a/frontend/src/plugins/index.js b/frontend/src/plugins/index.js
index ca386bb..d3b7ea3 100644
--- a/frontend/src/plugins/index.js
+++ b/frontend/src/plugins/index.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 import element_plus from './element_plus';
 import event_bus from './event_bus';
 
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index e62712c..0c8ce56 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -98,6 +98,23 @@ const routes = [
           },
         ],
       },
+      {
+        path: '/control',
+        name: 'Control',
+        component: () => import(/* webpackChunkName: "control" */ '../views/Control'),
+        children: [
+          {
+            path: 'indicator/:panel/:id/:mode',
+            name: 'Indicator',
+            component: () => import(/* webpackChunkName: "Indicator" */ '../views/Control/components/indicator.vue'),
+          },
+          {
+            path: 'query/:id',
+            name: 'Query',
+            component: () => import(/* webpackChunkName: "Query" */ '../views/Control/components/query.vue'),
+          },
+        ],
+      },
     ],
   },
   {
diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js
index 44c3088..d016290 100644
--- a/frontend/src/store/index.js
+++ b/frontend/src/store/index.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 import { createStore } from 'vuex';
 import moduleA from './moduleA';
 import axios from '@/util/axios.js';
diff --git a/frontend/src/styles/element.scss b/frontend/src/styles/element.scss
index 21e67e1..fc556db 100644
--- a/frontend/src/styles/element.scss
+++ b/frontend/src/styles/element.scss
@@ -20,6 +20,11 @@
 .el-button--primary {
   background-color: $theme-color !important;
   border-color: $theme-color !important;
+  &:hover.el-button,&:focus.el-button {
+    background:$theme-color !important;
+    border-color:$theme-color !important;
+    color: #fff;
+  }
   span {
     color: #fff;
   }
@@ -39,11 +44,17 @@
 }
 
 .el-button--default {
-  &:hover {
+  &:hover,
+  &:focus {
     color: #15c294 !important;
     background-color: transparent !important;
     border-color: #15c294 !important;
   }
+  //   &:focus {
+  //     color: none !important;
+  //     background-color: transparent !important;
+  //     border-color: #15c294 !important;
+  //   }
 }
 .button-delete:hover {
   background: #fff !important;
@@ -243,3 +254,52 @@
     }
   }
 }
+
+.el-select .el-input__inner:focus,
+.el-select .el-input.is-focus .el-input__inner {
+  border-color: $theme-bj-color !important;
+}
+.el-select-dropdown__item {
+  font-size: 12px;
+}
+.el-select-dropdown__item.selected {
+  color: $theme-bj-color;
+}
+// iotdb-table-style
+.iotdb-table {
+  width: 100%;
+  th {
+    font-weight: 500;
+    color: #808ba3 !important;
+    background-color: #f9fafc;
+  }
+  td {
+    font-weight: 400;
+    color: #333;
+  }
+  &.el-table--border th,
+  &.el-table--border td {
+    border-right: none;
+  }
+  &.el-table--border {
+    border-radius: 4px;
+  }
+  .el-table__row:last-child td {
+    border-bottom: none;
+  }
+  .el-table__body {
+    tr.hover-row > td {
+      background-color: #edf8f5 !important;
+    }
+  }
+  .el-table__fixed-right {
+    border-left: 1px solid #e7eaf2;
+    border-right: 1px solid #e7eaf2;
+  }
+}
+input.el-input__inner:hover {
+  border: 1px solid $theme-bj-color !important;
+}
+.el-loading-spinner .path {
+    stroke: $theme-color;
+}
diff --git a/frontend/src/styles/variables.scss b/frontend/src/styles/variables.scss
index 230d8c9..071bcae 100644
--- a/frontend/src/styles/variables.scss
+++ b/frontend/src/styles/variables.scss
@@ -18,5 +18,6 @@
  */
 
 $theme-color: #16c493ff;
-$border-color: #EEF0F5;
-$danger-color: #FB5151;
+$border-color: #eef0f5;
+$danger-color: #fb5151;
+$theme-bj-color: #15c294;
diff --git a/frontend/src/util/axios.js b/frontend/src/util/axios.js
index 369d688..193f878 100644
--- a/frontend/src/util/axios.js
+++ b/frontend/src/util/axios.js
@@ -22,7 +22,7 @@ import { ElMessage } from 'element-plus';
 import router from '../router';
 
 const instance = axios.create({});
-const headerUrls = ['/api/login', '/api/downloadFile/template'];
+const headerUrls = ['/api/login', '/api/downloadFile/template', '/api/downloadQueryLogFile'];
 const exportUrl = '/exportData';
 const downUrl = '/downloadFile';
 instance.defaults.withCredentials = true;
diff --git a/frontend/src/util/constant.js b/frontend/src/util/constant.js
index 8b396e3..75c390b 100644
--- a/frontend/src/util/constant.js
+++ b/frontend/src/util/constant.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 export const DataGranularityMap = {
   dataLink: 'dataLink', // 数据连接
   group: 'groupPath', // 存储组
diff --git a/frontend/src/util/export.js b/frontend/src/util/export.js
index add3d56..d0b86c5 100644
--- a/frontend/src/util/export.js
+++ b/frontend/src/util/export.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 export function handleExport(data, name) {
   const blob = new Blob([data]);
   const downloadElement = document.createElement('a');
diff --git a/frontend/src/util/setOperation.js b/frontend/src/util/setOperation.js
index 9b4e804..1a3fb48 100644
--- a/frontend/src/util/setOperation.js
+++ b/frontend/src/util/setOperation.js
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 function array_remove_repeat(a) {
   // 去重
   var r = [];
diff --git a/frontend/src/views/About/index.vue b/frontend/src/views/About/index.vue
index 5f1f3d5..89204e6 100644
--- a/frontend/src/views/About/index.vue
+++ b/frontend/src/views/About/index.vue
@@ -26,12 +26,17 @@
       </div>
       <div class="lang-btn">
         <el-dropdown @command="handleLangCommand">
-          <span class="el-dropdown-link"> {{ [$t('rootPage.chinalang'), $t('rootPage.englishlang'), $t('rootPage.deutsch')][langIndex] }}<i class="el-icon-arrow-down el-icon--right"></i> </span>
+          <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="1.2em" height="1.2em" data-v-dd9c9540="">
+            <path
+              fill="currentColor"
+              d="m18.5 10l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16.5 10h2zM10 2v2h6v2h-1.968a18.222 18.222 0 0 1-3.62 6.301a14.864 14.864 0 0 0 2.336 1.707l-.751 1.878A17.015 17.015 0 0 1 9 13.725a16.676 16.676 0 0 1-6.201 3.548l-.536-1.929a14.7 14.7 0 0 0 5.327-3.042A18.078 18.078 0 0 1 4.767 8h2.24A16.032 16.032 0 0 0 9 10.877a16.165 16.165 0 0 0 2.91-4.876L2 6V4h6V2h2zm7.5 10.885L16.253 16h2.492L17.5 12.885z"
+            ></path>
+          </svg>
           <template #dropdown>
             <el-dropdown-menu>
-              <el-dropdown-item :disabled="langIndex === 0" command="0">{{ $t('rootPage.chinalang') }}</el-dropdown-item>
-              <el-dropdown-item :disabled="langIndex === 1" command="1">{{ $t('rootPage.englishlang') }}</el-dropdown-item>
-              <el-dropdown-item :disabled="langIndex === 2" command="2">{{ $t('rootPage.deutsch') }}</el-dropdown-item>
+              <el-dropdown-item :disabled="langIndex === 0" command="0">中文</el-dropdown-item>
+              <el-dropdown-item :disabled="langIndex === 1" command="1">English</el-dropdown-item>
+              <el-dropdown-item :disabled="langIndex === 2" command="2">Deutsch</el-dropdown-item>
             </el-dropdown-menu>
           </template>
         </el-dropdown>
@@ -107,7 +112,7 @@ export default {
     right: 0;
     .lang-btn {
       position: absolute;
-      right: 20px;
+      right: 40px;
       top: 50%;
       transform: translate(0, -50%);
     }
diff --git a/frontend/src/views/Control/api/index.js b/frontend/src/views/Control/api/index.js
new file mode 100644
index 0000000..4736ed3
--- /dev/null
+++ b/frontend/src/views/Control/api/index.js
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import axios from '@/util/axios.js';
+
+//Get Monitor List
+export function getMonitorList() {
+  return axios.get(`/servers/metrics/connection`);
+}
+
+//Get Single Monitor info
+export function getMonitorInfo(serverId) {
+  return axios.get(`/servers/${serverId}/metrics/datacount`);
+}
+
+//Get Metrics tableData
+export function getMetricsData(serverId, metricsType) {
+  return axios.get(`/servers/${serverId}/metrics/list/${metricsType}`);
+}
+//Get Search Metrics tableData
+export function getSearchMetricsData(serverId, mode) {
+  return axios.get(`/servers/${serverId}/metrics/list/query/${mode}`);
+}
+
+// Query Statistics API
+
+//Get  Classify List
+export function getClassifyList(serverId) {
+  return axios.get(`/servers/${serverId}/metrics/QueryClassification`);
+}
+
+//Get Current Classify Data
+export function getClassifyData(serverId, classifyId, query) {
+  return axios.get(`/servers/${serverId}/metrics/${classifyId}/selectcount`, {
+    params: query,
+  });
+}
+
+// Chart API
+
+//Get Chart data
+export function getChartData(serverId, metricsId) {
+  return axios.get(`/servers/${serverId}/metrics/diagram/?metricId=${metricsId}`);
+}
+
+// Get log
+export function getDownloadQueryLogFile(params) {
+  return axios.get(`/downloadQueryLogFile`, {
+    params,
+    responseType: 'blob',
+  });
+}
+
+//Get the measurement  list under the entity
+// export function getList(deviceData, data) {
+//     return axios.get(`/servers/${deviceData.connectionid}/storageGroups/${deviceData.storagegroupid}/devices/${deviceData.name}/info`, { params: data });
+// }
+// //Delete measurement
+// export function deleteData(deviceData, timeseriesName) {
+//     return axios.delete(`/servers/${deviceData.connectionid}/storageGroups/${deviceData.storagegroupid}/devices/${deviceData.name}/timeseries/${timeseriesName}`);
+// }
+// //Add / edit entity information
+// export function deviceAddEdite(serverId, groupName, data) {
+//     return axios.post(`/servers/${serverId}/storageGroups/${groupName}/devices`, data);
+// }
diff --git a/frontend/src/views/Control/components/indicator.vue b/frontend/src/views/Control/components/indicator.vue
new file mode 100644
index 0000000..9146dcd
--- /dev/null
+++ b/frontend/src/views/Control/components/indicator.vue
@@ -0,0 +1,77 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
+<template>
+  <div class="main-center">
+    <div class="main-center-container">
+      <indicator-list v-if="panelMode === 'list'" :currentData="currentData" />
+
+      <indicator-panel v-else :currentData="currentData" />
+    </div>
+  </div>
+</template>
+
+<script>
+import { computed, ref, watch } from 'vue';
+import IndicatorPanel from './indicatorPanel';
+import IndicatorList from './indicatorList';
+import { useRoute } from 'vue-router';
+export default {
+  name: 'Indicator',
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  components: {
+    IndicatorPanel,
+    IndicatorList,
+  },
+  setup(props) {
+    let route = useRoute();
+    let panelMode = ref('list');
+    let currentData = computed(() => props.data);
+    watch(
+      () => route.params.panel,
+      (newValue) => {
+        panelMode.value = newValue;
+      },
+      {
+        immediate: true,
+      }
+    );
+    return {
+      panelMode,
+      currentData,
+    };
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.main-center {
+  min-height: calc(100% - 243px);
+  padding: 20px;
+  background: #f9fbfc;
+  &-container {
+    background: #fff;
+    border-radius: 4px;
+  }
+}
+</style>
diff --git a/frontend/src/views/Control/components/indicatorChart.vue b/frontend/src/views/Control/components/indicatorChart.vue
new file mode 100644
index 0000000..4a34a71
--- /dev/null
+++ b/frontend/src/views/Control/components/indicatorChart.vue
@@ -0,0 +1,115 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<template>
+  <div class="chart-box">
+    <div class="chart-title">{{ title }}</div>
+    <div class="chart-con">
+      <div class="chart" ref="chartDom"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts';
+import { onMounted, ref, watch } from 'vue';
+export default {
+  name: 'IndicatorChart',
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  setup(props) {
+    let chartDom = ref();
+    let Chart;
+    onMounted(() => {
+      let option;
+      console.log(chartDom.value);
+      Chart = echarts.init(chartDom.value);
+      option = {
+        tooltip: {
+          trigger: 'axis',
+          textStyle: {
+            align: 'left',
+          },
+        },
+        grid: {
+          top: '20px',
+          left: '20px',
+          right: '20px',
+          bottom: '44px',
+          containLabel: true,
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+        },
+        yAxis: {
+          type: 'value',
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          splitLine: { show: false },
+        },
+      };
+      Object.assign(option, props.data.options);
+      option && Chart.setOption(option);
+    });
+    watch(
+      () => props.data,
+      (newValue) => {
+        if (newValue) {
+          Chart.setOption(newValue.options);
+        }
+      },
+      {
+        deep: true,
+      }
+    );
+
+    return {
+      title: props.data.title,
+      chartDom,
+    };
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.chart-box {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+.chart-con {
+  flex: 1;
+}
+.chart {
+  height: 100%;
+}
+.chart-title {
+  padding: 20px 0 0 20px;
+  font-size: 14px;
+  font-weight: 500;
+  color: #333;
+  line-height: 22px;
+  text-align: left;
+}
+</style>
diff --git a/frontend/src/views/Control/components/indicatorList.vue b/frontend/src/views/Control/components/indicatorList.vue
new file mode 100644
index 0000000..a002ed1
--- /dev/null
+++ b/frontend/src/views/Control/components/indicatorList.vue
@@ -0,0 +1,370 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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>
+    <div class="main-center-container-head">
+      <div class="select-box">
+        <el-select v-model="mode" class="m-2" placeholder="Select">
+          <el-option v-for="item in modeOptions" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+      <div v-if="showBtnGroup">
+        <el-button type="primary" @click="handleChangePanel">{{ $t('controlPage.chartBtn') }}</el-button>
+        <el-button @click="handleRefres">{{ $t('common.refresh') }}</el-button>
+      </div>
+    </div>
+    <div class="main-center-container-center">
+      <div class="main-center-container-center-left">
+        <el-tabs v-model="activeName" tab-position="left" style="height: 200px" class="demo-tabs">
+          <el-tab-pane v-for="(item, index) in tabPanelOptions" :key="index" v-bind="item"></el-tab-pane>
+        </el-tabs>
+      </div>
+      <div class="main-center-container-center-right">
+        <div class="search-way" v-if="activeName === 'search'">
+          <span :class="{ active: searchWay === '0' }" @click="handleSearchWay('0')">Top Sql</span>
+          <span :class="{ active: searchWay === '1' }" @click="handleSearchWay('1')">{{ $t('controlPage.slowSearch') }}</span>
+        </div>
+        <el-table class="iotdb-table" border style="width: 100%" :empty-text="$t('controlPage.nodata')" :data="tableData">
+          <template v-for="(item, index) in tableColumn">
+            <el-table-column v-if="!item.fixed" :key="'col' + index" v-bind="item"></el-table-column>
+
+            <el-table-column v-else :key="'colfixed' + index" fixed="right" :label="$t('common.operation')" width="140">
+              <template #default="scoped">
+                <el-button v-if="scoped.row.detailAvailable !== 0" type="text" size="small" @click="handleDeatil(scoped)">{{ $t('common.detail') }}</el-button>
+              </template>
+            </el-table-column>
+          </template>
+        </el-table>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { computed, onMounted, ref, watch } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import { getMetricsData, getSearchMetricsData } from '../api';
+
+export default {
+  name: 'IndicatorList',
+  props: {
+    currentData: {
+      type: Object,
+    },
+  },
+  setup(props) {
+    let { t } = useI18n();
+    let router = useRouter();
+    let route = useRoute();
+    let mode = ref(route.query.mode || '0');
+    let activeName = ref(route.params.mode || 'JVM');
+    let searchWay = ref('0');
+    let tableData = ref();
+
+    let modeOptions = computed(() => [
+      {
+        label: t('controlPage.allMode'),
+        value: '0',
+      },
+      {
+        label: t('controlPage.devMode'),
+        value: '1',
+      },
+      {
+        label: t('controlPage.opeMode'),
+        value: '2',
+      },
+    ]);
+    let tableColumn = computed(() => {
+      const temp = [
+        {
+          prop: 'name',
+          label: t('controlPage.iName'),
+          minWidth: '160px',
+        },
+        {
+          prop: 'latestScratchTime',
+          label: t('controlPage.zxjg'),
+          minWidth: '160px',
+        },
+        {
+          prop: 'latestResult',
+          label: t('controlPage.zxzb'),
+          minWidth: '160px',
+        },
+        { fixed: true },
+      ];
+      if (activeName.value === 'JVM') {
+        let formatCol = [...temp];
+        formatCol.splice(1, 0, {
+          prop: 'metricType',
+          label: t('controlPage.iType'),
+          minWidth: '120px',
+        });
+        return formatCol;
+      } else if (activeName.value === 'search') {
+        return [
+          {
+            prop: 'sqlstatement',
+            minWidth: '372',
+            label: t('controlPage.sql'),
+          },
+          {
+            prop: 'runningTime',
+            minWidth: '160',
+            label: t('controlPage.runTime'),
+          },
+          {
+            prop: 'executionTime',
+            sortable: true,
+            minWidth: '140',
+            label: t('controlPage.exeTime'),
+          },
+        ];
+      } else if (activeName.value === 'memory') {
+        let formatCol = [...temp];
+        formatCol.pop();
+        return formatCol;
+      }
+      return temp;
+    });
+    let targetType = computed(() => [
+      {
+        label: t('controlPage.jvm'),
+        name: 'JVM',
+        type: '1',
+      },
+      {
+        label: t('controlPage.cpu'),
+        name: 'CPU',
+        type: '2',
+      },
+      {
+        label: t('controlPage.memory'),
+        name: 'memory',
+        type: '2',
+      },
+      {
+        label: t('controlPage.store'),
+        name: 'store',
+        type: '2',
+      },
+      {
+        label: t('controlPage.write'),
+        name: 'write',
+        type: '0',
+      },
+      {
+        label: t('controlPage.isearch'),
+        name: 'search',
+        type: '0',
+      },
+    ]);
+    let tabPanelOptions = computed(() => {
+      let filterData = targetType.value.filter(
+        (item) => {
+          if (mode.value === '0' || item.type === mode.value || item.type === '0') {
+            return true;
+          }
+        },
+        { immediate: true }
+      );
+      checkedTarget(filterData, activeName.value);
+      return filterData;
+    });
+    let showBtnGroup = computed(() => props.currentData?.status);
+    watch(
+      activeName,
+      (newVlaue) => {
+        initTableData(props.currentData, newVlaue);
+        router.push({
+          path: `/control/indicator/${route.params?.panel || 'list'}/${props.currentData.serverId}/${newVlaue}`,
+          query: { ...route.query },
+        });
+      },
+      {
+        immediate: true,
+      }
+    );
+    watch(
+      () => route.params.mode,
+      (newValue) => {
+        newValue && (activeName.value = newValue);
+      },
+      {
+        immediate: true,
+      }
+    );
+    watch(
+      () => route.query.mode,
+      (newValue) => {
+        newValue && (mode.value = newValue);
+      }
+    );
+    watch(
+      () => props.currentData,
+      (newValue) => {
+        initTableData(newValue, activeName.value);
+      }
+    );
+    onMounted(() => {});
+    function handleRefres() {
+      initTableData(props.currentData, activeName.value);
+    }
+    function handleSearchWay(way) {
+      if (searchWay.value !== way) {
+        searchWay.value = way;
+        initTableData(props.currentData, activeName.value);
+      }
+    }
+    function checkedTarget(data, type) {
+      for (let i = 0, len = data.length; i < len; i++) {
+        if (data[i].name === type) {
+          return false;
+        }
+      }
+      data[0]?.name && (activeName.value = data[0].name);
+    }
+    function handleDeatil({ row }) {
+      let modeMap = {
+        JVM: {
+          1: 0,
+          2: 1,
+          3: 2,
+          4: 3,
+        },
+      };
+      let type = activeName.value === 'JVM' ? modeMap[activeName.value][row.detailAvailable] : undefined;
+      router.push({ path: `/control/indicator/chart/${route.params.id}/${route.params.mode}`, query: { mode: mode.value, type } });
+    }
+    function initTableData(data, mode) {
+      const modeMap = {
+        JVM: 0,
+        CPU: 1,
+        memory: 2,
+        store: 3,
+        write: 4,
+      };
+      if (!data?.status) {
+        tableData.value = [];
+        return;
+      }
+      // 数据列表信息
+      if (mode !== 'search') {
+        getMetricsData(data.serverId, modeMap[mode]).then((res) => {
+          tableData.value = res.data.listInfo;
+        });
+      } else {
+        getSearchMetricsData(data.serverId, searchWay.value).then((res) => {
+          tableData.value = res.data.queryMetricsVOs;
+        });
+      }
+    }
+    function handleChangePanel() {
+      router.push({ path: `/control/indicator/chart/${route.params.id}/${route.params.mode}`, query: { mode: mode.value } });
+    }
+    return {
+      mode,
+      activeName,
+      modeOptions,
+      tabPanelOptions,
+      tableData,
+      tableColumn,
+      searchWay,
+      showBtnGroup,
+
+      handleDeatil,
+      handleSearchWay,
+      handleChangePanel,
+      handleRefres,
+    };
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.main-center-container {
+  background: #fff;
+  border-radius: 4px;
+  &-head {
+    display: flex;
+    justify-content: space-between;
+    padding: 12px 20px;
+    border: 1px solid #eaecf0;
+  }
+  &-center {
+    padding: 20px 20px 20px 0;
+    display: flex;
+    border: 1px solid #eaecf0;
+    border-top: none;
+    &-left {
+      margin-right: 15px;
+      &:deep .el-tabs__active-bar {
+        min-width: 0 !important;
+      }
+      &:deep .el-tabs__item {
+        height: 24px;
+        line-height: 24px;
+        color: #8e97aa;
+        font-size: 12px !important;
+        &.is-active {
+          color: $theme-bj-color !important;
+        }
+      }
+      &:deep .el-tabs__nav-scroll,
+      &:deep .el-tabs__nav-wrap {
+        height: auto;
+      }
+    }
+    &-right {
+      width: 100px;
+      flex: 1;
+      .search-way {
+        display: flex;
+        font-size: 12px;
+        margin-bottom: 20px;
+        span {
+          padding: 8px 21px;
+          color: #8e97aa;
+          border: 1px solid #eaecf0;
+          cursor: pointer;
+          &.active {
+            background: #edf8f5;
+            color: #15c294;
+          }
+        }
+        span:first-child {
+          border-radius: 4px 0 0 4px;
+          border-right: none;
+        }
+        span:last-child {
+          border-radius: 0 4px 4px 0;
+        }
+      }
+    }
+  }
+  .select-box {
+    width: 120px;
+    &:deep .el-input__inner {
+      font-size: 12px;
+    }
+  }
+}
+</style>
diff --git a/frontend/src/views/Control/components/indicatorPanel.vue b/frontend/src/views/Control/components/indicatorPanel.vue
new file mode 100644
index 0000000..3d78d6b
--- /dev/null
+++ b/frontend/src/views/Control/components/indicatorPanel.vue
@@ -0,0 +1,414 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="indicator-list">
+    <div class="list-head">
+      <div class="select-box">
+        <el-select v-model="modeValue" class="selece-box-mode" placeholder="请选择">
+          <el-option v-for="item in modeOptions" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+        <el-select v-model="typeValue" class="selece-box-type" :placeholder="$t('controlPage.selectMetrics')">
+          <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+      <div>
+        <el-button type="primary" @click="handleChangePanel">{{ $t('controlPage.listBtn') }}</el-button>
+        <el-button @click="handleRefresh">{{ $t('common.refresh') }}</el-button>
+      </div>
+    </div>
+    <div class="list-center">
+      <div v-for="(item, index) in chartList" v-show="isShowChart(item.name)" :key="'chart' + index" :class="['chart-item', 'chart-' + item.size]" :tag="item.name">
+        <IndicatorChart v-if="ChartObject[item.name]" :data="ChartObject[item.name]" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import IndicatorChart from './indicatorChart';
+import useInitChart from '../hooks/useInitChart';
+import { useI18n } from 'vue-i18n';
+export default {
+  name: 'IndicatorPanel',
+  props: {
+    currentData: {
+      type: Object,
+    },
+  },
+  components: {
+    IndicatorChart,
+  },
+  setup(props) {
+    const typeMap = {
+      CPU: '4',
+      memory: '5',
+      store: '6',
+      write: '7',
+      search: '8',
+    };
+    const chartList = [
+      {
+        name: 'GCEchart',
+        size: '50',
+      },
+
+      {
+        name: 'JVMClassEchart',
+        size: '50',
+      },
+      {
+        name: 'YGCEchart',
+        size: '100',
+      },
+      {
+        name: 'FGCEchart',
+        size: '100',
+      },
+      {
+        name: 'JAVATypeEchart',
+        size: '50',
+      },
+      {
+        name: 'JAVATimeEchart',
+        size: '50',
+      },
+      {
+        name: 'MemoryEchart',
+        size: '50',
+      },
+      {
+        name: 'BufferEchart',
+        size: '50',
+      },
+      {
+        name: 'CPUEchart',
+        size: '50',
+      },
+      {
+        name: 'IOEchart',
+        size: '50',
+      },
+      {
+        name: 'FileCountEchart',
+        size: '50',
+      },
+      {
+        name: 'FileSizeEchart',
+        size: '50',
+      },
+      {
+        name: 'WriteEchart',
+        size: '50',
+      },
+      {
+        name: 'SearchEchart',
+        size: '50',
+      },
+      {
+        name: 'ApiEchart',
+        size: '50',
+      },
+      {
+        name: 'ApiQPSEchart',
+        size: '50',
+      },
+    ];
+    let DOMQueue = [];
+    let { t, locale } = useI18n();
+    let router = useRouter();
+    let route = useRoute();
+    let modeValue = ref(route.query?.mode || '0');
+    const typeDefault = route.params.mode === 'JVM' ? route.query.type : typeMap[route.params.mode];
+    let typeValue = ref(typeDefault);
+    let ChartObject = reactive({
+      GCEchart: null,
+      JVMClassEchart: null,
+      YGCEchart: null,
+      FGCEchart: null,
+      JAVATypeEchart: null,
+      JAVATimeEchart: null,
+      MemoryEchart: null,
+      BufferEchart: null,
+      CPUEchart: null,
+      IOEchart: null,
+      FileCountEchart: null,
+      FileSizeEchart: null,
+      WriteEchart: null,
+      SearchEchart: null,
+      ApiEchart: null,
+      ApiQPSEchart: null,
+    });
+
+    let modeOptions = computed(() => [
+      {
+        label: t('controlPage.allMode'),
+        value: '0',
+      },
+      {
+        label: t('controlPage.devMode'),
+        value: '1',
+      },
+      {
+        label: t('controlPage.opeMode'),
+        value: '2',
+      },
+    ]);
+    let typeOptions = computed(() => {
+      const JVM = [
+        {
+          label: t('controlPage.JVMThread'),
+          value: '0',
+        },
+        {
+          label: t('controlPage.JVMRecycle'),
+          value: '1',
+        },
+        {
+          label: t('controlPage.JVMMemory'),
+          value: '2',
+        },
+        {
+          label: t('controlPage.JVMClasses'),
+          value: '3',
+        },
+      ];
+      const CPU = {
+        label: t('controlPage.cpu'),
+        value: '4',
+      };
+      const memory = {
+        label: t('controlPage.memory'),
+        value: '5',
+      };
+      const store = {
+        label: t('controlPage.store'),
+        value: '6',
+      };
+      const write = {
+        label: t('controlPage.write'),
+        value: '7',
+      };
+      const search = {
+        label: t('controlPage.isearch'),
+        value: '8',
+      };
+      if (modeValue.value === '0') {
+        return [...JVM, CPU, memory, store, write, search];
+      } else if (modeValue.value === '1') {
+        return [...JVM, write, search];
+      } else {
+        return [CPU, memory, store, write, search];
+      }
+    });
+    watch(modeValue, () => {
+      typeValue.value = '';
+      nextTick(() => {
+        lazyChart();
+      });
+    });
+    watch(typeValue, () => {
+      nextTick(() => {
+        lazyChart();
+      });
+    });
+    watch(
+      () => props.currentData,
+      () => {
+        handleRefresh();
+      }
+    );
+    watch(locale, async () => {
+      handleRefresh('0');
+    });
+    onMounted(() => {
+      DOMQueue = [...document.querySelectorAll('.chart-item')];
+      let main = document.querySelectorAll('main')[0];
+      main?.addEventListener('scroll', lazyChart);
+      main && lazyChart();
+    });
+    onUnmounted(() => {
+      document.querySelectorAll('main')[0]?.removeEventListener('scroll', lazyChart);
+    });
+
+    function isShowChart(name) {
+      // JVM-线程
+      let JVMThreadMap = {
+        JAVATypeEchart: true,
+        JAVATimeEchart: true,
+      };
+      // JVM-垃圾回收
+      let JVMRecycleMap = {
+        YGCEchart: true,
+        FGCEchart: true,
+        GCEchart: true,
+      };
+      // JVM-内存
+      let JVMMemoryMap = {
+        BufferEchart: true,
+      };
+      // JVM-classes
+      let JVMclassesMap = {
+        JVMClassEchart: true,
+      };
+      //   CPU
+      let CPUMap = {
+        CPUEchart: true,
+      };
+      //   内存
+      let MemoryMap = {
+        MemoryEchart: true,
+      };
+      //   存储
+      let StoreMap = {
+        IOEchart: true,
+        FileCountEchart: true,
+        FileSizeEchart: true,
+      };
+      //   写入
+      let WriteMap = {
+        WriteEchart: true,
+      };
+      //   查询
+      let SearchMap = {
+        SearchEchart: true,
+        ApiEchart: true,
+        ApiQPSEchart: true,
+      };
+      let devChartMap = {
+        ...JVMThreadMap,
+        ...JVMRecycleMap,
+        ...JVMMemoryMap,
+        ...JVMclassesMap,
+      };
+      let operatorMap = {
+        ...CPUMap,
+        ...MemoryMap,
+        ...StoreMap,
+        ...WriteMap,
+        ...SearchMap,
+      };
+      let type2Map = {
+        0: JVMThreadMap,
+        1: JVMRecycleMap,
+        2: JVMMemoryMap,
+        3: JVMclassesMap,
+        4: CPUMap,
+        5: MemoryMap,
+        6: StoreMap,
+        7: WriteMap,
+        8: SearchMap,
+      };
+      if (!typeValue.value) {
+        if (modeValue.value === '0') {
+          return true;
+        } else if (modeValue.value === '1') {
+          return devChartMap[name];
+        } else if (modeValue.value === '2') {
+          return operatorMap[name];
+        }
+      } else {
+        return type2Map[typeValue.value][name];
+      }
+    }
+    function handleChangePanel() {
+      router.push({ path: `/control/indicator/list/${route.params.id}/${route.params.mode}`, query: { mode: modeValue.value } });
+    }
+    function lazyChart(refreshData) {
+      DOMQueue.filter((item) => {
+        let tag = item.getAttribute('tag');
+        if (window.getComputedStyle(item).display !== 'none' && !ChartObject[tag]) {
+          return true;
+        }
+      }).map((item) => {
+        let rect = item.getBoundingClientRect();
+        if (rect.top + 100 <= (window.innerHeight || document.documentElement.clientHeight) && rect.top > -300) {
+          initMatchChart(item.getAttribute('tag'), refreshData);
+        }
+      });
+    }
+    async function initMatchChart(name, refreshData) {
+      let result = await useInitChart(props.currentData.serverId, name, refreshData);
+      ChartObject[name] = result;
+    }
+    function handleRefresh(refreshData) {
+      let arr = [...document.querySelectorAll('.chart-item')];
+      arr.map((item) => {
+        if (window.getComputedStyle(item).display !== 'none') {
+          let chartName = item.getAttribute('tag');
+          ChartObject[chartName] = null;
+        }
+      });
+      lazyChart(refreshData);
+    }
+    return {
+      modeValue,
+      chartList,
+      typeValue,
+      modeOptions,
+      typeOptions,
+      ChartObject,
+
+      handleChangePanel,
+      handleRefresh,
+      isShowChart,
+    };
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.indicator-list {
+  .list-head {
+    display: flex;
+    justify-content: space-between;
+    padding: 12px 20px;
+    border: 1px solid #eaecf0;
+  }
+  .list-center {
+    display: grid;
+    border-left: 1px solid #eaecf0;
+    grid-template-columns: repeat(2, 50%);
+  }
+  .chart-item {
+    box-sizing: border-box;
+    height: 304px;
+    border-right: 1px solid #eaecf0;
+    border-bottom: 1px solid #eaecf0;
+  }
+  .chart-50 {
+    width: 100%;
+  }
+  .chart-100 {
+    grid-column: 1/3;
+    width: 100%;
+  }
+}
+.selece-box-mode {
+  width: 120px;
+}
+.selece-box-type {
+  margin-left: 20px;
+  width: 200px;
+}
+:deep .el-select .el-input__inner {
+  font-size: 12px;
+}
+</style>
diff --git a/frontend/src/views/Control/components/query.vue b/frontend/src/views/Control/components/query.vue
new file mode 100644
index 0000000..07115fe
--- /dev/null
+++ b/frontend/src/views/Control/components/query.vue
@@ -0,0 +1,536 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="query-main">
+    <div class="query-main-container">
+      <div class="container-left">
+        <el-tabs v-model="activeType" tab-position="left" style="height: 200px" class="demo-tabs">
+          <el-tab-pane v-for="(item, index) in tabPanelOptions" :key="index" :label="item.name" :name="item.id + ''">
+            <template #label>
+              <div class="tab-label" :key="index">{{ item.name }}</div>
+            </template>
+          </el-tab-pane>
+        </el-tabs>
+      </div>
+      <div v-if="tabPanelOptions?.length" class="container-right">
+        <div class="container-right-tip">
+          <div>
+            {{ $t('controlPage.lastTime') }} <span>{{ formatInfo(latestTime) }}</span>
+          </div>
+          <div>
+            {{ $t('controlPage.runCount') }}<span>{{ formatInfo(runTotal) }}</span>
+          </div>
+        </div>
+        <div class="container-right-operate">
+          <div class="operate-item">
+            <span class="input-label">{{ $t('controlPage.querySentence') }}:</span>
+            <div class="input-box">
+              <el-input v-model="searchValue" class="w-50 m-2" :placeholder="$t('common.placeHolder')" />
+            </div>
+          </div>
+          <div class="operate-item">
+            <span class="input-label">{{ $t('controlPage.runTime') }}:</span>
+            <div class="date-box">
+              <el-config-provider :locale="langLocale">
+                <!-- <el-color-picker :model-value="''" style="vertical-align: middle" /> -->
+                <el-date-picker v-model="runTime" size="mini" type="datetimerange" :start-placeholder="$t('common.startTime')" :end-placeholder="$t('common.endTime')" />
+              </el-config-provider>
+            </div>
+          </div>
+          <div class="operate-item">
+            <span class="input-label">{{ $t('controlPage.exeResult') }}:</span>
+            <div class="select-box">
+              <el-select v-model="runResult" class="m-2" :placeholder="$t('common.selectPlaceholder')">
+                <el-option v-for="item in resultOptions" :key="item.value" :label="item.label" :value="item.value" />
+              </el-select>
+            </div>
+          </div>
+          <el-button class="operate-btn" @click="handleSearch">{{ $t('common.query') }}</el-button>
+        </div>
+        <div class="container-right-table">
+          <el-table class="iotdb-table" border style="width: 100%" :empty-text="$t('controlPage.nodata')" :data="tableData">
+            <template v-for="(item, index) in tableColumn">
+              <el-table-column v-if="item.isSlowQuery" :key="'col' + index" label="" align="right" :width="item.maxWidth">
+                <template #default="scope">
+                  <div class="slow-query" v-if="scope.row.isSlowQuery">{{ $t('controlPage.slow') }}</div>
+                </template>
+              </el-table-column>
+              <el-table-column v-else-if="item.type === 'result'" :key="'col' + index" :label="$t('controlPage.exeResult')">
+                <template #default="scope">
+                  <div :class="+scope.row.executionResult === 1 ? 'success' : 'error'">{{ +scope.row.executionResult === 1 ? $t('common.success') : $t('common.fail') }}{{ scope.row.result }}</div>
+                </template>
+              </el-table-column>
+              <el-table-column v-else-if="item.fixed === 'right'" :key="'colright' + index" v-bind="item">
+                <template #default="scoped">
+                  <el-button type="text" size="small" @click="handleDownload(scoped)">{{ $t('controlPage.downloadLog') }}</el-button>
+                </template>
+              </el-table-column>
+              <el-table-column v-else :key="'col' + index" show-overflow-tooltip v-bind="item"></el-table-column>
+            </template>
+          </el-table>
+          <!-- :page-sizes="[10, 25,50, 100]" -->
+          <div class="table-pagination">
+            <el-pagination layout="slot" v-model:currentPage="currentPage" v-model:page-size="pageSize" :total="totalCount">
+              <span class="pagination-title">{{ $t('controlPage.Ptotal') }} {{ totalCount }} {{ $t('controlPage.Pentries') }}</span>
+            </el-pagination>
+            <el-pagination layout="slot" v-model:currentPage="currentPage" v-model:page-size="pageSize" :total="totalCount">
+              {{ $t('controlPage.EachPage')
+              }}<el-select class="pageSelectContainer" v-model="pageSize" @change="handlePageSize" placeholder="请选择">
+                <el-option v-for="item in optionsPage" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select
+              >{{ $t('controlPage.Pentries') }}
+            </el-pagination>
+            <el-pagination
+              v-model:currentPage="currentPage"
+              v-model:page-size="pageSize"
+              layout="prev, pager, next"
+              :total="totalCount"
+              @size-change="handlePageSize"
+              @current-change="handleCurrentPage"
+            >
+            </el-pagination>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+// @ is an alias to /src
+import { get } from 'lodash';
+import { ElMessage } from 'element-plus';
+import { handleExport } from '@/util/export';
+import { computed, nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue';
+import { useI18n } from 'vue-i18n';
+import zhCn from 'element-plus/lib/locale/lang/zh-cn';
+import en from 'element-plus/lib/locale/lang/en';
+import de from 'element-plus/lib/locale/lang/de';
+// import { ElTabs } from 'element-plus';
+// import { useRouter } from 'vue-router';
+import { getClassifyList, getClassifyData, getDownloadQueryLogFile } from '../api';
+
+export default {
+  name: 'Query',
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  setup(props) {
+    let { t, locale } = useI18n();
+    let tabPanelOptions = ref();
+    let tableColumnType = ref(true);
+    let activeType = ref();
+    let runTime = ref('');
+    let tableData = ref();
+    let runResult = ref('0');
+    let searchValue = ref('');
+    let pageReactive = reactive({
+      latestTime: '',
+      runTotal: '',
+    });
+    let tablePage = reactive({
+      totalCount: 0,
+      currentPage: 1,
+      pageSize: 10,
+    });
+    let resultOptions = computed(() => [
+      {
+        label: t('common.all'),
+        value: '0',
+      },
+      {
+        label: t('common.success'),
+        value: '1',
+      },
+      {
+        label: t('common.fail'),
+        value: '2',
+      },
+    ]);
+    let langLocale = computed(() => {
+      let lang = locale.value;
+      let langMap = {
+        'zh-cn': zhCn,
+        en,
+        de,
+      };
+      return langMap[lang];
+    });
+    let tableColumn = computed(() => {
+      let flagWidthMap = {
+        'zh-cn': 40,
+        en: 50,
+        de: 80,
+      };
+      let ctrlWidthMap = {
+        'zh-cn': 100,
+        en: 120,
+        de: 170,
+      };
+      let temp = [
+        {
+          label: '',
+          maxWidth: flagWidthMap[locale.value] || 80,
+          isSlowQuery: true,
+        },
+        {
+          label: t('controlPage.runTime'),
+          prop: 'runningTime',
+          width: '170px',
+        },
+        {
+          label: t('controlPage.querySentence'),
+          prop: 'statement',
+          minWidth: '180px',
+        },
+        {
+          label: t('controlPage.totalUseTime'),
+          prop: 'totalTime',
+          minWidth: '100px',
+        },
+      ];
+      if (tableColumnType.value === 0) {
+        temp = [
+          ...temp,
+          {
+            label: t('controlPage.garmmarUseTime'),
+            prop: 'analysisTime',
+            minWidth: '120px',
+          },
+          {
+            label: t('controlPage.ybyUseTime'),
+            prop: 'precompiledTime',
+            minWidth: '120px',
+          },
+          {
+            label: t('controlPage.yhbyUseTime'),
+            prop: 'optimizedTime',
+            minWidth: '120px',
+          },
+          {
+            label: t('controlPage.exeUseTime'),
+            prop: 'executionTime',
+            minWidth: '150px',
+          },
+        ];
+      }
+      temp.push({
+        label: t('controlPage.exeResult'),
+        prop: 'executionResult',
+        minWidth: '80px',
+        type: 'result',
+      });
+      temp.push({
+        fixed: 'right',
+        label: t('common.operation'),
+        width: ctrlWidthMap[locale.value],
+      });
+      return temp;
+    });
+    let optionsPage = computed(() => [
+      {
+        label: '10',
+        value: 10,
+      },
+      {
+        label: '20',
+        value: 20,
+      },
+      {
+        label: '30',
+        value: 30,
+      },
+    ]);
+    watch(activeType, (newValue) => {
+      if (newValue) {
+        QueryDataInit();
+        tabPanelOptions.value.every((item) => {
+          if (item.id + '' === newValue + '') {
+            tableColumnType.value = item.flag;
+            return false;
+          }
+          return true;
+        });
+        getCurrentQueryData(props.data.serverId, newValue);
+      }
+    });
+    watch(
+      () => props.data,
+      (newValue) => {
+        if (newValue.status) {
+          getClassifyList(newValue.serverId).then((res) => {
+            tabPanelOptions.value = res.data.classificationList;
+            activeType.value = '';
+            nextTick(() => {
+              activeType.value = tabPanelOptions.value[0]?.id + '';
+            });
+          });
+        } else {
+          tabPanelOptions.value = [];
+          tableData.value = [];
+          QueryDataInit();
+        }
+      },
+      { immediate: true }
+    );
+
+    onMounted(() => {});
+    function QueryDataInit() {
+      pageReactive.latestTime = '';
+      pageReactive.runTotal = '';
+      tablePage.currentPage = 1;
+      tablePage.pageSize = 10;
+      tablePage.totalCount = 0;
+      runResult.value = '0';
+      searchValue.value = '';
+    }
+    function handlePageSize() {
+      tablePage.currentPage = 1;
+      getCurrentQueryData();
+    }
+    function handleCurrentPage() {
+      getCurrentQueryData();
+    }
+    function getCurrentQueryData() {
+      if (!props.data.status) {
+        tableData.value = [];
+        return;
+      }
+      let query = {
+        pageSize: tablePage.pageSize,
+        pageNum: tablePage.currentPage,
+        filterString: searchValue.value || undefined,
+        startTime: (runTime.value && runTime.value[0]?.getTime()) || undefined,
+        endTime: (runTime.value && runTime.value[1]?.getTime()) || undefined,
+        executionResult: runResult.value,
+      };
+
+      getClassifyData(props.data.serverId, activeType.value, query).then((res) => {
+        let { data } = res;
+        pageReactive.latestTime = data.latestRunningTime;
+        pageReactive.runTotal = data.totalCount;
+        tableData.value = data.filteredQueryDataStrVOSList;
+        tablePage.totalCount = data.totalCount;
+      });
+    }
+    function handleSearch() {
+      getCurrentQueryData();
+    }
+    async function handleDownload({ row }) {
+      const res = await getDownloadQueryLogFile({
+        SQLStatement: row.statement,
+        timeStamp: new Date(row.runningTime).valueOf(),
+      });
+      let filename = get(res, 'headers.content-disposition');
+      filename = filename ? decodeURI(filename.replace(/.*(?=filename=)filename=/, '')) : '';
+      if (get(res, 'data.type') === 'application/json') {
+        return ElMessage({
+          type: 'error',
+          message: `${t('common.fail')}`,
+        });
+      }
+      handleExport(res.data, filename);
+      ElMessage({
+        type: 'success',
+        message: `${t('device.exportSucceeded')}`,
+      });
+    }
+    function formatInfo(val) {
+      return val || '-';
+    }
+    return {
+      searchValue,
+      activeType,
+      tabPanelOptions,
+      runTime,
+      runResult,
+      tableData,
+      optionsPage,
+      ...toRefs(tablePage),
+      ...toRefs(pageReactive),
+      //   ...toRefs(tablePage),
+      langLocale,
+
+      resultOptions,
+      tableColumn,
+
+      handleSearch,
+      //   handlePaginateChange,
+      handleDownload,
+      handleCurrentPage,
+      handlePageSize,
+      formatInfo,
+    };
+  },
+  components: {
+    // ElTabs,
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.query-main {
+  min-height: calc(100% - 243px);
+  padding: 20px;
+  background: #f9fbfc;
+  display: flex;
+  &-container {
+    width: 100%;
+    display: flex;
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #eaecf0;
+    padding: 20px 20px 20px 0;
+  }
+  .container-left {
+    &:deep .el-tabs__active-bar {
+      min-width: 0 !important;
+    }
+    &:deep .el-tabs__item {
+      height: 24px;
+      line-height: 24px;
+      font-weight: 400;
+      color: #8e97aa;
+      font-size: 12px !important;
+      &.is-active {
+        font-weight: 400;
+        color: $theme-bj-color !important;
+      }
+    }
+    &:deep .el-tabs__nav-scroll,
+    &:deep .el-tabs__nav-wrap {
+      height: auto;
+    }
+  }
+  .container-right {
+    padding-left: 10px;
+    width: 500px;
+    flex: 1;
+    &-tip {
+      display: flex;
+      align-items: center;
+      height: 48px;
+      padding: 0 20px;
+      background: #fafafa;
+      font-weight: 500;
+      font-size: 12px;
+      color: #808ba3;
+      div {
+        margin-left: 50px;
+        display: flex;
+        align-items: center;
+      }
+      div:first-child {
+        margin-left: 0;
+      }
+      span {
+        padding-left: 12px;
+        font-size: 16px;
+        font-weight: 400;
+        color: #333;
+        line-height: 24px;
+      }
+    }
+    &-operate {
+      font-size: 12px;
+      display: flex;
+      flex-wrap: wrap;
+      align-items: center;
+      .operate-item {
+        margin-top: 20px;
+        display: flex;
+        align-items: center;
+      }
+      .operate-btn {
+        margin-left: 20px;
+        margin-top: 20px;
+      }
+      .input-box {
+        width: 160px;
+      }
+      .select-box {
+        width: 120px;
+      }
+      .input-label {
+        padding: 0 10px;
+      }
+      &:deep .el-date-editor--datetimerange.el-input__inner {
+        width: 320px;
+      }
+    }
+    &-table {
+      .slow-query {
+        display: inline-block;
+        background: #f33f2b;
+        color: #fff;
+        height: 18px;
+        line-height: 18px;
+        padding: 0 2px;
+      }
+
+      margin-top: 20px;
+      .success {
+        font-weight: 400;
+        color: #5776ed;
+      }
+      .error {
+        font-weight: 400;
+        color: #fd5c5c;
+      }
+      .table-pagination {
+        padding: 12px 0;
+        text-align: right;
+        display: flex;
+        justify-content: flex-end;
+        .pagination-title {
+          font-weight: 400;
+          font-size: 14px;
+          color: rgb(96, 98, 102);
+        }
+        &:deep button:hover {
+          color: #15c294;
+        }
+        &:deep li {
+          outline: none;
+          &:hover {
+            color: #15c294;
+          }
+          &.active {
+            color: #15c294;
+          }
+        }
+      }
+    }
+  }
+  &:deep .el-input .el-input__inner {
+    font-size: 12px;
+  }
+  &:deep .el-pagination {
+    font-size: 14px;
+    font-weight: 400;
+    color: rgba(34, 34, 34, 0.75);
+    line-height: 14px;
+  }
+  &:deep .el-pagination .el-select .el-input {
+    width: 60px;
+  }
+}
+</style>
diff --git a/frontend/src/views/Control/hooks/useInitChart.js b/frontend/src/views/Control/hooks/useInitChart.js
new file mode 100644
index 0000000..630e82e
--- /dev/null
+++ b/frontend/src/views/Control/hooks/useInitChart.js
@@ -0,0 +1,625 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 { getChartData } from '../api';
+import { useI18n } from 'vue-i18n';
+import { get } from 'lodash';
+const ChartMap = {
+  GCEchart: 0,
+  JVMClassEchart: 1,
+  YGCEchart: 2,
+  FGCEchart: 3,
+  JAVATypeEchart: 4,
+  JAVATimeEchart: 5,
+  MemoryEchart: 6,
+  BufferEchart: 7,
+  CPUEchart: 8,
+  IOEchart: 9,
+  FileCountEchart: 10,
+  FileSizeEchart: 11,
+  WriteEchart: 12,
+  SearchEchart: 13,
+  ApiEchart: 14,
+  ApiQPSEchart: 15,
+};
+let ChartCacheData = {};
+let chartsTitle = null;
+let t = null;
+async function initMatchChart(serverId, type, refreshData = true) {
+  !t && (t = useI18n().t);
+  chartsTitle = {
+    GCEchart: t('controlPage.GCEchart'),
+    JVMClassEchart: t('controlPage.JVMClassEchart'),
+    YGCEchart: t('controlPage.YGCEchart'),
+    FGCEchart: t('controlPage.FGCEchart'),
+    JAVATypeEchart: t('controlPage.JAVATypeEchart'),
+    JAVATimeEchart: t('controlPage.JAVATimeEchart'),
+    MemoryEchart: t('controlPage.MemoryEchart'),
+    BufferEchart: t('controlPage.BufferEchart'),
+    CPUEchart: t('controlPage.CPUEchart'),
+    IOEchart: t('controlPage.IOEchart'),
+    FileCountEchart: t('controlPage.FileCountEchart'),
+    FileSizeEchart: t('controlPage.FileSizeEchart'),
+    WriteEchart: t('controlPage.WriteEchart'),
+    SearchEchart: t('controlPage.SearchEchart'),
+    ApiEchart: t('controlPage.ApiEchart'),
+    ApiQPSEchart: t('controlPage.ApiQPSEchart'),
+  };
+  let res;
+  // Cache
+  if (refreshData === '0') {
+    res = ChartCacheData[type];
+  } else {
+    let result = await getChartData(serverId, ChartMap[type]);
+    ChartCacheData[type] = result.data.chartData;
+    res = result.data.chartData;
+  }
+  if (type === 'GCEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#5776ED', '#F69823', '#FD6031'],
+        legend: {
+          type: 'scroll',
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res ? res.timeList : [],
+        },
+        yAxis: {
+          type: 'category',
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'bar',
+            barGap: '0',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'JVMClassEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#5776ED', '#FD5C5C'],
+        legend: {
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res ? res.timeList : [],
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'YGCEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#F69823'],
+        tooltip: {},
+        xAxis: {
+          type: 'value',
+          splitLine: { show: false },
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' }, formatter: `{value}${get(res, 'unitList.0')}` },
+        },
+        yAxis: {
+          inverse: true,
+          type: 'category',
+          axisTick: { show: false },
+          data: res ? res.metricnameList : [],
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+        },
+        grid: {
+          top: '20px',
+          left: '20px',
+          right: '20px',
+          bottom: '16px',
+          containLabel: true,
+        },
+        series: [
+          {
+            type: 'bar',
+            data: res?.metricnameList.map((item, index) => {
+              return res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`).map((item) => parseFloat(item))[0];
+            }),
+          },
+        ],
+      },
+    };
+    return temp;
+  } else if (type === 'FGCEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#5855DA'],
+        tooltip: {},
+        xAxis: {
+          type: 'value',
+          splitLine: { show: false },
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' }, formatter: `{value}${get(res, 'unitList.0')}` },
+        },
+        yAxis: {
+          inverse: true,
+          type: 'category',
+          data: res ? res.metricnameList : [],
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+        },
+        grid: {
+          top: '20px',
+          left: '20px',
+          right: '20px',
+          bottom: '16px',
+          containLabel: true,
+        },
+        series: [
+          {
+            type: 'bar',
+            data: res?.metricnameList.map((item, index) => {
+              return res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`).map((item) => parseFloat(item))[0];
+            }),
+          },
+        ],
+      },
+    };
+    return temp;
+  } else if (type === 'JAVATypeEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#F69823', '#FD5C5C', '#5776ED'],
+        legend: {
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'JAVATimeEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#66A5FF', '#5776ED', '#F69823', '#FD5C5C', '#50D6BB'],
+        legend: {
+          type: 'scroll',
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'MemoryEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#5776ED'],
+        legend: {
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'BufferEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#5776ED'],
+        legend: {
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'CPUEchart') {
+    let data = [];
+    res?.metricnameList.map((item) => {
+      data.push({ value: parseFloat(get(res, `dataList.${item}`)), name: item });
+    });
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#5776ED', '#66A5FF', '#F69823', '#FD5C5C'],
+        legend: {
+          type: 'scroll',
+          bottom: '12px',
+        },
+        tooltip: {
+          trigger: 'item',
+          textStyle: {
+            align: 'left',
+          },
+          formatter: function (val) {
+            console.log(val.name, val.value);
+            return `${val.marker}${val.name}&nbsp;&nbsp;&nbsp;&nbsp;${val.value}%`;
+          },
+        },
+        xAxis: null,
+        yAxis: null,
+        series: [
+          {
+            name: chartsTitle[type],
+            type: 'pie',
+            radius: ['45%', '70%'],
+            avoidLabelOverlap: false,
+            center: ['50%', '120px'],
+            label: {
+              show: false,
+              position: 'center',
+            },
+            emphasis: {
+              label: {
+                show: false,
+                fontSize: '40',
+                fontWeight: 'bold',
+              },
+            },
+            labelLine: {
+              show: false,
+            },
+            data,
+          },
+        ],
+      },
+    };
+    return temp;
+  } else if (type === 'IOEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D'],
+        legend: null,
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'FileCountEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#5776ED', '#66A5FF', '#F69823', '#379E7D'],
+        legend: {
+          type: 'scroll',
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'FileSizeEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#5776ED', '#66A5FF', '#F69823', '#379E7D'],
+        legend: {
+          type: 'scroll',
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'WriteEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#FD6031', '#5776ED'],
+        legend: {
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+
+    return temp;
+  } else if (type === 'SearchEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#FD6031', '#5776ED'],
+        legend: {
+          data: res?.metricnameList,
+          bottom: '12px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'bar',
+            barGap: '0',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'ApiEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#66A5FF', '#5776ED', '#F69823', '#FD5C5C', '#50D6BB'],
+        legend: {
+          type: 'scroll',
+          data: res?.metricnameList,
+          bottom: '12px',
+          left: '20px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  } else if (type === 'ApiQPSEchart') {
+    let temp = {
+      title: chartsTitle[type],
+      options: {
+        color: ['#379E7D', '#66A5FF', '#5776ED', '#F69823', '#FD5C5C', '#50D6BB'],
+        legend: {
+          type: 'scroll',
+          data: res?.metricnameList,
+          bottom: '12px',
+          left: '20px',
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: { show: false },
+          axisLine: { show: true, lineStyle: { color: ' #eee', width: 1 } },
+          axisLabel: { show: true, textStyle: { color: '#8E97AA' } },
+          data: res?.timeList,
+        },
+        yAxis: {
+          axisLabel: {
+            //这种做法就是在y轴的数据的值旁边拼接单位,貌似也挺方便的
+            formatter: `{value}${get(res, 'unitList.0')}`,
+          },
+        },
+        series: res?.metricnameList.map((item, index) => {
+          return {
+            name: item,
+            data: res?.dataList && get(res, `dataList.${get(res, `metricnameList.${index}`)}`),
+            type: 'line',
+          };
+        }),
+      },
+    };
+    return temp;
+  }
+}
+export default initMatchChart;
diff --git a/frontend/src/views/Control/index.vue b/frontend/src/views/Control/index.vue
new file mode 100644
index 0000000..e78f36b
--- /dev/null
+++ b/frontend/src/views/Control/index.vue
@@ -0,0 +1,420 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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="monitor">
+    <el-container>
+      <el-aside :width="dividerWidth + 'px'">
+        <div class="aside-title">
+          {{ $t('controlPage.dataList') }}<span> ({{ filterDataList.length || 0 }}) </span>
+        </div>
+        <el-input v-if="dataList.length" v-model="search" class="w-50 m-2" :placeholder="$t('common.placeHolder')" suffix-icon="el-icon-search" />
+        <div class="aside-main">
+          <div :class="{ 'data-item': true, 'active-item': checkedId === item.id }" v-for="(item, index) in filterDataList" :key="index" @click="handleSwitch(item)">
+            <svg class="aside-icon" aria-hidden="true">
+              <use xlink:href="#icon-shujulianjie1"></use></svg
+            >{{ item.name }}
+          </div>
+          <div v-if="dataList.length === 0" class="datalist-empty">
+            <span>{{ $t('controlPage.nodata') }}</span>
+          </div>
+        </div>
+      </el-aside>
+      <div class="divider" ref="dividerRef"></div>
+      <el-main v-if="monitorInfo">
+        <div class="main-top">
+          <div class="main-head">
+            <div class="main-title">
+              {{ currentData.name }}
+              <span v-if="monitorInfo.status" class="survive">{{ $t('common.survival') }}</span>
+              <span v-else class="die">{{ $t('common.death') }}</span>
+            </div>
+            <div class="main-host format">
+              <div>
+                <svg class="main-icon" aria-hidden="true">
+                  <use xlink:href="#icon-se-icon-ip"></use>
+                </svg>
+                {{ $t('controlPage.address') }}:<span>{{ formatInfo(monitorInfo?.url) }}</span>
+              </div>
+              <div>
+                <svg class="main-icon" aria-hidden="true">
+                  <use xlink:href="#icon-duankou"></use>
+                </svg>
+                {{ $t('common.port') }}: <span>{{ formatInfo(monitorInfo?.port) }}</span>
+              </div>
+            </div>
+            <div class="main-info format">
+              <div>
+                <svg class="main-icon" aria-hidden="true">
+                  <use xlink:href="#icon-cunchuzu1"></use></svg
+                >{{ $t('controlPage.storage') }}: <span>{{ formatInfo(monitorInfo?.storageGroupCount) }}</span>
+              </div>
+              <div>
+                <svg class="main-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shiti"></use></svg
+                >{{ $t('controlPage.entity') }}: <span>{{ formatInfo(monitorInfo?.monitorCount) }}</span>
+              </div>
+              <div>
+                <svg class="main-icon" aria-hidden="true">
+                  <use xlink:href="#icon-wuliliang"></use></svg
+                >{{ $t('controlPage.physics') }}: <span>{{ formatInfo(monitorInfo?.deviceCount) }}</span>
+              </div>
+              <div>
+                <svg class="main-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shujuzongliang"></use></svg
+                >{{ $t('controlPage.total') }}: <span>{{ formatInfo(monitorInfo?.dataCount) }}</span>
+              </div>
+            </div>
+          </div>
+          <div class="main-top-tabs">
+            <el-tabs v-model="activeTab" @tab-click="handleChangeTab">
+              <template v-for="(item, index) in tabPaneOptions" :key="index">
+                <el-tab-pane v-bind="item" :disabled="item.name === 'Query' ? disabled : false"> </el-tab-pane>
+              </template>
+            </el-tabs>
+          </div>
+        </div>
+        <router-view v-slot="{ Component }">
+          <keep-alive>
+            <component :is="Component" :data="monitorInfo" />
+          </keep-alive>
+        </router-view>
+      </el-main>
+    </el-container>
+  </div>
+</template>
+
+<script>
+// @ is an alias to /src
+import { computed, onMounted, ref, watch } from 'vue';
+import { ElTabs, ElContainer, ElAside, ElMain } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import useElementResize from '@/hooks/useElementResize.js';
+import useLanguageWatch from '@/hooks/useLanguageWatch';
+import { useI18n } from 'vue-i18n';
+import { getMonitorList, getMonitorInfo } from './api';
+
+export default {
+  name: 'ComtrolIndex',
+  components: {
+    ElTabs,
+    ElContainer,
+    ElAside,
+    ElMain,
+  },
+  setup() {
+    let { t } = useI18n();
+    const router = useRouter();
+    const route = useRoute();
+    let routerParams = {};
+    let dividerRef = ref();
+    let dividerWidth = ref(240);
+    let search = ref();
+    let activeTab = ref('Indicator');
+    let currentData = ref(null);
+    let dataList = ref([]);
+    let monitorInfo = ref();
+    let show = ref(false);
+    let disabled = ref(false);
+    let tabPaneOptions = ref([
+      { name: 'Indicator', label: t('controlPage.monitor') },
+      { name: 'Query', label: t('controlPage.search') },
+    ]);
+    //数据列表选中id
+    let checkedId = computed(() => currentData.value && currentData.value.id);
+    let filterDataList = computed(() => {
+      let reg = new RegExp(search.value);
+      return dataList.value.filter((item) => {
+        if (reg.test(item.name)) {
+          return true;
+        }
+      });
+    });
+    watch(currentData, async (newValue) => {
+      if (newValue) {
+        let res = await getMonitorInfo(newValue.id);
+        monitorInfo.value = res.data;
+        if (monitorInfo.value?.status) {
+          disabled.value = false;
+          handleChangeTab({ paneName: activeTab.value });
+        } else {
+          handleChangeTab({ paneName: 'Indicator' });
+          disabled.value = true;
+        }
+      }
+    });
+
+    onMounted(() => {
+      initFun();
+      useElementResize(dividerRef, dividerWidth);
+      useLanguageWatch(tabPaneOptions, () => [
+        { name: 'Indicator', label: t('controlPage.monitor') },
+        { name: 'Query', label: t('controlPage.search') },
+      ]);
+    });
+
+    function urlSkip(routerName, id, params) {
+      let panelMode = monitorInfo.value?.status ? params?.panel || 'list' : 'list';
+      if (routerName == 'Indicator') {
+        router.push({ path: `/control/indicator/${panelMode}/${id}/${params.mode}`, query: { ...route.query } });
+      } else if (routerName === 'Query') {
+        router.push({ path: `/control/query/${id}` });
+      }
+    }
+    async function initFun() {
+      // init tabs
+      activeTab.value = routerNameLimit(route.name);
+      await getData();
+      //   routerParamId to data
+      filterCurrentData(route.params.id);
+    }
+    async function getData() {
+      let res = await getMonitorList();
+      dataList.value = res.data || [];
+    }
+    function routerNameLimit(name) {
+      for (let i = 0, len = tabPaneOptions.value.length; i < len; i++) {
+        if (tabPaneOptions.value[i].name === name) {
+          return name;
+        }
+      }
+      return tabPaneOptions.value[0].name;
+    }
+    function filterCurrentData(id) {
+      let len = dataList.value.length;
+      for (let i = 0; i < len; i++) {
+        let item = dataList.value[i];
+        if (item.id === +id) {
+          currentData.value = { ...item };
+          return;
+        }
+      }
+      currentData.value = dataList.value[0];
+    }
+    const handleChangeTab = (tabs) => {
+      routerParams[route.name] = route.params;
+      activeTab.value = tabs.paneName;
+      let id = currentData.value?.id;
+      let params = { ...routerParams['Indicator'] };
+      params.mode = routerParams['Indicator']?.mode || 'JVM';
+      urlSkip(tabs.paneName, id, params);
+    };
+    function handleSwitch(data) {
+      currentData.value = data;
+    }
+    function formatInfo(val) {
+      return val || '-';
+    }
+    return {
+      dividerRef,
+      dividerWidth,
+      activeTab,
+      search,
+      dataList,
+      currentData,
+      monitorInfo,
+      filterDataList,
+      show,
+      disabled,
+
+      checkedId,
+      tabPaneOptions,
+
+      handleChangeTab,
+      handleSwitch,
+      formatInfo,
+    };
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.monitor {
+  height: 100%;
+  .datalist-empty {
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 14px;
+    color: #909399;
+  }
+  .el-container {
+    height: 100%;
+  }
+  .el-aside {
+    text-align: left;
+    padding: 0 20px;
+  }
+  .divider {
+    z-index: 10;
+    width: 1px;
+    height: 100%;
+    background-color: #e0e0e0;
+    &:hover {
+      cursor: w-resize;
+      background-color: $theme-color;
+      width: 2px;
+    }
+  }
+  .aside-title {
+    height: 20px;
+    font-size: 14px;
+    font-weight: 500;
+    color: #333;
+    line-height: 20px;
+    margin: 20px 0;
+    span {
+      font-weight: 400;
+      color: #808a9f;
+    }
+  }
+  .aside-main {
+    margin: 20px 0 10px 0;
+    height: calc(100% - 118px);
+    font-size: 12px;
+    font-weight: 400;
+    overflow-y: auto;
+
+    .data-item {
+      margin-top: 10px;
+      height: 30px;
+      line-height: 30px;
+      border-radius: 4px;
+      display: flex;
+      align-items: center;
+      cursor: pointer;
+      &:hover {
+        background: #edf8f5;
+        color: $theme-color;
+      }
+      &:first-child {
+        margin-top: 0;
+      }
+    }
+    .active-item {
+      background: #edf8f5;
+      color: $theme-color;
+    }
+    .aside-icon {
+      width: 14px;
+      height: 14px;
+      margin: 0 10px;
+    }
+  }
+  .main-top {
+    padding: 20px 20px 0 20px;
+    &:deep .el-tabs {
+      .el-tabs__nav-wrap::after {
+        display: none;
+      }
+      .el-tabs__item.is-disabled {
+        cursor: not-allowed;
+        &:hover {
+          color: #8e97aaff !important;
+        }
+      }
+      .el-tabs__header {
+        margin: 0;
+      }
+      .el-tabs__item {
+        &.is-active {
+          color: #15c294 !important;
+        }
+      }
+    }
+    .main-top-tabs {
+      padding-left: 20px;
+    }
+  }
+  .main-head {
+    margin-bottom: 10px;
+    padding: 20px;
+    border-radius: 4px;
+    border: 1px solid #eaecf0;
+    text-align: left;
+    .main-title {
+      display: flex;
+      align-items: center;
+      height: 24px;
+      line-height: 24px;
+      color: #333;
+      font-size: 16px;
+      font-weight: 500;
+      span {
+        margin-left: 26px;
+        font-size: 12px;
+        padding: 0 12px;
+        height: 20px;
+        line-height: 20px;
+        border-radius: 2px;
+        &.survive {
+          color: #00a950;
+          background: rgba(0, 169, 80, 0.1);
+        }
+        &.die {
+          color: #f33f2b;
+          background: rgba(243, 63, 43, 0.1);
+        }
+      }
+    }
+    .format {
+      display: flex;
+      margin-top: 12px;
+      height: 20px;
+      line-height: 20px;
+      font-size: 12px;
+      color: #828ca1;
+      font-weight: 400;
+      > div {
+        display: flex;
+        margin-left: 38px;
+        align-items: center;
+        span {
+          color: #333;
+        }
+        &:first-child {
+          margin-left: 0;
+        }
+      }
+    }
+
+    .main-icon {
+      margin-right: 8px;
+      width: 14px;
+      height: 14px;
+    }
+  }
+  .main-tab {
+    display: inline-block;
+    padding: 12px 20px;
+  }
+
+  &:deep .el-main {
+    padding: 0;
+  }
+  &:deep td,
+  &:deep th {
+    height: 40px;
+  }
+  &:deep .el-input .el-input__inner {
+    font-size: 12px;
+  }
+}
+</style>
diff --git a/frontend/src/views/DataBaseM/components/dataListTree.vue b/frontend/src/views/DataBaseM/components/dataListTree.vue
index 8fba1b9..86ae528 100644
--- a/frontend/src/views/DataBaseM/components/dataListTree.vue
+++ b/frontend/src/views/DataBaseM/components/dataListTree.vue
@@ -74,7 +74,7 @@
 
 <script>
 import { ElTree, ElButton } from 'element-plus';
-import { reactive, ref, computed } from 'vue';
+import { reactive, ref, computed, nextTick } from 'vue';
 import { useStore } from 'vuex';
 import IconTypes from './iconTypes.vue';
 import axios from '@/util/axios.js';
@@ -110,7 +110,23 @@ export default {
     };
 
     const nodeClick = (data, node) => {
-      props.handleNodeClick(data, node);
+      if (data.type === 'pre' || data.type === 'next') {
+        const resolve = async (array) => {
+          const childNodes = node.parent.childNodes.slice();
+          props.handleNodeClick(node.parent.data, node.parent);
+          array.forEach((element) => {
+            nextTick(() => treeRef.value.append(element, node.parent));
+          });
+          await Promise.all(
+            childNodes.map((element) => {
+              return nextTick(() => treeRef.value.remove(element));
+            })
+          );
+        };
+        getData(node.parent, resolve, node);
+      } else {
+        props.handleNodeClick(data, node);
+      }
     };
 
     /**
@@ -170,7 +186,7 @@ export default {
       treeExpandKey.value = arr;
     };
 
-    const recurseDeviceTree = (data, node) => {
+    const recurseDeviceTree = (data, node, res) => {
       let newDevice = {
         id: node.data.id + ':newdevice',
         name: computed(() => t(`databasem.newDevice`)),
@@ -180,6 +196,35 @@ export default {
         connectionid: node.data.connectionid,
         storagegroupid: node.data.storagegroupid,
       };
+      let isPage = res.data.total > res.data.pageSize;
+      let prev = {
+        id: node.data.id + ':pre',
+        name: computed(() => t('sourcePage.prePage')),
+        type: 'pre',
+        leaf: true,
+        parent: node.data,
+        rawid: node.data.name,
+        connectionid: node.data.connectionid,
+        storagegroupid: node.data.storagegroupid,
+        serverId: res.serverId,
+        pageNum: res.data.pageNum,
+        pageSize: res.data.pageSize,
+        total: res.data.total,
+      };
+      let next = {
+        id: node.data.id + ':next',
+        name: computed(() => t('sourcePage.nextPage')),
+        type: 'next',
+        leaf: true,
+        parent: node.data,
+        rawid: node.data.name,
+        connectionid: node.data.connectionid,
+        storagegroupid: node.data.storagegroupid,
+        serverId: res.serverId,
+        pageNum: res.data.pageNum,
+        pageSize: res.data.pageSize,
+        total: res.data.total,
+      };
       let childs = data.map((e) => {
         let child = {
           parent: node.data,
@@ -192,16 +237,62 @@ export default {
           storagegroupid: node.data.storagegroupid,
           connectionid: node.data.connectionid,
           deviceid: e.name,
+          serverId: res.serverId,
         };
-        // if (e.children) {
-        let innerChilds = recurseDeviceTree(e.children || [], { data: child });
-        child.zones = innerChilds;
-        // }
+        if (e.children) {
+          let innerChilds = recurseDeviceTree(e.children || [], { data: child }, res);
+          child.zones = innerChilds;
+        }
         return child;
       });
+      isPage && childs.unshift(prev);
       childs.unshift(newDevice);
+      isPage && childs.push(next);
       return childs;
     };
+    const getData = (node, resolve, pagination) => {
+      let groupName = node.data.rawid;
+      let serverId = node.data.parent.rawid;
+      if (node.data.type !== 'storageGroup') {
+        serverId = node.data.serverId;
+      }
+      const params = { pageNum: (pagination && pagination.data.pageNum) || 1, pageSize: (pagination && pagination.data.pageSize) || 10 };
+      if (pagination && pagination.data.type === 'pre') {
+        params.pageNum = params.pageNum - 1 < 1 ? 1 : params.pageNum - 1;
+      }
+      if (pagination && pagination.data.type === 'next') {
+        const max = Math.ceil((pagination.data.total || 1) / params.pageSize);
+        params.pageNum = params.pageNum + 1 > max ? max : params.pageNum + 1;
+      }
+      axios
+        .get(`/servers/${serverId}/storageGroups/${groupName}/devices/tree`, {
+          params,
+        })
+        .then((res) => {
+          if (res?.code === '0') {
+            if (!res.data) {
+              let newDevice = {
+                id: node.data.id + ':newdevice',
+                name: computed(() => t(`databasem.newDevice`)),
+                type: 'newdevice',
+                leaf: true,
+                parent: node.data,
+                connectionid: node.data.connectionid,
+                storagegroupid: node.data.storagegroupid,
+              };
+              resolve([newDevice]);
+              return;
+            }
+            let childs = recurseDeviceTree(res.data.children || [], node, { serverId, data: res.data });
+            resolve(childs);
+          } else {
+            resolve([]);
+          }
+        })
+        .catch(() => {
+          resolve([]);
+        });
+    };
 
     const loadNode = (node, resolve) => {
       if (node?.data?.zones) {
@@ -281,53 +372,8 @@ export default {
             resolve([]);
           });
       }
-      if (node.level === 2 && node.data.type === 'storageGroup') {
-        let groupName = node.data.rawid;
-        let serverId = node.data.parent.rawid;
-        axios
-          .get(`/servers/${serverId}/storageGroups/${groupName}/devices/tree`, {})
-          .then((res) => {
-            if (res?.code === '0') {
-              if (!res.data) {
-                let newDevice = {
-                  id: node.data.id + ':newdevice',
-                  name: computed(() => t(`databasem.newDevice`)),
-                  type: 'newdevice',
-                  leaf: true,
-                  parent: node.data,
-                  connectionid: node.data.connectionid,
-                  storagegroupid: node.data.storagegroupid,
-                };
-                resolve([newDevice]);
-                return;
-              }
-              if (res.data.name === null) {
-                let childs = recurseDeviceTree(res.data.children || [], node);
-                resolve(childs);
-              } else {
-                let rootDevice = {
-                  // parent: node.data,
-                  name: res.data.name,
-                  // id: node.data.id + res.data.name + 'device',
-                  // type: 'device',
-                  // leaf: false,
-                  // rawid: res.data.name,
-                  // storagegroupid: node.data.storagegroupid,
-                  // connectionid: node.data.connectionid,
-                  // deviceid: res.data.name,
-                  children: res.data.children,
-                };
-                let childs = recurseDeviceTree([rootDevice] || [], node);
-                node.zones = childs;
-                resolve(childs);
-              }
-            } else {
-              resolve([]);
-            }
-          })
-          .catch(() => {
-            resolve([]);
-          });
+      if ((node.level === 2 && node.data.type === 'storageGroup') || (node.data && node.data.type === 'device')) {
+        getData(node, resolve);
       }
       if (node.level === 2 && node.data.type === 'querylist') {
         let serverId = node.data.parent.rawid;
diff --git a/frontend/src/views/DataBaseM/index.vue b/frontend/src/views/DataBaseM/index.vue
index cf9e9d5..c549225 100644
--- a/frontend/src/views/DataBaseM/index.vue
+++ b/frontend/src/views/DataBaseM/index.vue
@@ -74,12 +74,12 @@
 <script>
 // @ is an alias to /src
 import { onMounted, ref, watch } from 'vue';
-import useElementResize from './hooks/useElementResize.js';
+import { useStore } from 'vuex';
+import { useRouter, useRoute } from 'vue-router';
+import useElementResize from '@/hooks/useElementResize.js';
 import DataListTree from './components/dataListTree.vue';
 import IconTypes from './components/iconTypes.vue';
 import { ElContainer, ElAside, ElMain, ElTabs, ElTabPane } from 'element-plus';
-import { useStore } from 'vuex';
-import { useRouter, useRoute } from 'vue-router';
 
 export default {
   name: 'Root',
diff --git a/frontend/src/views/Device/index.vue b/frontend/src/views/Device/index.vue
index 9e3cef8..73ba311 100644
--- a/frontend/src/views/Device/index.vue
+++ b/frontend/src/views/Device/index.vue
@@ -22,9 +22,7 @@
     <form-table :form="form"></form-table>
     <div class="addbox">
       {{ $t('device.physical') }}
-      <el-button type="primary" class="addbutton" size="small" @click="addItem">
-        {{ $t('device.addphysical') }}
-      </el-button>
+      <el-button type="primary" class="addbutton" size="small" @click="addItem"> {{ $t('device.addphysical') }} </el-button>
     </div>
     <div class="tableBox">
       <stand-table
@@ -118,6 +116,9 @@ export default {
           type: 'INPUT',
           size: 'small',
           canEdit: true,
+          border: true,
+          required: true,
+          event: checkValue,
         },
         {
           label: 'device.datatype',
@@ -213,7 +214,7 @@ export default {
           required: true,
           disabled: false,
           inputHeader: true,
-          inputHeaderText: 'groupName',
+          inputHeaderText: (data) => `${data.groupName}.`,
           message: 'device.inputdevice',
         },
         {
@@ -231,6 +232,13 @@ export default {
     function changeBorder(scope) {
       tableData.list[scope.$index].seBorder = false;
     }
+    function checkValue(scope, object, value, event, item) {
+      if (value == null || value === '') {
+        ElMessage.error(`${t('common.placeHolder')}${t(item.label)}`);
+      } else {
+        tableData.list[scope.$index].border = false;
+      }
+    }
     function checkVal(scope, obj, val) {
       console.log(obj);
       if (!/^\w+$/.test(val)) {
@@ -331,11 +339,14 @@ export default {
     function sumbitData() {
       let checkfalg = true;
       tableData.list.forEach((item) => {
-        if (item.timeseries === null || item.dataType === null || item.border || item.seBorder) {
+        if (item.timeseries === null || item.dataType === null || item.border || item.seBorder || item.alias == null || item.alias === '') {
           if (checkfalg) {
             if (item.timeseries === null) {
               item.border = true;
               ElMessage.error(`${t('device.pynamel')}`);
+            } else if (item.alias == null || item.alias === '') {
+              item.border = true;
+              ElMessage.error(`${t('common.placeHolder')}${t('device.alias')}`);
             } else if (item.dataType === null) {
               item.seBorder = true;
               ElMessage.error(`"${item.timeseries}"${t('device.selectdatatype')}`);
@@ -351,6 +362,9 @@ export default {
       if (checkfalg) {
         let copyForm = _cloneDeep(form);
         let { deviceName, groupName } = copyForm.formData;
+        if (/\./.test(deviceName)) {
+          return ElMessage.error(`"${t('device.devicename')}"${t('device.must')}`);
+        }
         let copyTableData = _cloneDeep(tableData);
         copyForm.formData.deviceName = deviceName ? groupName + '.' + deviceName : groupName;
 
diff --git a/frontend/src/views/DeviceMessage/index.vue b/frontend/src/views/DeviceMessage/index.vue
index c6a219f..0c2d34e 100644
--- a/frontend/src/views/DeviceMessage/index.vue
+++ b/frontend/src/views/DeviceMessage/index.vue
@@ -27,13 +27,13 @@
             <el-button @click="editDevce">
               <svg class="icon edit" aria-hidden="true">
                 <use xlink:href="#icon-se-icon-f-edit"></use></svg
-              >&nbsp;{{ $t('common.edit') }}</el-button
-            >
+              >&nbsp;{{ $t('common.edit') }}
+            </el-button>
             <el-button @click="deleteData">
               <svg class="icon delete" aria-hidden="true">
                 <use xlink:href="#icon-se-icon-delete"></use></svg
-              >&nbsp;{{ $t('common.delete') }}</el-button
-            >
+              >&nbsp;{{ $t('common.delete') }}
+            </el-button>
           </div>
         </div>
         <div class="messageBox">
@@ -52,7 +52,7 @@
             </svg>
           </span>
           <span style="margin-left: 5px">{{ $t('device.description') }}:</span>
-          <span>{{ deviceObj.deviceData.description }}</span>
+          <span class="ellipsis" :title="deviceObj.deviceData.description">{{ deviceObj.deviceData.description }}</span>
           <span class="spanmargin">
             <svg class="icon" aria-hidden="true">
               <use xlink:href="#icon-user"></use>
@@ -78,6 +78,7 @@
             <form-table :form="form" @serchFormData="serchFormData"></form-table>
           </div>
           <stand-table
+            v-loading="loading"
             :column="column"
             :tableData="tableData"
             :getList="getListData"
@@ -238,8 +239,8 @@
 import { ElMessageBox, ElMessage, ElButton, ElTabs, ElTabPane, ElDropdown, ElDropdownMenu, ElDropdownItem, ElDialog, ElForm, ElFormItem, ElProgress } from 'element-plus';
 import StandTable from '@/components/StandTable';
 import FormTable from '@/components/FormTable';
-import { reactive, ref, onActivated } from 'vue';
-import { getList, getDeviceDate, getTimeseiresList, deleteDevice, getDataDeviceList, randomImport, editData, deleteDeviceData, exportDataCSV, downloadFile, importData } from './api';
+import { reactive, ref, onActivated, computed } from 'vue';
+import { getList, getDeviceDate, deleteDevice, getDataDeviceList, randomImport, editData, deleteDeviceData, exportDataCSV, downloadFile, importData } from './api';
 import Echarts from '@/components/Echarts';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
@@ -357,7 +358,7 @@ export default {
           width: '150px',
           itemID: 'measurementList',
           placeholder: 'device.serchPy',
-          options: timeseriesOptions,
+          options: computed(() => [{ label: t('device.all'), value: '' }, ...timeseriesOptions.value]),
           multiple: true,
         },
       ],
@@ -808,19 +809,25 @@ export default {
     }
     //Get physical quantity list
     async function getListData() {
-      await getList(routeData.obj, { ...pagination, ...form.formData }).then((res) => {
-        tableData.list = res.data.measurementVOList;
-        totalCount.value = res.data.totalCount;
-      });
+      try {
+        loading.value = true;
+        await getList(routeData.obj, { ...pagination, ...form.formData }).then((res) => {
+          tableData.list = res.data.measurementVOList;
+          totalCount.value = res.data.totalCount;
+          getTimeseriesOption(res.data.measurementVOList.map((item) => item.timeseries));
+        });
+      } catch (error) {
+        //   console.error(error)
+      } finally {
+        loading.value = false;
+      }
     }
-    async function getTimeseriesOption() {
-      let { connectionid, storagegroupid, deviceid } = routeData.obj;
-      await getTimeseiresList(connectionid, storagegroupid, deviceid).then((res) => {
-        if (res.code === '0') {
-          timeseriesOptions.value = res.data.map((d) => ({ label: d, value: d }));
-          timeseriesOptions.value.unshift({ label: t('device.all'), value: '' });
-        }
-      });
+    async function getTimeseriesOption(array) {
+      let before = timeseriesOptions.value.map((item) => item.value);
+      before.unshift(...array);
+      timeseriesOptions.value = [...new Set(before)].map((d) => ({ label: d, value: d })).slice(0, 50);
+      form1.formData.measurementList[0] = '';
+      getPview();
     }
     //Get physical quantity data preview list
     function getPview() {
@@ -843,9 +850,23 @@ export default {
       if (form1.formData.measurementList[0] === '') {
         data = timeseriesOptions.value.filter((d) => d.value !== '').map((d) => d.value);
       }
+      if (!Array.isArray(data) || data.length === 0) return;
       getDataDeviceList(routeData.obj, pagination1, { startTime: sTime, endTime: eTime, measurementList: data }).then((res) => {
         res.data.metaDataList.forEach((item, index) => {
-          column1.list.push({ label: item, prop: `t${index}`, value: '——', icon: index ? res.data.typeList[index] : 'TIME' });
+          column1.list.push({
+            label: item,
+            prop: `t${index}`,
+            value: '——',
+            icon: index ? res.data.typeList[index] : 'TIME',
+            closable:
+              index > 0 && (form1.formData.measurementList.length === 0 || form1.formData.measurementList[0] !== item)
+                ? (data) => {
+                    const index = timeseriesOptions.value.findIndex((item) => item.value === data.label);
+                    timeseriesOptions.value.splice(index, 1);
+                    getPview();
+                  }
+                : void 0,
+          });
         });
         res.data.valueList.forEach((item) => {
           let obj = {};
@@ -900,7 +921,6 @@ export default {
       }
       setTimeout(async () => {
         getdData();
-        await getTimeseriesOption();
         await getListData();
         await getPview();
       }, 500);
@@ -1127,6 +1147,15 @@ $cursor: pointer;
   color: #fff;
   margin-top: 3px;
 }
+
+.ellipsis {
+  display: inline-block;
+  width: 80px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  vertical-align: top;
+  text-align: left;
+}
 </style>
 <style lang="scss">
 .tab_class {
diff --git a/frontend/src/views/Login/index.vue b/frontend/src/views/Login/index.vue
index 2b973c6..3b18b4f 100644
--- a/frontend/src/views/Login/index.vue
+++ b/frontend/src/views/Login/index.vue
@@ -23,12 +23,18 @@
       <div class="header-logo"></div>
       <div class="lang-btn">
         <el-dropdown @command="handleLangCommand">
-          <span class="el-dropdown-link"> {{ [$t('rootPage.chinalang'), $t('rootPage.englishlang'), $t('rootPage.deutsch')][langIndex] }}<i class="el-icon-arrow-down el-icon--right"></i> </span>
+          <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="1.2em" height="1.2em" data-v-dd9c9540="">
+            <path
+              fill="currentColor"
+              d="m18.5 10l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16.5 10h2zM10 2v2h6v2h-1.968a18.222 18.222 0 0 1-3.62 6.301a14.864 14.864 0 0 0 2.336 1.707l-.751 1.878A17.015 17.015 0 0 1 9 13.725a16.676 16.676 0 0 1-6.201 3.548l-.536-1.929a14.7 14.7 0 0 0 5.327-3.042A18.078 18.078 0 0 1 4.767 8h2.24A16.032 16.032 0 0 0 9 10.877a16.165 16.165 0 0 0 2.91-4.876L2 6V4h6V2h2zm7.5 10.885L16.253 16h2.492L17.5 12.885z"
+            ></path>
+          </svg>
+
           <template #dropdown>
             <el-dropdown-menu>
-              <el-dropdown-item :disabled="langIndex === 0" command="0">{{ $t('rootPage.chinalang') }}</el-dropdown-item>
-              <el-dropdown-item :disabled="langIndex === 1" command="1">{{ $t('rootPage.englishlang') }}</el-dropdown-item>
-              <el-dropdown-item :disabled="langIndex === 2" command="2">{{ $t('rootPage.deutsch') }}</el-dropdown-item>
+              <el-dropdown-item :disabled="langIndex === 0" command="0">中文</el-dropdown-item>
+              <el-dropdown-item :disabled="langIndex === 1" command="1">English</el-dropdown-item>
+              <el-dropdown-item :disabled="langIndex === 2" command="2">Deutsch</el-dropdown-item>
             </el-dropdown-menu>
           </template>
         </el-dropdown>
@@ -58,7 +64,7 @@
       </div>
     </div>
 
-    <el-dialog append-to-body :title="$t(`loginPage.forgetPassword`)" v-model="dialogVisible" width="30%">
+    <el-dialog append-to-body :title="$t(`loginPage.forgetPassword`)" v-model="dialogVisible" width="32%">
       <div class="forget-tip">
         {{ $t(`loginPage.forgetPasswordTip`) }}
       </div>
@@ -188,9 +194,10 @@ export default {
     position: relative;
     .lang-btn {
       position: absolute;
-      right: 20px;
+      right: 40px;
       top: 50%;
       transform: translate(0, -50%);
+      cursor: pointer;
     }
     .header-logo {
       background-image: url(~@/assets/logo.png);
diff --git a/frontend/src/views/Root/index.vue b/frontend/src/views/Root/index.vue
index 3b57237..ba1d3eb 100644
--- a/frontend/src/views/Root/index.vue
+++ b/frontend/src/views/Root/index.vue
@@ -23,16 +23,22 @@
       <el-header>
         <el-menu :default-active="menuIndex" mode="horizontal" @select="handleMenuSelect">
           <el-menu-item index="1">{{ $t('rootPage.databaseManagement') }}</el-menu-item>
+          <el-menu-item index="2">{{ $t('rootPage.monitorManagement') }}</el-menu-item>
         </el-menu>
         <div class="logo-img"></div>
         <div class="lang-btn">
           <el-dropdown @command="handleLangCommand">
-            <span class="el-dropdown-link"> {{ [$t('rootPage.chinalang'), $t('rootPage.englishlang'), $t('rootPage.deutsch')][langIndex] }}<i class="el-icon-arrow-down el-icon--right"></i> </span>
+            <svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24" width="1.2em" height="1.2em" data-v-dd9c9540="">
+              <path
+                fill="currentColor"
+                d="m18.5 10l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16.5 10h2zM10 2v2h6v2h-1.968a18.222 18.222 0 0 1-3.62 6.301a14.864 14.864 0 0 0 2.336 1.707l-.751 1.878A17.015 17.015 0 0 1 9 13.725a16.676 16.676 0 0 1-6.201 3.548l-.536-1.929a14.7 14.7 0 0 0 5.327-3.042A18.078 18.078 0 0 1 4.767 8h2.24A16.032 16.032 0 0 0 9 10.877a16.165 16.165 0 0 0 2.91-4.876L2 6V4h6V2h2zm7.5 10.885L16.253 16h2.492L17.5 12.885z"
+              ></path>
+            </svg>
             <template #dropdown>
               <el-dropdown-menu>
-                <el-dropdown-item :disabled="langIndex === 0" command="0">{{ $t('rootPage.chinalang') }}</el-dropdown-item>
-                <el-dropdown-item :disabled="langIndex === 1" command="1">{{ $t('rootPage.englishlang') }}</el-dropdown-item>
-                <el-dropdown-item :disabled="langIndex === 2" command="2">{{ $t('rootPage.deutsch') }}</el-dropdown-item>
+                <el-dropdown-item :disabled="langIndex === 0" command="0">中文</el-dropdown-item>
+                <el-dropdown-item :disabled="langIndex === 1" command="1">English</el-dropdown-item>
+                <el-dropdown-item :disabled="langIndex === 2" command="2">Deutsch</el-dropdown-item>
               </el-dropdown-menu>
             </template>
           </el-dropdown>
@@ -65,19 +71,30 @@
 // @ is an alias to /src
 import { onMounted, ref } from 'vue';
 import { useStore } from 'vuex';
-import { useRouter } from 'vue-router';
+import { useRouter, useRoute } from 'vue-router';
 import useLangSwitch from './hooks/useLangSwitch.js';
 import { ElContainer, ElHeader, ElMenu, ElMenuItem, ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus';
 
 export default {
   name: 'Root',
   setup() {
+    const TopMenuMap = {
+      DataBaseM: '1',
+      Control: '2',
+    };
     const router = useRouter();
+    const route = useRoute();
     const store = useStore();
-    const menuIndex = ref('1');
+    const menuIndex = ref(TopMenuMap[route.matched[1]?.name] || '1');
     const { langIndex, handleLangCommand } = useLangSwitch();
     const handleMenuSelect = (key) => {
       menuIndex.value = key;
+      if (key == 1) {
+        store.commit('setFirstPageLoad', true);
+        router.push({ name: 'DataBaseM' });
+      } else if (key == 2) {
+        router.push({ name: 'Control' });
+      }
     };
 
     const handleLoginCommand = (val) => {
@@ -101,7 +118,6 @@ export default {
       store.commit('setFirstPageLoad', true);
       store.dispatch('fetchIsLogin');
     });
-
     // watch(
     //   () => {
     //     return store.state.userInfo;
@@ -179,14 +195,16 @@ export default {
   .lang-btn {
     position: absolute;
     right: 100px;
-    top: 50%;
+    top: 52%;
     transform: translate(0, -50%);
+    cursor: pointer;
   }
   .user-btn {
     position: absolute;
     right: 20px;
     top: 50%;
     transform: translate(0, -50%);
+    cursor: pointer;
   }
 }
 </style>
diff --git a/frontend/src/views/Source/components/dataModal.vue b/frontend/src/views/Source/components/dataModal.vue
index ba811c4..42c3c4d 100644
--- a/frontend/src/views/Source/components/dataModal.vue
+++ b/frontend/src/views/Source/components/dataModal.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <template>
   <div id="main" class="main-contain"></div>
 </template>
@@ -19,23 +37,25 @@ export default {
   name: 'DataModal',
   //   props: ['func'],
   //   setup(props) {
-  setup() {
+  setup(props, { emit }) {
     const { t } = useI18n();
     const x = ref(0);
     const router = useRouter();
     const datas = ref({});
+    let showNum = ref(0);
 
     const getModalTreeData = (func) => {
       axios.get(`/servers/${router.currentRoute.value.params.serverid}/dataModel`, {}).then((res) => {
         if (res && res.code == 0) {
           datas.value = res.data || {};
+          showNum.value = res.data.showNum;
+          emit('show-num', showNum);
           func && func();
         }
       });
     };
-    const initCharts = () => {
-      MyCharts = echarts.init(document.getElementById('main'));
 
+    const setOption = () => {
       let option = {
         tooltip: {
           trigger: 'item',
@@ -68,6 +88,10 @@ export default {
             top: '8%',
             bottom: '8%',
             roam: true,
+            scaleLimit: {
+              min: 0.5,
+              max: 3,
+            },
             symbol: 'emptyCircle',
             symbolSize: 0,
             orient: 'vertical',
@@ -150,9 +174,16 @@ export default {
         ],
       };
 
+      // show echart
       MyCharts.setOption(option);
     };
 
+    const initCharts = () => {
+      MyCharts = echarts.init(document.getElementById('main'));
+
+      setOption();
+    };
+
     onMounted(() => {
       // getModalTreeData(() => {
       //   initCharts();
diff --git a/frontend/src/views/Source/components/dataModalAll.vue b/frontend/src/views/Source/components/dataModalAll.vue
index aaef6bd..170e9d0 100644
--- a/frontend/src/views/Source/components/dataModalAll.vue
+++ b/frontend/src/views/Source/components/dataModalAll.vue
@@ -1,10 +1,28 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <template>
   <div id="mains" class="mains-contain"></div>
 </template>
 
 <script>
 // @ is an alias to /src
-import { onMounted, ref, onActivated, onDeactivated } from 'vue';
+import { onMounted, ref, onActivated, onDeactivated, reactive } from 'vue';
 import * as echarts from 'echarts';
 // import { ElButton } from 'element-plus';
 import { useI18n } from 'vue-i18n';
@@ -25,83 +43,88 @@ export default {
     const x = ref(0);
     const router = useRouter();
     // const route = useRoute();
-
+    const pagination = reactive({
+      pageSize: 10,
+      pageNum: 1,
+    });
     const datas = ref({});
 
     const getModalTreeData = (func) => {
-      axios.get(`/servers/${router.currentRoute.value.params.serverid}/dataModel`, {}).then((res) => {
-        if (res && res.code == 0) {
-          // dealData(res.data, (res.data && res.data.children) || [], 0);
-          dealData([res.data] || {}, 0);
-          datas.value = res.data || {};
-          func && func();
-        }
-      });
+      axios
+        .get(`/servers/${router.currentRoute.value.params.serverid}/dataModel/detail`, {
+          params: pagination,
+        })
+        .then((res) => {
+          if (res && res.code == 0) {
+            res.data.pageSize = pagination.pageSize;
+            res.data.pageNum = pagination.pageNum;
+            dealData([res.data] || {}, 0);
+            res.data.collapsed = false;
+            datas.value = res.data || {};
+            func && func();
+          }
+        });
     };
     /**
      * data current level data
      * index  level num
      */
-    const dealData = (data, index) => {
+    const dealData = (data) => {
       for (let i = 0; i < data.length; i++) {
-        if (index < initialTreeDepth.value) {
-          data[i].collapsed = false;
-        } else {
-          data[i].collapsed = true;
-        }
+        data[i].collapsed = true;
+        const isNext = data[i].total > data[i].pageNum * data[i].pageSize;
+        const isPrev = data[i].pageNum !== 1;
         if (data[i].children && data[i].children.length) {
-          if (data[i].children.length > 10) {
-            data[i].pageNum = 1;
-            data[i].totalPage = Math.ceil(data[i].children.length / 10);
-            data[i].childrensTemp = JSON.parse(JSON.stringify(data[i].children));
-            data[i].children = data[i].children.splice((data[i].pageNum - 1) * 10, 10);
-
-            data[i].children.push({ name: t('sourcePage.nextPage'), parentName: data[i].path, type: 'next', pageNum: 1, totalPage: Math.ceil(data[i].childrensTemp.length / 10) });
-            data[i].children.unshift({ name: t('sourcePage.prePage'), parentName: data[i].path, type: 'pre', pageNum: 1, totalPage: Math.ceil(data[i].childrensTemp.length / 10) });
-          } else {
-            data[i].pageNum = 1;
-            data[i].totalPage = 1;
-          }
-
-          index += 1;
-          dealData(data[i].children, index);
+          isNext && data[i].children.push({ name: t('sourcePage.nextPage'), path: data[i].path, type: 'next', pageNum: data[i].pageNum, pageSize: data[i].pageSize });
+          isPrev && data[i].children.unshift({ name: t('sourcePage.prePage'), path: data[i].path, type: 'pre', pageNum: data[i].pageNum, pageSize: data[i].pageSize });
         }
       }
     };
-
+    let loading = false;
     const clickFunction = (params) => {
+      if (loading) return;
+      loading = true;
       let data = params.data || {};
-      if (data.type) {
-        //do next if has 'type' key;
-        if (data.type == 'pre') {
-          if (data.pageNum == 1) {
-            return;
-          } else {
-            circulateData(data, 'pre');
-          }
-        } else if (data.type == 'next') {
-          if (data.pageNum == data.totalPage) {
-            return;
-          } else {
-            circulateData(data, 'next');
-          }
-        }
+      if (data.type === 'next') {
+        data.pageNum += 1;
+      } else if (data.type === 'pre' && data.pageNum >= 1) {
+        data.pageNum -= 1;
       } else {
-        if (params.data.children && params.data.children.length) {
-          circulateDataSelf(data);
-        }
+        data.pageNum = 1;
+        data.pageSize = 10;
       }
+      axios
+        .get(`/servers/${router.currentRoute.value.params.serverid}/dataModel/detail`, {
+          params: { pageNum: data.pageNum, pageSize: data.pageSize, path: data.path },
+        })
+        .then((res) => {
+          if (res && res.code == 0) {
+            dealData([res.data] || [], 0);
+            params.data.children = res.data.children || [];
+            if (params.data.children && params.data.children.length) {
+              circulateDataSelf(data, res.data || {}); //第二个参数为动态请求回来的数据
+            }
+          }
+        })
+        .finally(() => {
+          loading = false;
+        });
     };
-    const circulateDataSelf = (data) => {
+    const circulateDataSelf = (data, levelData) => {
       let name = data.path;
       // let dataAll = datas.value;
       let index = 1;
-      deepSearchSelf(datas.value, name, index);
+      deepSearchSelf(datas.value, name, index, levelData);
     };
-    const deepSearchSelf = (data, name, index) => {
+    const deepSearchSelf = (data, name, index, levelData) => {
       if (data.path == name) {
         //do it
+        data.collapsed = levelData.collapsed;
         data.collapsed = !data.collapsed;
+        data.children = levelData.children || [];
+        data.childrensTemp = levelData.childrensTemp || [];
+        data.pageNum = levelData.pageNum;
+        data.totalPage = levelData.totalPage;
         initialTreeDepth.value = index;
         MyChart.clear();
         setOption();
@@ -110,55 +133,12 @@ export default {
         index++;
         if (data.children && data.children.length) {
           for (let i = 0; i < data.children.length; i++) {
-            deepSearchSelf(data.children[i], name, index);
+            deepSearchSelf(data.children[i], name, index, levelData);
           }
         }
       }
     };
-    const circulateData = (data, type) => {
-      let name = data.parentName;
-      let dataAll = datas.value;
-      let index = 1;
-      deepSearch(dataAll, name, type, index);
-    };
     const initialTreeDepth = ref(1);
-    const deepSearch = (data, name, type, index) => {
-      if (data.path == name) {
-        //do it
-        // data.collapsed = false;
-        let temp = JSON.parse(JSON.stringify(data.childrensTemp));
-        initialTreeDepth.value = index;
-        if (type == 'next') {
-          data.pageNum += 1;
-          temp = temp.splice((data.pageNum - 1) * 10, 10);
-          data.children[0].pageNum += 1;
-          data.children[data.children.length - 1].pageNum += 1;
-        } else {
-          data.pageNum -= 1;
-          temp = temp.splice((data.pageNum - 1) * 10, 10);
-          data.children[0].pageNum -= 1;
-          data.children[data.children.length - 1].pageNum -= 1;
-        }
-        temp.unshift(data.children[0]);
-        temp.push(data.children[data.children.length - 1]);
-        data.children = temp;
-        for (let i = 0; i < temp.length; i++) {
-          if (temp[i].children && temp[i].children.length) {
-            dealData(temp[i], temp[i].children || []);
-          }
-        }
-        MyChart.clear();
-        setOption();
-        return;
-      } else {
-        index++;
-        if (data.children && data.children.length) {
-          for (let i = 0; i < data.children.length; i++) {
-            deepSearch(data.children[i], name, type, index);
-          }
-        }
-      }
-    };
     const initCharts = () => {
       //  init charts
       MyChart = echarts.init(document.getElementById('mains'));
@@ -196,11 +176,15 @@ export default {
             type: 'tree',
             edgeShape: 'polyline',
             data: [datas.value],
-            left: '2%',
+            left: '4%',
             // right: '2%',
             top: '8%',
             bottom: '8%',
             roam: true,
+            scaleLimit: {
+              min: 0.5,
+              max: 3,
+            },
             symbol: 'emptyCircle',
             symbolSize: 0,
             // orient: 'vertical',
diff --git a/frontend/src/views/Source/components/permitDialog.vue b/frontend/src/views/Source/components/permitDialog.vue
index e9b55cf..f37b4e5 100644
--- a/frontend/src/views/Source/components/permitDialog.vue
+++ b/frontend/src/views/Source/components/permitDialog.vue
@@ -21,12 +21,12 @@
   <div id="mains" class="mains-contain">
     <el-dialog v-model="visible" :title="dialogType === 'add' ? $t('sourcePage.addPermission') : $t('sourcePage.editPermission')" width="520px">
       <el-form ref="formRef" :model="form" :rules="rules" label-position="top" class="permit-form">
-        <el-form-item prop="type" :label="$t('sourcePage.path')">
+        <el-form-item prop="type" :label="language.path">
           <el-radio-group v-model="form.type" @change="changeRadio">
             <el-radio v-for="item in pathList" :disabled="dialogType === 'edit'" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
           </el-radio-group>
         </el-form-item>
-        <el-form-item prop="path" :label="$t('sourcePage.range')">
+        <el-form-item prop="path" :label="language.range">
           <!-- data connection -->
           <template v-if="form.type === 0"> -- </template>
           <!-- Storage group -->
@@ -53,7 +53,7 @@
             </el-select>
           </template>
         </el-form-item>
-        <el-form-item prop="privileges" :label="$t('sourcePage.selectPermissions')">
+        <el-form-item prop="privileges" :label="language.selectPermissions">
           <el-checkbox-group v-model="form.privileges">
             <el-checkbox v-for="item in dataPrivileges[form.type]" :key="item.id" :label="item.id" :value="item.id">{{ item.label }}</el-checkbox>
           </el-checkbox-group>
@@ -61,8 +61,8 @@
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button @click="handleCancel">{{ $t('common.cancel') }}</el-button>
-          <el-button type="primary" @click="handleSubmit">{{ $t('common.submit') }}</el-button>
+          <el-button @click="handleCancel">{{ language.cancel }}</el-button>
+          <el-button type="primary" @click="handleSubmit">{{ language.submit }}</el-button>
         </span>
       </template>
     </el-dialog>
@@ -105,7 +105,15 @@ export default {
       path: [], //tree
       privileges: [],
     });
-
+    let language = computed(() => {
+      return {
+        cancel: t('common.cancel'),
+        submit: t('common.submit'),
+        path: t('sourcePage.path'),
+        range: t('sourcePage.range'),
+        selectPermissions: t('sourcePage.selectPermissions'),
+      };
+    });
     let storage = ref([]);
     let device = reactive({
       storage: '',
@@ -508,6 +516,8 @@ export default {
       form,
       granularityValue,
       rules,
+      language,
+
       ...toRefs(options),
       open,
       origin,
diff --git a/frontend/src/views/Source/components/role/AuthManage.vue b/frontend/src/views/Source/components/role/AuthManage.vue
index c069bdd..c4cd097 100644
--- a/frontend/src/views/Source/components/role/AuthManage.vue
+++ b/frontend/src/views/Source/components/role/AuthManage.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- Permission management permission -->
 <template>
   <div class="permitpermission-content">
diff --git a/frontend/src/views/Source/components/role/DataManage.vue b/frontend/src/views/Source/components/role/DataManage.vue
index 4cc52d0..027318c 100644
--- a/frontend/src/views/Source/components/role/DataManage.vue
+++ b/frontend/src/views/Source/components/role/DataManage.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- Role data management permission -->
 <template>
   <div class="data-manage">
diff --git a/frontend/src/views/Source/components/role/DialogGrantUser.vue b/frontend/src/views/Source/components/role/DialogGrantUser.vue
index 133c8bf..1885425 100644
--- a/frontend/src/views/Source/components/role/DialogGrantUser.vue
+++ b/frontend/src/views/Source/components/role/DialogGrantUser.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- Authorized user Popup -->
 <template>
   <el-dialog :title="$t('sourcePage.grantUser')" width="520px" :append-to-body="true" v-model="visible" custom-class="grant-dialog">
diff --git a/frontend/src/views/Source/components/role/Index.vue b/frontend/src/views/Source/components/role/Index.vue
index 463a028..a9e5102 100644
--- a/frontend/src/views/Source/components/role/Index.vue
+++ b/frontend/src/views/Source/components/role/Index.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- 用户角色 -->
 <template>
   <div class="user-role-wrapper">
diff --git a/frontend/src/views/Source/components/role/PowerManage.vue b/frontend/src/views/Source/components/role/PowerManage.vue
index 8e4046c..e8741b5 100644
--- a/frontend/src/views/Source/components/role/PowerManage.vue
+++ b/frontend/src/views/Source/components/role/PowerManage.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- Right part of role management -->
 <template>
   <div id="role-tabs">
diff --git a/frontend/src/views/Source/components/role/RoleInfo.vue b/frontend/src/views/Source/components/role/RoleInfo.vue
index 558bae2..24e3d5e 100644
--- a/frontend/src/views/Source/components/role/RoleInfo.vue
+++ b/frontend/src/views/Source/components/role/RoleInfo.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- User role - basic information -->
 <template>
   <el-form ref="roleForm" label-position="top" :model="form" :rules="rules" label-width="120px">
@@ -74,9 +92,12 @@ export default {
           form.value = { ...val };
           form.value.users = val.userList;
           oldForm.value = { ...form.value };
-          roleForm.value.clearValidate();
+          roleForm.value?.clearValidate();
           stateType.value = props.roleInfo.type;
         }
+      },
+      {
+        immediate: true,
       }
     );
     const rules = ref({
diff --git a/frontend/src/views/Source/components/role/RoleList.vue b/frontend/src/views/Source/components/role/RoleList.vue
index 062eaab..35ce4f6 100644
--- a/frontend/src/views/Source/components/role/RoleList.vue
+++ b/frontend/src/views/Source/components/role/RoleList.vue
@@ -1,3 +1,21 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
 <!-- role list -->
 <template>
   <div class="list-wrapper">
@@ -9,7 +27,7 @@
         </svg>
       </div>
     </div>
-    <ul v-if="roleList.length" class="role-list">
+    <ul v-if="roleList?.length" class="role-list">
       <li v-for="item in roleList" :key="item" :class="[activeRole === item ? 'active-item' : '']" class="role-list-item" @click="clickRole(item)">
         <div :class="[activeRole === item ? 'circle active-circle' : 'circle']">
           <div class="small-circle"></div>
@@ -64,7 +82,7 @@ export default {
       isAdding.value = false;
       let result = await api.getRoles(serverId);
       roleList.value = result.data;
-      if (!roleList.value.length) {
+      if (!roleList.value?.length) {
         emit('changeCurrRole', { id: '', name: 'NEW' });
         activeRole.value = '';
       } else {
diff --git a/frontend/src/views/Source/index.vue b/frontend/src/views/Source/index.vue
index 0076c66..e16e5bc 100644
--- a/frontend/src/views/Source/index.vue
+++ b/frontend/src/views/Source/index.vue
@@ -40,7 +40,7 @@
       <p class="more last">
         <span
           ><span class="more-title">{{ $t('sourcePage.storageNum') + ':' }}</span
-          >{{ countInfo.groupCount }}</span
+          >{{ countInfo.storageGroupCount }}</span
         >
         <span
           ><span class="more-title">{{ $t('sourcePage.entityNum') + ':' }}</span
@@ -48,7 +48,7 @@
         >
         <span
           ><span class="more-title">{{ $t('sourcePage.physicalNum') + ':' }}</span
-          >{{ countInfo.measurementCount }}</span
+          >{{ countInfo.monitorCount }}</span
         >
         <span
           ><span class="more-title">{{ $t('sourcePage.dataNum') + ':' }}</span
@@ -79,7 +79,8 @@
         <el-tab-pane :label="$t('sourcePage.dataModel')" name="d">
           <div class="tab-content">
             <el-button class="title" @click="goToAllModal()">{{ $t('sourcePage.showMore') }}</el-button>
-            <DataModal></DataModal>
+            <div class="tip">第一层最多展示多{{ showNum }}个模型,若需查看所有模型,点击查看更多</div>
+            <DataModal @show-num="onShowNum"></DataModal>
           </div>
         </el-tab-pane>
         <el-tab-pane :label="$t('sourcePage.accountPermitLabel')" name="a">
@@ -392,6 +393,17 @@
                 </template>
               </el-table-column>
             </el-table>
+            <div class="pagination">
+              <el-pagination
+                @current-change="currentChange"
+                v-model:currentPage="pagination.pageNum"
+                v-model:page-size="pagination.pageSize"
+                layout="total, prev, pager, next"
+                :total="groupTotal"
+                :hide-on-single-page="true"
+              >
+              </el-pagination>
+            </div>
           </div>
         </el-tab-pane>
       </el-tabs>
@@ -421,6 +433,7 @@ import {
   ElPopover,
   ElPopper,
   ElTooltip,
+  ElPagination,
 } from 'element-plus';
 // import { Close } from '@element-plus/icons';
 import NewSource from './components/newSource.vue';
@@ -462,6 +475,12 @@ export default {
     let canAuth = ref(false);
 
     let canAuthRole = ref(false);
+    let showNum = ref(0);
+
+    function onShowNum(value) {
+      showNum.value = value;
+    }
+
     const router = useRouter();
     let pathList = ref([
       { label: t('sourcePage.selectAlias'), value: 0 },
@@ -764,6 +783,19 @@ export default {
       }
     };
 
+    const pagination = reactive({
+      pageSize: 10,
+      pageNum: 1,
+    });
+    function currentChange() {
+      getGroupList();
+    }
+
+    let paginationAll = {
+      pagination,
+      currentChange,
+    };
+
     const savepermitAuth = () => {
       if (store.state.dataBaseM.privilegeListAll.indexOf('GRANT_USER_PRIVILEGE') < 0) {
         ElMessage.error(t(`sourcePage.noAuthTip`));
@@ -784,10 +816,10 @@ export default {
       axios.post(`/servers/${serverId.value}/users/${baseInfoForm.userName}/authorityPrivilege`, { ...reqObj }).then((rs) => {
         if (rs && rs.code == 0) {
           ElMessage.success(t('sourcePage.successEditPermit'));
-          store.dispatch('fetchAllPrivileges', {
-            serverId: serverId.value,
-            userName: baseInfoForm.userName,
-          });
+          //   store.dispatch('fetchAllPrivileges', {
+          //     serverId: serverId.value,
+          //     userName: baseInfoForm.userName,
+          //   });
         }
       });
     };
@@ -1213,10 +1245,10 @@ export default {
     };
 
     const getGroupList = () => {
-      axios.get(`/servers/${serverId.value}/storageGroups/info`, {}).then((res) => {
+      axios.get(`/servers/${serverId.value}/storageGroups/info`, { params: pagination }).then((res) => {
         if (res && res.code == 0) {
-          tableData.value = res.data;
-          groupTotal.value = (res.data && res.data.length) || 0;
+          tableData.value = res.data?.groupInfoList;
+          groupTotal.value = (res.data && res.data.groupCount) || 0;
           let temp = [];
           for (let i = 0; i < res.data.length; i++) {
             temp.push(res.data[i].groupName);
@@ -1590,6 +1622,9 @@ export default {
       permitPermissionListTemp,
       savepermitAuth,
       permitDialogRef,
+      showNum,
+      onShowNum,
+      ...paginationAll,
     };
   },
   components: {
@@ -1616,6 +1651,7 @@ export default {
     ElPopover,
     ElPopper,
     UserRole,
+    ElPagination,
     /* eslint-disable */
   },
 };
@@ -2001,7 +2037,7 @@ export default {
   .group-table {
     width: 100%;
     padding: 10px;
-    height: 100% !important;
+    height: calc(100% - 34px) !important;
     max-height: initial !important;
     &:deep(.el-table__body-wrapper) {
       height: calc(100% - 32px) !important;
@@ -2010,5 +2046,20 @@ export default {
       padding-left: 0 !important;
     }
   }
+  .pagination {
+    display: flex;
+    justify-content: flex-end;
+    margin-top: 10px;
+
+    // padding: 10px 0px;
+    .el-pagination {
+      padding: 4px 5px 0 5px;
+    }
+  }
+  .tip {
+    float: right;
+    font-size: 12px;
+    color: $danger-color;
+  }
 }
 </style>
diff --git a/frontend/src/views/SqlSerch/index.vue b/frontend/src/views/SqlSerch/index.vue
index dd2a1a0..d205fc5 100644
--- a/frontend/src/views/SqlSerch/index.vue
+++ b/frontend/src/views/SqlSerch/index.vue
@@ -66,13 +66,16 @@
                 <div class="table_top_border"></div>
                 <div class="tab_table" v-if="item && display">
                   <stand-table
+                    :key="key"
                     ref="standTable"
                     :column="item"
-                    :tableData="tableData.list[index]"
+                    :tableData="tableDataPagination[index]"
                     :lineHeight="5"
                     :celineHeight="5"
                     :maxHeight="divwerHeight - 78"
                     :pagination="pagination"
+                    :total="total[index]"
+                    :getList="getList(index)"
                     backColor="#E7EAF2"
                   >
                   </stand-table>
@@ -162,6 +165,7 @@ export default {
     let codemirror = ref(null);
     let tabelNum = ref(0);
     const standTable = ref(null);
+    let key = ref('1');
     let activeName = ref(0);
     let activeNameRight = ref('first');
     let runFlag = ref(true);
@@ -191,6 +195,29 @@ export default {
     const treeList = reactive({
       list: [],
     });
+    const total = computed(() => tableData.list.map((item) => item?.list?.length));
+    const pagination = reactive({
+      pageSize: 10,
+      pageNum: 1,
+    });
+    const pageNums = reactive([]);
+    function getList(index) {
+      return (value) => {
+        pageNums[index] = value;
+      };
+    }
+    const tableDataPagination = computed(() =>
+      tableData.list.map((item, index) => {
+        nextTick(() => {
+          key.value = Math.random() + Date.now() + '';
+        });
+        return {
+          ...item,
+          list: item?.list?.slice(((pageNums[index] || 1) - 1) * pagination.pageSize, (pageNums[index] || 1) * pagination.pageSize),
+        };
+      })
+    );
+
     function getFunction(val) {
       codemirror.value.onCmCodeChange(val);
     }
@@ -211,62 +238,66 @@ export default {
         divwerHeight.value = 400;
         timeNumber.value = Number(new Date());
         useElementResize(dividerRef, divwerHeight);
-        querySql(routeData.obj.connectionid, { sqls: codeArr, timestamp: timeNumber.value }).then((res) => {
-          activeName.value = 't0';
-          column.list = [];
-          tableData.list = [];
-          let lengthArry = [];
-          time.list = [];
-          line.list = [];
-          tabelNum.value = res.data.length;
-          res.data.forEach((item) => {
-            let length = [];
-            time.list.push(item.queryTime);
-            line.list.push(item.line);
-            if (item.metaDataList) {
-              column.list.push({
-                list: item.metaDataList.map((eleitem, index) => {
-                  return {
-                    label: eleitem,
-                    prop: `t${index}`,
-                    width: 'auto',
-                    fixed: index === 0 ? 'left' : index === item.metaDataList.length - 1 ? 'right' : false,
-                  };
-                }),
-              });
-            } else {
-              column.list.push(null);
-            }
-            if (item.valueList) {
-              tableData.list.push({
-                list: item.valueList.map((eleitem) => {
-                  const obj = {};
-                  for (let i = 0; i < eleitem.length; i++) {
-                    if (eleitem[i].length > length[i] || !length[i]) {
-                      length[i] = eleitem[i].length;
+        querySql(routeData.obj.connectionid, { sqls: codeArr, timestamp: timeNumber.value })
+          .then((res) => {
+            activeName.value = 't0';
+            column.list = [];
+            tableData.list = [];
+            let lengthArry = [];
+            time.list = [];
+            line.list = [];
+            tabelNum.value = res.data.length;
+            res.data.forEach((item) => {
+              let length = [];
+              time.list.push(item.queryTime);
+              line.list.push(item.line);
+              if (item.metaDataList) {
+                column.list.push({
+                  list: item.metaDataList.map((eleitem, index) => {
+                    return {
+                      label: eleitem,
+                      prop: `t${index}`,
+                      width: 'auto',
+                      fixed: index === 0 ? 'left' : index === item.metaDataList.length - 1 ? 'right' : false,
+                    };
+                  }),
+                });
+              } else {
+                column.list.push(null);
+              }
+              if (item.valueList) {
+                tableData.list.push({
+                  list: item.valueList.map((eleitem) => {
+                    const obj = {};
+                    for (let i = 0; i < eleitem.length; i++) {
+                      if (eleitem[i].length > length[i] || !length[i]) {
+                        length[i] = eleitem[i].length;
+                      }
+                      obj[`t${i}`] = eleitem[i];
                     }
-                    obj[`t${i}`] = eleitem[i];
-                  }
-                  return obj;
-                }),
-              });
-            } else {
-              tableData.list.push(null);
-            }
-            lengthArry.push(length);
+                    return obj;
+                  }),
+                });
+              } else {
+                tableData.list.push(null);
+              }
+              lengthArry.push(length);
+            });
+            // lengthArry.forEach((element, i) => {
+            //   element.forEach((item, index) => {
+            //     if (index === element.length - 1) {
+            //       return false;
+            //     }
+            //     column.list[i].list[index].width = column.list[i].list[index].label.length < item ? item * 12 : column.list[i].list[index].label.length * 12;
+            //   });
+            // });
+            display.value = true;
+            runFlag.value = true;
+            console.log(line.list);
+          })
+          .finally(() => {
+            runFlag.value = true;
           });
-          // lengthArry.forEach((element, i) => {
-          //   element.forEach((item, index) => {
-          //     if (index === element.length - 1) {
-          //       return false;
-          //     }
-          //     column.list[i].list[index].width = column.list[i].list[index].label.length < item ? item * 12 : column.list[i].list[index].label.length * 12;
-          //   });
-          // });
-          display.value = true;
-          runFlag.value = true;
-          console.log(line.list);
-        });
         setTimeout(() => {
           runFlag.value = true;
         }, 5000);
@@ -294,6 +325,7 @@ export default {
             type: 'success',
             message: t('device.savesuccess'),
           });
+          sqlName.value = null;
           centerDialogVisible.value = false;
           props.func.updateTree();
           let locationId = '';
@@ -416,6 +448,12 @@ export default {
       querySqlRun,
       deleteQuery,
       routeData,
+      total,
+      pagination,
+      getList,
+      pageNums,
+      tableDataPagination,
+      key,
     };
   },
   components: {
diff --git a/frontend/src/views/storage/index.vue b/frontend/src/views/storage/index.vue
index 6490324..ec9bbac 100644
--- a/frontend/src/views/storage/index.vue
+++ b/frontend/src/views/storage/index.vue
@@ -60,7 +60,7 @@
           <el-input v-model="searchVal" class="search-btn" suffix-icon="el-icon-search" :placeholder="$t('device.devicename')" @blur="search()" @keyup.enter="search()"></el-input>
         </div>
         <div class="device-list">
-          <el-table :data="tableData" style="width: 100%">
+          <el-table :data="tableData" style="width: 100%" v-loading="loading">
             <el-table-column show-overflow-tooltip prop="deviceName" :label="$t('device.devicename')" width="180" sortable>
               <template #default="scope">
                 <a class="to-entity" @click="goToEntity(scope)">{{ scope.row.deviceName }}</a>
@@ -102,10 +102,10 @@ export default {
   props: ['data', 'func'],
   setup(props) {
     const { t, locale } = useI18n();
-
     const router = useRouter();
     let baseInfo = ref({});
     let searchVal = ref(null);
+    const loading = ref(false);
     let tableData = ref([]);
     let currentPage = ref(1);
     const pageSize = ref(10);
@@ -184,6 +184,7 @@ export default {
      * groupname:storage name
      */
     const getDeviceList = () => {
+      loading.value = true;
       axios
         .get(`/servers/${router.currentRoute.value.params.serverid}/storageGroups/${router.currentRoute.value.params.groupname}/devices/info`, {
           params: {
@@ -200,6 +201,9 @@ export default {
             tableData.value = [];
             total.value = 0;
           }
+        })
+        .finally(() => {
+          loading.value = false;
         });
     };
     /**
@@ -270,6 +274,7 @@ export default {
       t,
       baseInfo,
       searchVal,
+      loading,
       tableData,
       currentPage,
       pageSize,
diff --git a/frontend/src/views/storage/newStorage.vue b/frontend/src/views/storage/newStorage.vue
index e79c105..88c320d 100644
--- a/frontend/src/views/storage/newStorage.vue
+++ b/frontend/src/views/storage/newStorage.vue
@@ -78,7 +78,7 @@ export default {
           trigger: 'blur',
         },
         {
-          pattern: /^[^.][a-zA-Z0-9_\u4e00-\u9fa5.]+$/,
+          pattern: /^(["'a-zA-Z0-9_\u4e00-\u9fa5]*)$/,
           message: () => {
             return t(`sourcePage.newUserErrorTip`);
           },
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index 1624e93..a2636dc 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -22,6 +22,8 @@ function resolve(dir) {
   return path.join(__dirname, dir);
 }
 
+const Version = new Date().getTime();
+
 module.exports = {
   chainWebpack: (config) => {
     config.resolve.alias.set('@', resolve('./src')).set('components', resolve('./src/components'));
@@ -30,15 +32,39 @@ module.exports = {
     loaderOptions: {
       sass: {
         prependData: `@use "@/styles/variables.scss" as *;`,
+        sassOptions: {
+          outputStyle: 'expanded',
+        },
       },
     },
+    extract: {
+      // 打包后css文件名称添加时间戳
+      filename: `css/[name].${Version}.css`,
+      chunkFilename: `css/chunk.[id].${Version}.css`,
+    },
+  },
+  configureWebpack: {
+    // 重点
+    // 输出重构 打包编译后的js文件名称,添加时间戳.
+    output: {
+      filename: `js/[name].${Version}.js`,
+      chunkFilename: `js/chunk.[id].${Version}.js`,
+    },
   },
+  productionSourceMap: false,
   devServer: {
     proxy: {
       '/.*': {
-        target: 'http://127.0.0.1:9090',
-        changeOrigin: true,
+        target: 'http://192.168.1.84:9090',
+        progress: false,
       },
+      // '/user': {
+      //     target: 'http://119.84.128.59:8079/api',
+      //     changeOrigin: true,
+      //     pathRewrite: {
+      //         '^/user': ''
+      //     }
+      // },
     },
   },
 };


[iotdb-web-workbench] 29/34: 新增监控指标展示功能

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 893c93408bce2de4663dc4560ba212473fbd681d
Author: loveher147 <lo...@qq.com>
AuthorDate: Mon May 30 15:19:22 2022 +0800

    新增监控指标展示功能
    
    - 解决大数据量场景的卡顿问题。
---
 .../iotdb/admin/controller/IotDBController.java    |  62 +++++---
 .../iotdb/admin/model/dto/DataModelDetailDTO.java  |   3 +-
 .../apache/iotdb/admin/model/vo/NodeTreeVO.java    |   9 ++
 .../apache/iotdb/admin/service/IotDBService.java   |  28 ++--
 .../iotdb/admin/service/impl/IotDBServiceImpl.java | 162 +++++++++++++++------
 5 files changed, 188 insertions(+), 76 deletions(-)

diff --git a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
index 8930913..67e4289 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/controller/IotDBController.java
@@ -98,12 +98,12 @@ public class IotDBController {
   @GetMapping("/dataModel/detail")
   @ApiOperation("Get IoTDB data model in detail")
   public BaseVO<DataModelVO> getDataModelDetail(
-          @PathVariable("serverId") Integer serverId,
-          @RequestParam(value = "path", required = false, defaultValue = "root") String path,
-          @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
-          @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
-          HttpServletRequest request)
-          throws BaseException {
+      @PathVariable("serverId") Integer serverId,
+      @RequestParam(value = "path", required = false, defaultValue = "root") String path,
+      @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
+      @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+      HttpServletRequest request)
+      throws BaseException {
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
     DataModelVO dataModelVO = iotDBService.getDataModelDetail(connection, path, pageSize, pageNum);
@@ -113,11 +113,11 @@ public class IotDBController {
   @GetMapping("/storageGroups/info")
   @ApiOperation("Get information of the storage group list")
   public BaseVO<GroupInfoVO> getAllStorageGroupsInfo(
-          @PathVariable("serverId") Integer serverId,
-          @RequestParam(value = "pageSize", required = false, defaultValue = "15") Integer pageSize,
-          @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
-          HttpServletRequest request)
-          throws BaseException {
+      @PathVariable("serverId") Integer serverId,
+      @RequestParam(value = "pageSize", required = false, defaultValue = "15") Integer pageSize,
+      @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+      HttpServletRequest request)
+      throws BaseException {
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
     List<String> groupNames = iotDBService.getAllStorageGroups(connection);
@@ -162,8 +162,6 @@ public class IotDBController {
     String host = connection.getHost();
     for (String groupName : groupNames) {
       StorageGroupVO storageGroupVO = new StorageGroupVO();
-      Integer id = groupService.getGroupId(host, groupName);
-      storageGroupVO.setGroupId(id);
       storageGroupVO.setGroupName(groupName);
       storageGroupVOList.add(storageGroupVO);
     }
@@ -193,9 +191,9 @@ public class IotDBController {
     Connection connection = connectionService.getById(serverId);
     Long ttl = groupDTO.getTtl();
     String ttlUnit = groupDTO.getTtlUnit();
-    checkTtl(ttl, ttlUnit);
     Integer groupId = groupDTO.getGroupId();
     groupDTO.setGroupName(groupName);
+
     List<String> groupNames = iotDBService.getAllStorageGroups(connection);
     if (groupId == null) {
       if (!groupNames.contains(groupDTO.getGroupName())) {
@@ -206,6 +204,7 @@ public class IotDBController {
       groupService.updateStorageGroupInfo(connection, groupDTO);
     }
     if (ttl != null && ttlUnit != null) {
+      checkTtl(ttl, ttlUnit);
       if (ttl >= 0) {
         Long times = switchTime(ttlUnit);
         iotDBService.saveGroupTtl(connection, groupName, ttl * times);
@@ -354,12 +353,19 @@ public class IotDBController {
   public BaseVO<NodeTreeVO> getDevicesTreeByGroup(
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
+      @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
+      @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
       HttpServletRequest request)
       throws BaseException {
     checkParameter(groupName);
     check(request, serverId);
     Connection connection = connectionService.getById(serverId);
-    NodeTreeVO deviceList = iotDBService.getDeviceList(connection, groupName);
+    NodeTreeVO deviceList = iotDBService.getDeviceList(connection, groupName, pageSize, pageNum);
+    if (deviceList == null) {
+      deviceList = new NodeTreeVO(groupName);
+    }
+    deviceList.setPageNum(pageNum);
+    deviceList.setPageSize(pageSize);
     return BaseVO.success("Get successfully", deviceList);
   }
 
@@ -461,8 +467,8 @@ public class IotDBController {
       @PathVariable("serverId") Integer serverId,
       @PathVariable("groupName") String groupName,
       @PathVariable("deviceName") String deviceName,
-      @RequestParam("pageSize") Integer pageSize,
-      @RequestParam("pageNum") Integer pageNum,
+      @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
+      @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
       @RequestParam(value = "keyword", required = false) String keyword,
       HttpServletRequest request)
       throws BaseException {
@@ -475,17 +481,26 @@ public class IotDBController {
     List<MeasurementVO> measurementVOList = new ArrayList<>();
     String host = connection.getHost();
     if (measurementDTOList != null) {
+      List<String> timeseriesList = new ArrayList<>();
+      for (MeasurementDTO measurementDTO : measurementDTOList) {
+        timeseriesList.add(measurementDTO.getTimeseries());
+      }
+      List<String> batchNewValue =
+          iotDBService.getBatchLastMeasurementValue(connection, timeseriesList);
+      List<String> batchDataCount =
+          iotDBService.getBatchDataCount(connection, deviceName, timeseriesList);
+      int index = 0;
       for (MeasurementDTO measurementDTO : measurementDTOList) {
         MeasurementVO measurementVO = new MeasurementVO();
         BeanUtils.copyProperties(measurementDTO, measurementVO);
         String description =
             measurementService.getDescription(host, measurementDTO.getTimeseries());
-        String newValue =
-            iotDBService.getLastMeasurementValue(connection, measurementDTO.getTimeseries());
-        Integer dataCount =
-            iotDBService.getOneDataCount(connection, deviceName, measurementDTO.getTimeseries());
-        measurementVO.setDataCount(dataCount);
-        measurementVO.setNewValue(newValue);
+        if (batchNewValue.size() != 0) {
+          measurementVO.setNewValue(batchNewValue.get(index));
+        }
+        if (batchDataCount.size() != 0) {
+          measurementVO.setDataCount(Integer.parseInt(batchDataCount.get(index)));
+        }
         measurementVO.setDescription(description);
         ObjectMapper mapper = new ObjectMapper();
         List<List<String>> tags = new ArrayList<>();
@@ -519,6 +534,7 @@ public class IotDBController {
           throw new BaseException(ErrorCode.GET_MSM_FAIL, ErrorCode.GET_MSM_FAIL_MSG);
         }
         measurementVOList.add(measurementVO);
+        index++;
       }
     }
     MeasuremtnInfoVO measuremtnInfoVO = new MeasuremtnInfoVO();
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
index b33cce1..58463b0 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/dto/DataModelDetailDTO.java
@@ -1,8 +1,9 @@
 package org.apache.iotdb.admin.model.dto;
 
-import lombok.Data;
 import org.apache.iotdb.admin.model.vo.DataModelVO;
 
+import lombok.Data;
+
 import java.io.Serializable;
 import java.util.List;
 
diff --git a/backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java b/backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java
index cfa4acc..46a476b 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/model/vo/NodeTreeVO.java
@@ -31,10 +31,19 @@ public class NodeTreeVO implements Serializable {
 
   private List<NodeTreeVO> children;
 
+  private Integer pageSize;
+
+  private Integer pageNum;
+
+  private Integer total;
+  //  private List<String> childrenName;
+
   public NodeTreeVO(String name) {
     this.name = name;
   }
 
+  public NodeTreeVO() {}
+
   public List<NodeTreeVO> initChildren() {
     if (children == null) {
       children = new ArrayList<>();
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
index 2a97117..4c5eff4 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/IotDBService.java
@@ -62,9 +62,6 @@ public interface IotDBService {
 
   void setIotDBRole(Connection connection, IotDBRole iotDBRole) throws BaseException;
 
-  DataModelVO getDataModelDetail(
-          Connection connection, String path, Integer pageSize, Integer pageNum) throws BaseException;
-
   UserRolesVO getRolesOfUser(Connection connection, String userName) throws BaseException;
 
   void userGrant(Connection connection, String userName, UserGrantDTO userGrantDTO)
@@ -122,7 +119,9 @@ public interface IotDBService {
 
   List<NodeTreeVO> getDeviceNodeTree(Connection connection, String groupName) throws BaseException;
 
-  NodeTreeVO getDeviceList(Connection connection, String groupName) throws BaseException;
+  NodeTreeVO getDeviceList(
+      Connection connection, String groupName, Integer pageSize, Integer pageNum)
+      throws BaseException;
 
   List<String> getDeviceParents(Connection connection, String groupName, String deviceName)
       throws BaseException;
@@ -155,6 +154,8 @@ public interface IotDBService {
       Connection connection, String userOrRole, String name, PrivilegeInfoDTO privilegeInfoDTO)
       throws BaseException;
 
+  public List<QueryMetricsVO> getSlowQueryMetricsData();
+
   RecordVO getRecords(
       Connection connection, String deviceName, String timeseriesName, String dataType)
       throws BaseException;
@@ -164,9 +165,7 @@ public interface IotDBService {
 
   void updatePwd(Connection connection, IotDBUser iotDBUser) throws BaseException;
 
-  void stopQuery(Integer serverId, Long timestamp) throws BaseException;
-
-  QueryInfoDTO getQueryInfoListByQueryClassificationId(
+  public QueryInfoDTO getQueryInfoListByQueryClassificationId(
       Connection connection,
       Integer queryClassificationId,
       Integer pageSize,
@@ -177,10 +176,19 @@ public interface IotDBService {
       Integer executionResult)
       throws BaseException;
 
-  MetricsDataForDiagramVO getMetricDataByMetricId(Connection connection, Integer metricId)
+  public List<QueryMetricsVO> getTopQueryMetricsData();
+
+  public MetricsDataForDiagramVO getMetricDataByMetricId(Connection connection, Integer metricId)
       throws BaseException;
 
-  List<QueryMetricsVO> getTopQueryMetricsData();
+  void stopQuery(Integer serverId, Long timestamp) throws BaseException;
+
+  DataModelVO getDataModelDetail(
+      Connection connection, String path, Integer pageSize, Integer pageNum) throws BaseException;
+
+  List<String> getBatchLastMeasurementValue(Connection connection, List<String> timeseriesList)
+      throws BaseException;
 
-  List<QueryMetricsVO> getSlowQueryMetricsData();
+  List<String> getBatchDataCount(
+      Connection connection, String deviceName, List<String> timeseriesList) throws BaseException;
 }
diff --git a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
index 4318825..c174d0e 100644
--- a/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
+++ b/backend/src/main/java/org/apache/iotdb/admin/service/impl/IotDBServiceImpl.java
@@ -151,10 +151,11 @@ public class IotDBServiceImpl implements IotDBService {
       sessionPool = getSessionPool(connection);
       DataModelVO root = new DataModelVO(path);
       setNodeInfo(root, sessionPool, path);
-      List<DataModelVO> childrenDataModel = getChildrenDataModel(root, path, sessionPool);
+      List<DataModelVO> childrenDataModel = getChildrenDataModel(root, path, sessionPool, 20);
       root.setChildren(childrenDataModel);
       root.setGroupCount(path.equals("root") ? getGroupCount(sessionPool) : null);
       root.setPath(path);
+      root.setShowNum(20);
       return root;
     } finally {
       closeSessionPool(sessionPool);
@@ -162,15 +163,21 @@ public class IotDBServiceImpl implements IotDBService {
   }
 
   private List<DataModelVO> getChildrenDataModel(
-      DataModelVO root, String path, SessionPool sessionPool) throws BaseException {
+      DataModelVO root, String path, SessionPool sessionPool, Integer showNum)
+      throws BaseException {
     Set<String> childrenNode = getChildrenNode(path, sessionPool);
     if (childrenNode == null) {
       return null;
     }
+    List<String> childrenNodeList = new ArrayList<>(childrenNode);
+    List<String> childrenNodeSubList = new ArrayList<>();
+    if (childrenNodeList.size() > showNum) {
+      childrenNodeSubList = childrenNodeList.subList(0, showNum);
+    } else {
+      childrenNodeSubList = childrenNodeList;
+    }
     List<DataModelVO> childrenlist = new ArrayList<>();
-
-    // TODO: 大量IO
-    for (String child : childrenNode) {
+    for (String child : childrenNodeSubList) {
       DataModelVO childNode = new DataModelVO(child);
       setNodeInfo(childNode, sessionPool, path + "." + child);
       childrenlist.add(childNode);
@@ -561,7 +568,15 @@ public class IotDBServiceImpl implements IotDBService {
       Connection connection, String deviceName, Integer pageSize, Integer pageNum, String keyword)
       throws BaseException {
     SessionPool sessionPool = getSessionPool(connection);
+    String queryCountSql = "count timeseries " + deviceName;
+    String s = executeQueryOneValue(sessionPool, queryCountSql);
+    int size = Integer.parseInt(s);
     String sql = "show timeseries " + deviceName;
+    int pageStart = pageNum == 1 ? 0 : (pageNum - 1) * pageSize;
+    int pageEnd = size < pageNum * pageSize ? size : pageNum * pageSize;
+    if (size > pageStart) {
+      sql = "show timeseries " + deviceName + " limit " + pageSize + " offset " + pageStart;
+    }
     SessionDataSetWrapper sessionDataSetWrapper = null;
     try {
       sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
@@ -582,37 +597,39 @@ public class IotDBServiceImpl implements IotDBService {
             } else {
               continue;
             }
-            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-              MeasurementDTO t = new MeasurementDTO();
-              List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-              for (int i = 0; i < fields.size(); i++) {
-                Field field =
-                    MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
-                field.setAccessible(true);
-                field.set(t, fields.get(i).toString());
-              }
-              results.add(t);
+            //            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum)
+            // {
+            MeasurementDTO t = new MeasurementDTO();
+            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+            for (int i = 0; i < fields.size(); i++) {
+              Field field =
+                  MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+              field.setAccessible(true);
+              field.set(t, fields.get(i).toString());
             }
+            results.add(t);
+            //            }
           } else {
             count++;
-            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum) {
-              MeasurementDTO t = new MeasurementDTO();
-              List<String> columnNames = sessionDataSetWrapper.getColumnNames();
-              for (int i = 0; i < fields.size(); i++) {
-                Field field =
-                    MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
-                field.setAccessible(true);
-                field.set(t, fields.get(i).toString());
-              }
-              results.add(t);
+            //            if (count >= pageSize * (pageNum - 1) + 1 && count <= pageSize * pageNum)
+            // {
+            MeasurementDTO t = new MeasurementDTO();
+            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
+            for (int i = 0; i < fields.size(); i++) {
+              Field field =
+                  MeasurementDTO.class.getDeclaredField(columnNames.get(i).replaceAll(" ", ""));
+              field.setAccessible(true);
+              field.set(t, fields.get(i).toString());
             }
+            results.add(t);
+            //            }
           }
         }
       }
       CountDTO countDTO = new CountDTO();
       countDTO.setObjects(results);
-      countDTO.setTotalCount(count);
-      Integer totalPage = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
+      countDTO.setTotalCount(size);
+      Integer totalPage = size % pageSize == 0 ? size / pageSize : size / pageSize + 1;
       countDTO.setTotalPage(totalPage);
       return countDTO;
     } catch (IoTDBConnectionException e) {
@@ -767,7 +784,7 @@ public class IotDBServiceImpl implements IotDBService {
 
   @Override
   public DataModelVO getDataModelDetail(
-          Connection connection, String path, Integer pageSize, Integer pageNum) throws BaseException {
+      Connection connection, String path, Integer pageSize, Integer pageNum) throws BaseException {
     SessionPool sessionPool = null;
     try {
       sessionPool = getSessionPool(connection);
@@ -775,9 +792,9 @@ public class IotDBServiceImpl implements IotDBService {
       setNodeInfo(root, sessionPool, path);
       List<DataModelVO> childrenDataModel = null;
       DataModelDetailDTO childrenDataModelDetail =
-              getChildrenDataModelDetail(root, path, sessionPool, pageSize, pageNum);
+          getChildrenDataModelDetail(root, path, sessionPool, pageSize, pageNum);
       childrenDataModel =
-              childrenDataModelDetail == null ? null : childrenDataModelDetail.getDataModelVOList();
+          childrenDataModelDetail == null ? null : childrenDataModelDetail.getDataModelVOList();
       if (childrenDataModelDetail != null) {
         root.setPageNum(childrenDataModelDetail.getPageNum());
         root.setPageSize(childrenDataModelDetail.getPageSize());
@@ -785,9 +802,9 @@ public class IotDBServiceImpl implements IotDBService {
       }
       root.setChildren(childrenDataModel);
       root.setTotalSonNodeCount(
-              getChildrenNode(path, sessionPool) == null
-                      ? 0
-                      : getChildrenNode(path, sessionPool).size());
+          getChildrenNode(path, sessionPool) == null
+              ? 0
+              : getChildrenNode(path, sessionPool).size());
       root.setGroupCount(path.equals("root") ? getGroupCount(sessionPool) : null);
       root.setPath(path);
       return root;
@@ -796,9 +813,57 @@ public class IotDBServiceImpl implements IotDBService {
     }
   }
 
+  @Override
+  public List<String> getBatchLastMeasurementValue(
+      Connection connection, List<String> timeseriesList) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<Integer> indexList = new ArrayList<>();
+    for (String timeseries : timeseriesList) {
+      indexList.add(timeseries.lastIndexOf("."));
+    }
+    String sql = "select ";
+    for (int i = 0; i < timeseriesList.size(); i++) {
+      sql += "last_value(" + timeseriesList.get(i).substring(indexList.get(i) + 1) + ")" + ", ";
+    }
+    sql = sql.substring(0, sql.length() - 2);
+    sql += " from ";
+    sql += timeseriesList.get(0).substring(0, indexList.get(0));
+    List<String> values;
+    try {
+      values = executeQueryOneLine(sessionPool, sql);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+    return values;
+  }
+
+  @Override
+  public List<String> getBatchDataCount(
+      Connection connection, String deviceName, List<String> timeseriesList) throws BaseException {
+    SessionPool sessionPool = getSessionPool(connection);
+    List<Integer> indexList = new ArrayList<>();
+    for (String timeseries : timeseriesList) {
+      indexList.add(timeseries.lastIndexOf("."));
+    }
+    String sql = "select ";
+    for (int i = 0; i < timeseriesList.size(); i++) {
+      sql += "count(" + timeseriesList.get(i).substring(indexList.get(i) + 1) + ")" + ", ";
+    }
+    sql = sql.substring(0, sql.length() - 2);
+    sql += " from ";
+    sql += timeseriesList.get(0).substring(0, indexList.get(0));
+    List<String> values;
+    try {
+      values = executeQueryOneLine(sessionPool, sql);
+    } finally {
+      closeSessionPool(sessionPool);
+    }
+    return values;
+  }
+
   private DataModelDetailDTO getChildrenDataModelDetail(
-          DataModelVO root, String path, SessionPool sessionPool, Integer pageSize, Integer pageNum)
-          throws BaseException {
+      DataModelVO root, String path, SessionPool sessionPool, Integer pageSize, Integer pageNum)
+      throws BaseException {
     Set<String> childrenNode = getChildrenNode(path, sessionPool);
     if (childrenNode == null) {
       return null;
@@ -1633,9 +1698,7 @@ public class IotDBServiceImpl implements IotDBService {
 
   private void upsertMeasurementAlias(SessionPool sessionPool, String timeseries, String alias)
       throws BaseException {
-    // 需要改为" "值。
-    if (alias == null || "null".equals(alias)) {
-      //    if (alias == null || "null".equals(alias) || StringUtils.isBlank(alias)) {
+    if (alias == null || "null".equals(alias) || StringUtils.isBlank(alias)) {
       return;
     }
     if (alias.matches("^as$") || alias.matches("^\\d+$") || alias.matches("^like$")) {
@@ -1850,7 +1913,9 @@ public class IotDBServiceImpl implements IotDBService {
   }
 
   @Override
-  public NodeTreeVO getDeviceList(Connection connection, String groupName) throws BaseException {
+  public NodeTreeVO getDeviceList(
+      Connection connection, String groupName, Integer pageSize, Integer pageNum)
+      throws BaseException {
     SessionPool sessionPool = null;
     try {
       sessionPool = getSessionPool(connection);
@@ -1863,7 +1928,9 @@ public class IotDBServiceImpl implements IotDBService {
         ancestryName = groupName;
       }
       NodeTreeVO ancestry = new NodeTreeVO(ancestryName);
-      assembleDeviceList(ancestry, groupName, sessionPool);
+      assembleDeviceList(ancestry, groupName, sessionPool, pageSize, pageNum);
+      ancestry.setName(groupName);
+      ancestry.setTotal(devices.size());
       return ancestry;
     } finally {
       closeSessionPool(sessionPool);
@@ -1891,17 +1958,28 @@ public class IotDBServiceImpl implements IotDBService {
     }
   }
 
-  private void assembleDeviceList(NodeTreeVO node, String deviceName, SessionPool sessionPool)
+  private void assembleDeviceList(
+      NodeTreeVO node,
+      String deviceName,
+      SessionPool sessionPool,
+      Integer pageSize,
+      Integer pageNum)
       throws BaseException {
     List<String> descendants = findDescendants(deviceName, sessionPool);
     if (descendants.size() == 0) {
       return;
     }
     List<String> children = findChildren(descendants);
+    int size = children.size();
+    int pageStart = pageNum == 1 ? 0 : (pageNum - 1) * pageSize;
+    int pageEnd = size < pageNum * pageSize ? size : pageNum * pageSize;
+    if (size > pageStart) {
+      children = children.subList(pageStart, pageEnd);
+    }
     for (String child : children) {
       NodeTreeVO childNode = new NodeTreeVO(child);
       node.initChildren().add(childNode);
-      assembleDeviceList(childNode, child, sessionPool);
+      //      assembleDeviceList(childNode, child, sessionPool);
     }
   }
 


[iotdb-web-workbench] 14/34: Renamed Workflows

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit f7adfb0a907869616deaeb441a2776c8cef10502
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat Sep 11 15:11:05 2021 +0200

    Renamed Workflows
---
 .github/workflows/default.yml  | 2 +-
 .github/workflows/frontend.yml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml
index d0b7938..60802e7 100644
--- a/.github/workflows/default.yml
+++ b/.github/workflows/default.yml
@@ -1,7 +1,7 @@
 # This workflow will build a Java project with Maven
 # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
 
-name: Main Mac and Linux
+name: Backend
 
 on:
   push:
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 0022604..2c19095 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -1,7 +1,7 @@
 # This workflow will build a Java project with Maven
 # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
 
-name: Main Mac and Linux
+name: Frontend
 
 on:
   push:


[iotdb-web-workbench] 26/34: Update documents. (#11)

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 161c24e294afa7f626ed59bef66d018150cf5ccc
Author: zhengqiang-cisdi <lo...@qq.com>
AuthorDate: Thu Mar 3 17:22:15 2022 +0800

    Update documents. (#11)
    
    * Update documents.
    
    Co-authored-by: wenjin <12...@qq.com>
    Co-authored-by: julian <j....@pragmaticminds.de>
    Co-authored-by: haungrui777 <hu...@163.com>
    Co-authored-by: qhy <97...@qq.com>
    Co-authored-by: qhy <qh...@163.com>
    Co-authored-by: benqhy <85...@users.noreply.github.com>
    Co-authored-by: wangdan-cisdi <47...@qq.com>
    Co-authored-by: shuhong.liu <01...@cisdi.com.cn>
    Co-authored-by: curiosityLiu <81...@qq.com>
    Co-authored-by: Xiangdong Huang <hx...@apache.org>
---
 README.md                                          |  22 +++++++-
 backend/doc/deploy.md                              |  21 +++++---
 backend/doc/image/login.png                        | Bin 0 -> 758774 bytes
 backend/doc/image/proxyConfig.png                  | Bin 0 -> 6257 bytes
 backend/doc/image/spotless.png                     | Bin 0 -> 40447 bytes
 backend/doc/image/welcome.PNG                      | Bin 26247 -> 40692 bytes
 backend/doc/intro.md                               |  28 +++++++---
 backend/doc/maven.md                               |   2 +-
 backend/doc/rest.md                                |  16 +++++-
 backend/doc/rule.md                                |  57 ++++++++++++++++++---
 backend/doc/swagger.md                             |   2 +-
 backend/doc/validate.md                            |   7 +--
 .../src/main/resources/application-dev.properties  |   2 +-
 frontend/README.md                                 |   6 +++
 frontend/vue.config.js                             |   2 +-
 15 files changed, 137 insertions(+), 28 deletions(-)

diff --git a/README.md b/README.md
index c2a9c75..6624231 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,25 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
-[![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/loveher147/iotdb-admin/releases)
 ![](https://img.shields.io/badge/java--language-1.8-blue.svg)
 
 # IoTDB-Workbench
diff --git a/backend/doc/deploy.md b/backend/doc/deploy.md
index c608a17..f6a3a0e 100644
--- a/backend/doc/deploy.md
+++ b/backend/doc/deploy.md
@@ -23,7 +23,9 @@
 
 ## 后端部署
 
-1 通过backend/src/main/resources/application-xxx.properties文件配置项目,注意修改数据源的路径。
+1 通过backend/src/main/resources/application.properties指定配置文件为prod:`spring.profiles.active=prod`
+
+在application-prod.properties中可按照自己需求修改端口号,并注意修改数据源的路径:
 
 ![](image/配置文件.PNG)
 
@@ -31,10 +33,12 @@
 
 ![](image/打包.png)
 
-3 打包之后,将jar包上传到指定服务器并运行。  
+3 打包之后,将jar包上传到你的服务器并运行:  
 
 首先请确定服务器上安装了sqlite3(一般Linux系统自带sqlite3,如果没有请安装)。  
+
 通过如下命令将jar包挂载到后台运行:  
+
 nohup java -jar xxx.jar >/dev/null 2>&1 &
 
 至此后端部署完成。
@@ -55,10 +59,15 @@ yum install -y nginx
 
 ![](image/nginx配置文件.png)
 
-黄框内容为监听端口号配置;  
-红框内容以“/”映射前端资源文件,请指定为你的dist文件路径;  
-绿框以“/api”映射后台服务地址,与application-xxx.properties文件中配置的端口号和上下文根保持一致;  
-如果你需要多个服务则需配置多个server
+其中:
+
+- 黄框内容为监听端口号配置;  
+
+- 红框内容以“/”映射前端资源文件,请指定为你的dist文件夹路径(dist文件夹是由前端打包产生的);  
+
+- 绿框以“/api”映射后台服务地址,其端口号与application-prod.properties文件中配置的端口号保持一致 。
+
+如果你需要多个服务则需配置多个server。
 
 4 保存配置后,命令行输入nginx启动nginx
 
diff --git a/backend/doc/image/login.png b/backend/doc/image/login.png
new file mode 100644
index 0000000..28fe2bb
Binary files /dev/null and b/backend/doc/image/login.png differ
diff --git a/backend/doc/image/proxyConfig.png b/backend/doc/image/proxyConfig.png
new file mode 100644
index 0000000..ab4484f
Binary files /dev/null and b/backend/doc/image/proxyConfig.png differ
diff --git a/backend/doc/image/spotless.png b/backend/doc/image/spotless.png
new file mode 100644
index 0000000..513018c
Binary files /dev/null and b/backend/doc/image/spotless.png differ
diff --git a/backend/doc/image/welcome.PNG b/backend/doc/image/welcome.PNG
index 1eac27b..b446d4c 100644
Binary files a/backend/doc/image/welcome.PNG and b/backend/doc/image/welcome.PNG differ
diff --git a/backend/doc/intro.md b/backend/doc/intro.md
index 7984784..a28f633 100644
--- a/backend/doc/intro.md
+++ b/backend/doc/intro.md
@@ -44,14 +44,30 @@
 
 由于是开源软件,使用的所有库都应该是maven公有仓库能找的,满足轻量、稳定2个特性。
 
-## 快速启动
+## 启动后端
 
-项目提供maven、gradle两种构建工具,以maven为例启动项目:  
-首先通过IntelliJ IDEA打开本项目,右键点击pom.xml,点击Add as Maven Project导入项目相关依赖。
+项目提供maven、gradle两种构建工具,以maven为例启动项目:  
+
+首先通过IntelliJ IDEA打开本项目,右键点击pom.xml,点击Add as Maven Project导入项目相关依赖。
 ![](image/pom.PNG)  
+
 导入完成后启动AdminApplication项目,启动成功后你应该能看到如下界面。  
+
 ![](image/启动成功.PNG)  
-接着,你可以通过浏览器访问127.0.0.1:8080/api/,看到如下页面则代表后端启动成功。
+
+接着,你可以通过浏览器访问127.0.0.1:9090/api/,看到如下页面则代表后端启动成功。
 ![](image/welcome.PNG)  
-具体部署步骤请参考[部署文档](deploy.md)  
-本系统默认登录用户为root,密码为123456。  
\ No newline at end of file
+
+## 启动前端
+
+在启动前端之前请先确保frontend/vue.config.js中配置的proxy的目标地址为后端服务的ip+端口,如图:
+
+![](image/proxyConfig.png)
+
+进入frontend目录,命令行输入`npm run serve`启动前端(具体步骤请参考[前端文档](../../frontend/README.md) ),启动成功后通过浏览器访问127.0.0.1:8080,你将进入登陆界面:
+
+![](image/login.png)
+
+输入默认账号root、密码123456,点击登录,你就可以使用本系统了。
+
+如果你想将本项目部署到服务器上,请参考[部署文档](deploy.md) 。
\ No newline at end of file
diff --git a/backend/doc/maven.md b/backend/doc/maven.md
index 6b03b5a..1ace60e 100644
--- a/backend/doc/maven.md
+++ b/backend/doc/maven.md
@@ -25,7 +25,7 @@
 
 ## Maven 安装
 
-无论你是mac电脑还是window电脑,都可以到Maven官网直接下载[Maven 3.8.2](https://dlcdn.apache.org/maven/maven-3/3.8.2/binaries/apache-maven-3.8.2-bin.tar.gz)
+无论你是mac电脑还是window电脑,都可以到[Maven官网](https://archive.apache.org/dist/maven/maven-3/)直接下载,选择3.3.9或以上版本即可。
 
 然后找一个目录解压,路径最好不要有中文,然后在Idea中引用该Maven。在下图中找到"Maven Setting"
 
diff --git a/backend/doc/rest.md b/backend/doc/rest.md
index 0b25e53..8481fa1 100644
--- a/backend/doc/rest.md
+++ b/backend/doc/rest.md
@@ -21,11 +21,23 @@
 
 # 接口规范
 
-有时候,会犯一些错误,例如直接会定义如下的一些接口:
+有时候,我们可能直接会定义如下的一些接口:
 
 - /user/delete
 - /user/add
 - /user/update
 - /user/select
 
-这样的接口太数据库化,读起来虽然比较容易
+但这样的接口太数据库化,读起来虽然比较容易。
+
+## RESTful API
+
+这里建议使用RESTful风格的API,例如:
+
+- 查询 /user?name=tom GET
+- 详情 /user/1 GET
+- 创建 /user POST
+- 修改 /user/1 PUT
+- 删除 /user/1 DELETE 
+
+它是一种互联网应用程序的API设计理念:URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作。
diff --git a/backend/doc/rule.md b/backend/doc/rule.md
index 31b6225..7da684c 100644
--- a/backend/doc/rule.md
+++ b/backend/doc/rule.md
@@ -25,13 +25,58 @@
 
 需使用idea(版本2018.3+)安装插件,自动检查代码规范,具体操作步骤如下:
 
-1、Mac:IntelliJ IDEA -> Preferences -> Plugins -> Installed plugins from Disk -> 选择doc目录下的code-guidelines进行安装
-   Windows:File -> Settings -> Plugins -> Installed plugins from Disk -> 选择doc目录下的code-guidelines进行安装
+## 本地安装Alibaba Java Coding Guidelines
+
+1、安装
+
+- Mac:IntelliJ IDEA -> Preferences -> Plugins -> Installed plugins from Disk -> 选择doc目录下的code-guidelines进行安装
+- Windows:File -> Settings -> Plugins -> Installed plugins from Disk -> 选择doc目录下的code-guidelines进行安装
+
+2、重启idea
+
+## 在线安装Alibaba Java Coding Guidelines
+
+1、安装
+
+- Mac:IntelliJ IDEA -> Preferences -> Plugins -> Browse repositories -> 搜索Alibaba Java Coding Guidelines -> 直接install进行在线安装
+- Windows:File -> Settings -> Plugins -> Marketplace -> 搜索Alibaba Java Coding Guidelines -> 直接install进行在线安装
 
 2、重启idea
 
-##在线安装java规范checkstyle
-1、Mac:IntelliJ IDEA -> Preferences -> Plugins -> Browse repositories -> 搜索Alibaba Java Coding Guidelines -> 直接install进行在线安装
-   Windows:File -> Settings -> Plugins -> Marketplace -> 搜索Alibaba Java Coding Guidelines -> 直接install进行在线安装
+# spotless插件规范代码
+
+另外,我们还使用了spotless这款插件来规范代码。在backend/pom.xml中添加spotless插件:
+
+```
+<plugin>
+  <groupId>com.diffplug.spotless</groupId>
+  <artifactId>spotless-maven-plugin</artifactId>
+  <version>${spotless.version}</version>
+  <configuration>
+    <java>
+      <googleJavaFormat>
+        <version>1.7</version>
+        <style>GOOGLE</style>
+      </googleJavaFormat>
+      <importOrder>
+        <order>org.apache.iotdb,,javax,java,\#</order>
+      </importOrder>
+      <removeUnusedImports/>
+    </java>
+    <lineEndings>UNIX</lineEndings>
+  </configuration>
+  <executions>
+    <execution>
+      <id>spotless-check</id>
+      <phase>validate</phase>
+      <goals>
+        <goal>check</goal>
+      </goals>
+    </execution>
+  </executions>
+</plugin>
+```
+
+添加成功后我们可以看见在Maven出现了spotless插件,点击check可检查代码是否满足规范,点击apply可自动格式化代码使其满足规范。此外,在Maven打包时会自动check,如果没通过,打包就不会成功。
 
-2、重启idea
\ No newline at end of file
+![](image/spotless.png)
diff --git a/backend/doc/swagger.md b/backend/doc/swagger.md
index 37e9b0d..7ca7a42 100644
--- a/backend/doc/swagger.md
+++ b/backend/doc/swagger.md
@@ -44,7 +44,7 @@ swagger在前后端联调开发中,启动非常重要的作用,如下:
 
 ## 网页地址
 
-你可以通过http://localhost:8080/swagger-ui.html这个地址获得接口信息。
+你可以通过 http://localhost:9090/api/swagger-ui.html 这个地址获得接口信息。
 
 ## 生产环境、测试环境、开发环境配置
 
diff --git a/backend/doc/validate.md b/backend/doc/validate.md
index ceb0f5b..0c90d74 100644
--- a/backend/doc/validate.md
+++ b/backend/doc/validate.md
@@ -26,16 +26,17 @@
 1. 直接写在controller中,有时候,特别是新人,98%会忘记写参数验证
 2. 切面,注解形式的参数验证
 
-我们认为第2种方式会好于第一种方式,所以我们使用了成熟的hibernat验证框架对参数进行验证
+我们认为第2种方式会好于第一种方式,所以我们使用了成熟的hibernate验证框架对参数进行验证
 
-## hibernat参数验证配置
+## hibernate参数验证配置
 
 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码有几个麻烦:
 
 1. 验证代码繁琐,重复劳动
 2. 方法内代码显得冗长
 3. 每次要看哪些参数验证是否完整,需要去翻阅验证逻辑代码
-hibernate validator(官方文档)提供了一套比较完善、便捷的验证实现方式。
+  
+[hibernate validator](http://hibernate.org/validator/documentation/) 提供了一套比较完善、便捷的验证实现方式。
 
 spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依赖。
 
diff --git a/backend/src/main/resources/application-dev.properties b/backend/src/main/resources/application-dev.properties
index b547fb9..bd75be1 100644
--- a/backend/src/main/resources/application-dev.properties
+++ b/backend/src/main/resources/application-dev.properties
@@ -21,7 +21,7 @@
 logging.config=classpath:log4j2.xml
 
 # Set port and context path
-server.port=8080
+server.port=9090
 server.servlet.context-path=/api
 
 # The following data source configuration method will cause data loss after the project is repackaged.
diff --git a/frontend/README.md b/frontend/README.md
index 260c866..527092b 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -46,6 +46,12 @@ npm run serve
 npm run test:unit
 ```
 
+## 打包
+
+```
+npm run build
+```
+
 ## 技术栈
 
 **Vue3.0** + **Scss**(css modules) + **Element Plus** + **Eslint,Stylelint,Prettier,Husky** 统一代码风格与规范。
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index a1e6b53..1624e93 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -36,7 +36,7 @@ module.exports = {
   devServer: {
     proxy: {
       '/.*': {
-        target: 'http://119.84.128.59:8079',
+        target: 'http://127.0.0.1:9090',
         changeOrigin: true,
       },
     },


[iotdb-web-workbench] 19/34: Fix link in readme

Posted by qi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb-web-workbench.git

commit 5dc612edb17ff85941b961da3f65e072f1e77067
Author: Haonan <hh...@outlook.com>
AuthorDate: Mon Sep 27 16:35:49 2021 +0800

    Fix link in readme
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index adf58fc..3a5cfff 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
 
 -->
 
-[English](./README.md) | [中文](./README_ZH.md)
+[English](./README.md) | [中文](./README_zh.md)
 
 # Overview