zhangliang2 3 年之前
父节点
当前提交
e35fa84d03
共有 36 个文件被更改,包括 3500 次插入1018 次删除
  1. 5 1
      src/api/algorithmsLibrary.js
  2. 7 2
      src/api/common.js
  3. 3 1
      src/api/index.js
  4. 30 0
      src/api/systemManagement.js
  5. 23 1
      src/api/workManagement.js
  6. 45 12
      src/axios/filter.js
  7. 30 1
      src/lib/util.js
  8. 1 1
      src/router/filter.js
  9. 10 3
      src/router/index.js
  10. 88 79
      src/router/systemManagement.js
  11. 74 18
      src/router/workManagement.js
  12. 2 1
      src/store/index.js
  13. 18 6
      src/views/algorithmsLibrary/algorithmsLibraryList.vue
  14. 4 1
      src/views/algorithmsLibrary/exportAlgorithms.vue
  15. 121 18
      src/views/algorithmsLibrary/gitAlgorithms.vue
  16. 23 2
      src/views/index.vue
  17. 11 39
      src/views/login.vue
  18. 8 0
      src/views/mainPage.vue
  19. 26 9
      src/views/modelLibrary/components/canvasVehicleConfiguration.vue
  20. 1 1
      src/views/page/breadCrumb.vue
  21. 156 64
      src/views/page/pageMenu.vue
  22. 150 58
      src/views/systemManagement/accountManagement.vue
  23. 97 129
      src/views/systemManagement/addAccount.vue
  24. 111 46
      src/views/systemManagement/clusteringDetail.vue
  25. 127 35
      src/views/systemManagement/clusteringManagement.vue
  26. 327 0
      src/views/systemManagement/editAccount.vue
  27. 69 53
      src/views/systemManagement/parameterDetail.vue
  28. 27 20
      src/views/systemManagement/parameterManagement.vue
  29. 514 0
      src/views/workManagement/autoRunProjectDetail.vue
  30. 391 0
      src/views/workManagement/autoRunProjectList.vue
  31. 390 0
      src/views/workManagement/autoRunSubProjectList.vue
  32. 86 24
      src/views/workManagement/evaluationReport.vue
  33. 46 22
      src/views/workManagement/manualRunProjectDetail.vue
  34. 194 179
      src/views/workManagement/manualRunProjectList.vue
  35. 255 189
      src/views/workManagement/projectInfo.vue
  36. 30 3
      src/views/workManagement/taskInfo.vue

+ 5 - 1
src/api/algorithmsLibrary.js

@@ -14,6 +14,8 @@ const getProgress = basePart + '/file/getProgress'; // 获取上传进度接口
 
 const selectAlgoPlatformList = basePart + '/algorithm/selectAlgoPlatformList'   //算法平台列表
 
+const testConnection = basePart + '/algorithm/testConnection'
+
 export default {
     selectSharedAlgorithmList,
     selectAlgorithmList,
@@ -25,5 +27,7 @@ export default {
     selectDetailsById,
     getProgress,
 
-    selectAlgoPlatformList
+    selectAlgoPlatformList,
+
+    testConnection
 }

+ 7 - 2
src/api/common.js

@@ -13,6 +13,7 @@ const uploadProcessBar = basePart + '/simulation/resource/common/minio/uploadPro
 const createMultipartUpload = basePart + '/simulation/resource/common/minio/createMultipartUpload'; // 分片上传-请求上传地址
 const completeMultipartUpload = basePart + '/simulation/resource/common/minio/completeMultipartUpload'; // 分片上传-文件合并地址
 
+const getMyMenuTree = '/simulation/resource/server/menu/getMyMenuTree';  //获取左侧菜单
 
 export default {
     single,
@@ -27,8 +28,12 @@ export default {
     uploadProcessBar,
 
     createMultipartUpload,
-    completeMultipartUpload
+    completeMultipartUpload,
+
+    getMyMenuTree
 }
 
 //10.15.12.74:7001/simulation/oauth/client/sign/single?code=1001&ticket=1001
-//10.12.10.74:7001/simulation/oauth/client/sign/single?code=1001&ticket=1001
+//10.12.10.70/simulation/oauth/client/sign/single?code=1002&ticket=1002
+//http://10.12.10.70/simulation/oauth/client/sign/entry?code=1002&ticket=1002
+//1002

+ 3 - 1
src/api/index.js

@@ -6,6 +6,7 @@ import workManagement from './workManagement.js' // 工作管理
 import modelLibrary from './modelLibrary.js' // 模型库
 import algorithmsLibrary from './algorithmsLibrary.js' // 算法库
 import mainPage from './mainPage.js' // 首页
+import systemManagement from "./systemManagement.js"; //系统管理
 
 const api = {
     common,
@@ -13,7 +14,8 @@ const api = {
     workManagement,
     modelLibrary,
     algorithmsLibrary,
-    mainPage
+    mainPage,
+    systemManagement
 }
 
 export default api;

+ 30 - 0
src/api/systemManagement.js

@@ -0,0 +1,30 @@
+const basePart = '/simulation/resource/server'
+//账户管理
+const getUserPageList = basePart + '/user/getUserPageList'
+const saveUser = basePart + '/user/saveUser'
+const saveDefaultPassword = basePart +  '/user/saveDefaultPassword'
+const saveVisible = basePart + '/user/saveVisible'
+//参数管理
+const getParameterList = basePart + '/parameter/getParameterList'
+const saveParameter = basePart + '/parameter/saveParameter'
+const getParamHistory = basePart + '/parameter/getParamHistory'
+//集群管理
+const getClusterList = basePart + '/cluster/getClusterList'
+const saveCluster = basePart + '/cluster/saveCluster'
+const getClusterHistory = basePart + '/cluster/getClusterHistory'
+const getClusterNum = basePart + '/cluster/getClusterNum'
+
+
+export default{
+    getUserPageList,
+    saveUser,
+    saveDefaultPassword,
+    saveVisible,
+    getParameterList,
+    saveParameter,
+    getParamHistory,
+    getClusterList,
+    saveCluster,
+    getClusterHistory,
+    getClusterNum
+}

+ 23 - 1
src/api/workManagement.js

@@ -17,6 +17,17 @@ const selectProjectReportById = basePart + '/simulationProject/selectProjectRepo
 const selectProjectTaskById = basePart + '/simulationProject/selectProjectTaskById'; // 获取手动运行项目工作详情-任务详情
 const exportProjectReportById = basePart + '/simulationProject/exportProjectReportById'; // 获取手动运行项目工作详情-下载测试报告
 
+const selectAutomaticProject = basePart + '/simulationProject/selectAutomaticProject'; // 自动运行项目列表
+const addOrUpdateAutomaticProject = basePart + '/simulationProject/addOrUpdateAutomaticProject'; // 添加/编辑自动运行任务
+const updateAutomaticRunState = basePart + '/simulationProject/updateAutomaticRunState'; // 修改自动运行主任务状态
+const selectAutomaticProjectById = basePart + '/simulationProject/selectAutomaticProjectById'; // 根据id查询自动运行项目信息
+const selectSubProjectInfo = basePart + '/simulationProject/selectSubProjectInfo'; // 查询自动运行子工作信息
+const selectSubProjectList = basePart + '/simulationProject/selectSubProjectList'; // 查询自动运行子工作列表
+const createAutomaticSubProject = basePart + '/simulationProject/createAutomaticSubProject'; // 手动运行自动项目
+const deleteAutomaticProjectByids = basePart + '/simulationProject/deleteAutomaticProjectByids'; // 删除自动运行主任务
+const deleteAutomaticSubProjectByIds = basePart + '/simulationProject/deleteAutomaticSubProjectByIds'; // 删除自动运行子任务
+const updateAutoProjectNowRunState = basePart + '/simulationProject/updateAutoProjectNowRunState'; // 修改自动运行子任务状态
+
 
 export default {
     addOrUpdateProject,
@@ -34,5 +45,16 @@ export default {
     selectProjectTaskList,
     selectProjectReportById,
     selectProjectTaskById,
-    exportProjectReportById
+    exportProjectReportById,
+
+    selectAutomaticProject,
+    addOrUpdateAutomaticProject,
+    updateAutomaticRunState,
+    selectAutomaticProjectById,
+    selectSubProjectInfo,
+    selectSubProjectList,
+    createAutomaticSubProject,
+    deleteAutomaticProjectByids,
+    deleteAutomaticSubProjectByIds,
+    updateAutoProjectNowRunState
 }

+ 45 - 12
src/axios/filter.js

@@ -43,13 +43,19 @@ axios.defaults.headers.common['Authorization'] = ""; //请求token信息配置
 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; //请求type设置
 axios.defaults.timeout = 30000; //在超时前,所有请求都会等待30秒
 axios.defaults.withCredentials = true;
+let isInvalid1 = false //用于控制登录信息过期后弹窗时间的截流,截流时间为5s
+let isInvalid2 = false
 
 // 添加请求拦截器
 axios.interceptors.request.use(function (config) {
     // 在发送请求之前处理
     // 判断token在前台session中是否存在
     config.headers.common['Authorization'] = localStorage.getItem('Authorization');
-    showFullScreenLoading();
+    if(config.noLoading===true){   //如果noLoading为true,不加载loading画面
+
+    }else{
+        showFullScreenLoading();
+    }
     return config;
 }, function (error) {
     // 对请求错误做处理
@@ -72,17 +78,28 @@ axios.interceptors.response.use(function (response) {
     return response;
 }, function (error) {
     tryHideFullScreenLoading();
-    console.log('网络异常');
-    ElementUI.Message.error("网络异常");
-    return Promise.reject(error);
+    if(error.response.status == 401){  //token失效,弹框提示确认返回login
+        //ElementUI.Message.error("用户信息过期,请重新登录");
+        if(isInvalid1 == false){
+            isInvalid1 = true
+            ElementUI.MessageBox.alert('用户信息过期,请重新登陆','提示',{
+                confirmButtonText:'确定',
+                callback: action => {
+                    let loginUrl = window.location.origin + '/login'
+                    window.location.href = loginUrl
+                }
+            })
+            setTimeout(()=>{isInvalid1 = false}, 5000)
+        }
+        return Promise.reject(error);
+    }else{
+        ElementUI.Message.error("网络异常");
+        return Promise.reject(error);
+    }
 });
 
 Vue.prototype.$axios = axios; //定义调用方式
 
-
-
-
-
 // 针对上传大文件
 const instance = axios.create({
     baseURL: '',
@@ -120,10 +137,26 @@ instance.interceptors.response.use(function (response) {
     return response;
 }, function (error) {
     tryHideFullScreenLoading();
-    console.log('网络异常');
-    ElementUI.Message.error("网络异常");
-    return Promise.reject(error);
+    if(error.response.status == 401){  //token失效,弹框提示确认返回login
+        if(isInvalid2 == false){
+            isInvalid2 = true
+            ElementUI.MessageBox.alert('用户信息过期,请重新登陆','提示',{
+                confirmButtonText:'确定',
+                callback: action => {
+                    let loginUrl = window.location.origin + '/login'
+                    window.location.href = loginUrl
+                }
+            })
+            setTimeout(()=>{isInvalid2 = false}, 5000)
+        }
+        return Promise.reject(error);
+    }else{
+        ElementUI.Message.error("网络异常");
+        return Promise.reject(error);
+    }
 });
 
 Vue.use(VueAxios, instance);
-Vue.prototype.$instance = instance; //定义调用方式
+Vue.prototype.$instance = instance; //定义调用方式
+
+//针对不需要loading画面的实例

+ 30 - 1
src/lib/util.js

@@ -177,4 +177,33 @@ Vue.prototype.$getObjectPathByRandom = function () {
     return a + b;
 }
 
-Vue.prototype.$md5 = md5
+Vue.prototype.$md5 = md5
+
+function TimeFormatter(time){
+    let date = new Date(time)
+    let year = date.getFullYear()
+    let month = date.getMonth()+1
+    let day = date.getDate()
+    let hour = date.getHours()
+    let min = date.getMinutes()
+    let second = date.getSeconds()
+    month<10?month = '0' + month:undefined
+    day<10?day = '0' + day:undefined
+    hour<10?hour = '0' + hour:undefined
+    min<10?min = '0' + min:undefined
+    second<10?second = '0' +second:undefined
+    return year + '-' + month + '-' + day + ' ' + hour + ':' + min + ':' + second
+}
+ Vue.prototype.$timeFormatter = TimeFormatter
+
+ function ValidatePhone(val){
+    let phoneReg = /^([0-9]{3,4}-)?[0-9]{7,8}$/;
+    let mobReg = /0?1[3|4|5|8][0-9]\d{8}$/;
+    if(phoneReg.test(val)||mobReg.test(val)){
+        return true
+    }else{
+        return false
+    }
+ }
+
+ Vue.prototype.$validatePhone = ValidatePhone

+ 1 - 1
src/router/filter.js

@@ -9,7 +9,7 @@ Router.prototype.push = function push(location) {
 
 
 router.beforeEach((to, from, next) => {
-    // console.log(to);
+    console.log(to);
     if (to.fullPath === '/' || to.name === '*') {
         let {
             code,

+ 10 - 3
src/router/index.js

@@ -9,7 +9,13 @@ import workManagement from "./workManagement"; // 工作管理
 
 Vue.use(VueRouter);
 
-const routes = [{
+const routes = [
+  {
+    path: "/login",
+    name: "login",
+    component: () => import("../views/login.vue")
+  },
+  {
   path: "/",
   name: "index",
   meta: {
@@ -82,7 +88,8 @@ const routes = [{
       name: "*",
       component: () => import("../views/mainPage.vue")
     }, ]),
-}];
+  },
+];
 // {
 //   path: "/",
 //   name: "About",
@@ -100,7 +107,7 @@ const router = new VueRouter({
   routes,
   scrollBehavior(to, from, savedPosition) {
     return {x: 0, y: 0}
-}
+  }
 });
 
 export default router;

+ 88 - 79
src/router/systemManagement.js

@@ -1,90 +1,99 @@
 export default [{
-        path: "/accountManagement",
-        name: "accountManagement",
-        meta: {
-            tabname: "账户管理",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/accountManagement")
+    path: "/accountManagement",
+    name: "accountManagement",
+    meta: {
+        tabname: "账户管理",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/addAccount",
-        name: "addAccount",
-        meta: {
-            tabname: "创建账户",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/addAccount")
+    component: () => import("@/views/systemManagement/accountManagement")
+},
+{
+    path: "/addAccount",
+    name: "addAccount",
+    meta: {
+        tabname: "创建账户",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/parameterManagement",
-        name: "paramenterManagement",
-        meta: {
-            tabname: "参数管理",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/parameterManagement")    
+    component: () => import("@/views/systemManagement/addAccount")
+},
+{
+    path: "/editAccount",
+    name: "editAccount",
+    meta: {
+        tabname: "编辑账户",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/parameterDetail",
-        name: "parameterDetail",
-        meta: {
-            tabname: "新增参数配置",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/parameterDetail")
+    component: () => import("@/views/systemManagement/editAccount")
+},
+{
+    path: "/parameterManagement",
+    name: "paramenterManagement",
+    meta: {
+        tabname: "参数管理",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/sceneLibraryManagement",
-        name: "sceneLibraryManagement",
-        meta: {
-            tabname: "场景库管理",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/sceneLibraryManagement/sceneLibraryManagement")
+    component: () => import("@/views/systemManagement/parameterManagement")    
+},
+{
+    path: "/parameterDetail",
+    name: "parameterDetail",
+    meta: {
+        tabname: "新增参数配置",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/reportTemplateManagement",
-        name: "reportTemplateManagement",
-        meta: {
-            tabname: "报告模板管理",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/reportTemplateManagement")
+    component: () => import("@/views/systemManagement/parameterDetail")
+},
+{
+    path: "/clusteringManagement",
+    name: "clusteringManagement",
+    meta: {
+        tabname: "集群管理",
+        menuKind: "sysyemManagement"
     },
-    {
-        path: "/reportTemplateDetail",
-        name: "reportTemplateDetail",
-        meta: {
-
-        },
-        component: () => import("@/views/systemManagement/reportTemplateDetail") 
+    component: () => import("@/views/systemManagement/clusteringManagement")
+},
+{
+    path: "/clusteringDetail",
+    name: "clusteringDetail",
+    meta: {
+        tabname: "新增集群配置",
+        menuKind: "systemManagement"
+    },
+    component: () => import("@/views/systemManagement/clusteringDetail")
+},
+{
+    path: "/sceneLibraryManagement",
+    name: "sceneLibraryManagement",
+    meta: {
+        tabname: "场景库管理",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/clusteringManagement",
-        name: "clusteringManagement",
-        meta: {
-            tabname: "集群管理",
-            menuKind: "sysyemManagement"
-        },
-        component: () => import("@/views/systemManagement/clusteringManagement")
+    component: () => import("@/views/systemManagement/sceneLibraryManagement/sceneLibraryManagement")
+},
+{
+    path: "/reportTemplateManagement",
+    name: "reportTemplateManagement",
+    meta: {
+        tabname: "报告模板管理",
+        menuKind: "systemManagement"
+    },
+    component: () => import("@/views/systemManagement/reportTemplateManagement")
+},
+{
+    path: "/reportTemplateDetail",
+    name: "reportTemplateDetail",
+    meta: {
+
     },
-    {
-        path: "/clusteringDetail",
-        name: "clusteringDetail",
-        meta: {
-            tabname: "新增集群配置",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/clusteringDetail")
+    component: () => import("@/views/systemManagement/reportTemplateDetail") 
+},
+{
+    path: "/logManagement",
+    name:"logManagement",
+    meta: {
+        tabname: "日志管理",
+        menuKind: "systemManagement"
     },
-    {
-        path: "/logManagement",
-        name:"logManagement",
-        meta: {
-            tabname: "日志管理",
-            menuKind: "systemManagement"
-        },
-        component: () => import("@/views/systemManagement/logManagement")
-    }
+    component: () => import("@/views/systemManagement/logManagement")
+}
 ]

+ 74 - 18
src/router/workManagement.js

@@ -5,7 +5,35 @@ export default [{
             tabname: "手动运行项目列表",
             menuKind: "workManagement"
         },
-        component: () => import("@/views/workManagement/manualRunProjectList")
+        component: () => import("@/views/workManagement/manualRunProjectList"),
+        children: [{
+            path: "projectInfo",
+            name: "projectInfo",
+            meta: {
+                tabname: "项目详情",
+                menuKind: "workManagement"
+            },
+            component: () => import("@/views/workManagement/projectInfo"),
+            children: [{
+                    path: "taskInfo",
+                    name: "taskInfo",
+                    meta: {
+                        tabname: "任务详情",
+                        menuKind: "workManagement"
+                    },
+                    component: () => import("@/views/workManagement/taskInfo")
+                },
+                {
+                    path: "evaluationReport",
+                    name: "evaluationReport",
+                    meta: {
+                        tabname: "评价报告",
+                        menuKind: "workManagement"
+                    },
+                    component: () => import("@/views/workManagement/evaluationReport")
+                },
+            ]
+        }, ]
     },
     {
         path: "/manualRunProjectDetail",
@@ -17,30 +45,58 @@ export default [{
         component: () => import("@/views/workManagement/manualRunProjectDetail")
     },
     {
-        path: "/projectInfo",
-        name: "projectInfo",
+        path: "/autoRunProjectList",
+        name: "autoRunProjectList",
         meta: {
-            tabname: "项目详情",
+            tabname: "自动运行项目列表",
             menuKind: "workManagement"
         },
-        component: () => import("@/views/workManagement/projectInfo")
+        component: () => import("@/views/workManagement/autoRunProjectList"),
+        children: [{
+            path: "autoRunSubProjectList",
+            name: "autoRunSubProjectList",
+            meta: {
+                tabname: "自动运行子项目列表",
+                menuKind: "workManagement"
+            },
+            component: () => import("@/views/workManagement/autoRunSubProjectList"),
+            children: [{
+                path: "projectInfo",
+                name: "projectInfo",
+                meta: {
+                    tabname: "项目详情",
+                    menuKind: "workManagement"
+                },
+                component: () => import("@/views/workManagement/projectInfo"),
+                children: [{
+                        path: "taskInfo",
+                        name: "taskInfo",
+                        meta: {
+                            tabname: "任务详情",
+                            menuKind: "workManagement"
+                        },
+                        component: () => import("@/views/workManagement/taskInfo")
+                    },
+                    {
+                        path: "evaluationReport",
+                        name: "evaluationReport",
+                        meta: {
+                            tabname: "评价报告",
+                            menuKind: "workManagement"
+                        },
+                        component: () => import("@/views/workManagement/evaluationReport")
+                    },
+                ]
+            }, ]
+        }, ]
     },
     {
-        path: "/taskInfo",
-        name: "taskInfo",
+        path: "/autoRunProjectDetail",
+        name: "autoRunProjectDetail",
         meta: {
-            tabname: "任务详情",
+            tabname: "自动运行项目",
             menuKind: "workManagement"
         },
-        component: () => import("@/views/workManagement/taskInfo")
-    },
-    {
-        path: "/evaluationReport",
-        name: "evaluationReport",
-        meta: {
-            tabname: "评价报告",
-            menuKind: "workManagement"
-        },
-        component: () => import("@/views/workManagement/evaluationReport")
+        component: () => import("@/views/workManagement/autoRunProjectDetail")
     },
 ]

+ 2 - 1
src/store/index.js

@@ -7,7 +7,8 @@ export default new Vuex.Store({
   state: {
     // configTitleList: ['摄像头', '完美传感器', '激光雷达', '毫米波雷达', 'GPS'],
     configTitleList: ['摄像头', '完美传感器', '激光雷达', 'GPS'],
-    fileHost: 'http://10.12.10.70:8001', // 开发环境需要连开发服务器地址,上线后会用相对地址拼接fileUrl
+    // fileHost: 'http://10.12.10.70:8001', // 开发环境需要连开发服务器地址,上线后会用相对地址拼接fileUrl
+    fileHost: 'http://47.94.105.148', // 开发环境需要连开发服务器地址,上线后会用相对地址拼接fileUrl
     fileUrl: '/simulation/resource/common/minio/preview',
     themeColor: '#3397FF',
   },

+ 18 - 6
src/views/algorithmsLibrary/algorithmsLibraryList.vue

@@ -60,7 +60,7 @@
             <el-tabs v-model="activeName" type="card" @tab-click="pageControl">
                 <el-tab-pane label="公有" name="1"></el-tab-pane>
                 <el-tab-pane label="私有导入" name="2"></el-tab-pane>
-                <el-tab-pane label="私有仓库" name="3" disabled></el-tab-pane>
+                <el-tab-pane label="私有仓库" name="3"></el-tab-pane>
             </el-tabs>
             <el-button
                 v-bind:class="{ addBtn: true, disabled: activeName === '1' }"
@@ -168,7 +168,7 @@ export default {
                     type: "post",
                     // firstRequest: false,
                     data: this.$api.algorithmsLibrary.selectAlgorithmList,
-                    param: {},
+                    param: this.activeName === "2"?{uploadMode: "1"}:{uploadMode: "2"},
                 };
             } else {
                 // 公有
@@ -183,6 +183,12 @@ export default {
             }
         },
     },
+    created(){
+        if(this.$route.query.activeName){
+            this.activeName = this.$route.query.activeName
+        }
+        this.$route.query.activeName = '2'
+    },
     methods: {
         doSearch() {
             if (this.activeName === "2") {
@@ -222,10 +228,16 @@ export default {
         addOne() {
             if (this.activeName === "2") {
                 // 私有导入
-                this.$router.push({ path: "/exportAlgorithms" });
+                this.$router.push({ 
+                    path: "/exportAlgorithms",
+                    query: {activeName: this.activeName}
+                });
             } else {
                 // 私有仓库
-                this.$router.push({ path: "/gitAlgorithms" });
+                this.$router.push({ 
+                    path: "/gitAlgorithms",
+                    query: {activeName: this.activeName}
+                });
             }
         },
         editRow(row) {
@@ -233,13 +245,13 @@ export default {
                 // 私有导入
                 this.$router.push({
                     path: "/exportAlgorithms",
-                    query: { id: row.id, share: row.share },
+                    query: { id: row.id, share: row.share, activeName: this.activeName },
                 });
             } else {
                 // 私有仓库
                 this.$router.push({
                     path: "/gitAlgorithms",
-                    query: { id: row.id, share: row.share },
+                    query: { id: row.id, share: row.share, activeName: this.activeName },
                 });
             }
         },

+ 4 - 1
src/views/algorithmsLibrary/exportAlgorithms.vue

@@ -160,7 +160,10 @@ export default {
             });
         },
         cancel() {
-            this.$router.replace({ path: "/algorithmsLibraryList" });
+            this.$router.replace({ 
+                path: "/algorithmsLibraryList", 
+                query:{activeName: this.$route.query.activeName}
+            });
         },
         onProgress() {
             this.$axios({

+ 121 - 18
src/views/algorithmsLibrary/gitAlgorithms.vue

@@ -36,33 +36,43 @@
                         >
                         </el-input>
                     </el-form-item>
-                    <el-form-item label="用户名:" prop="add1">
+                    <el-form-item label="用户名:" prop="gitUserName">
                         <el-input
                             placeholder="请输入"
                             maxlength="30"
-                            v-autoTrim="{ obj: form, key: 'add1' }"
-                            v-model="form.add1"
+                            v-autoTrim="{ obj: form, key: 'gitUserName' }"
+                            v-model="form.gitUserName"
                         >
                         </el-input>
                     </el-form-item>
-                    <el-form-item label="密码:" prop="add2">
+                    <el-form-item label="密码:" prop="gitPassword">
                         <el-input
                             placeholder="请输入"
                             maxlength="30"
                             type="password"
-                            v-autoTrim="{ obj: form, key: 'add2' }"
-                            v-model="form.add2"
+                            v-autoTrim="{ obj: form, key: 'gitPassword' }"
+                            v-model="form.gitPassword"
                         >
+                        <el-button slot="suffix" type="primary" @click="testConnection">测试链接</el-button>
                         </el-input>
                     </el-form-item>
-                    <div class="testLinkPanel">
-                        <el-button type="primary">测试链接</el-button>
-                    </div>
                 </el-form>
 
                 <div class="btns">
-                    <el-button type="primary">保存</el-button>
-                    <el-button type="primary">取消</el-button>
+                    <el-button
+                        type="primary"
+                        @click="save"
+                        >保存</el-button
+                    >
+                    <el-button
+                        v-if="form.share === '0' || form.share === '1'"
+                        type="primary"
+                        @click="saveOther"
+                        >另存为</el-button
+                    >
+                    <el-button type="primary" plain @click="cancel"
+                        >取消</el-button
+                    >
                 </div>
             </el-col>
         </el-row>
@@ -82,8 +92,8 @@ export default {
                 algorithmName: "", // 算法名称
                 description: "", // 算法描述
                 gitUrl: "", // 地址
-                gitToken: "", // 算法名称
-                sf: "", // 算法名称
+                gitUserName: "",  //仓库用户名
+                gitPassword: "",  //仓库密码
                 uploadMode: "2", // 方式
             },
             type: "1",
@@ -91,13 +101,105 @@ export default {
                 algorithmName: [{ required: true, message: "请输入", trigger: "blur" }],
                 description: [{ required: true, message: "请输入", trigger: "blur" }],
                 gitUrl: [{ required: true, message: "请输入", trigger: "blur" }],
-                name: [{ required: true, message: "请输入", trigger: "blur" }],
-                name: [{ required: true, message: "请输入", trigger: "blur" }],
+                //gitUserName: [{ required: true, message: "请输入", trigger: "blur" }],
+                //gitPassword: [{ required: true, message: "请输入", trigger: "blur" }],
             },
         };
     },
-
+    mounted(){
+        let id = this.$route.query.id;
+        if (id) {
+            this.form.share = this.$route.query.share;
+            this.$axios({
+                method: "post",
+                url: this.$api.algorithmsLibrary.selectDetailsById,
+                data: {
+                    id,
+                },
+            }).then((res) => {
+                if (res.code == 200 && res.info) {
+                    this.form = res.info;
+                } else {
+                    this.$message.error(res.message || "获取信息失败");
+                }
+            });
+        }
+    },
     methods: {
+        testConnection(){
+            let validateFieldList = []
+            this.$refs.form.validateField(['gitUrl'],async errorMsg=>{
+                if(!errorMsg){
+                    validateFieldList.push(errorMsg)
+                    if(validateFieldList.length == 1 && validateFieldList.every(item=>item ==='')){
+                        this.$axios({
+                            method: "POST",
+                            url: this.$api.algorithmsLibrary.testConnection,
+                            data:{
+                                gitUrl: this.form.gitUrl,
+                                gitUserName: this.form.gitUserName,
+                                gitPassword: this.form.gitPassword,
+                            }
+                        }).then(res=>{
+                            if(res.code == 200) {
+                                this.$message.success("测试成功");
+                            } else {
+                                this.$message.error(res.message || "测试失败");
+                            }
+                        })    
+                    }
+                }else{
+                    return false
+                } 
+            })
+            return
+        },
+        save(){
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    this.$axios({
+                        method: "post",
+                        url: this.$api.algorithmsLibrary.addOrUpdate,
+                        data: {
+                            ...this.form,
+                        },
+                    }).then((res) => {
+                        if (res.code == 200) {
+                            this.$message.success("保存成功");
+                            this.cancel();
+                        } else {
+                            this.$message.error(res.message || "保存失败");
+                        }
+                    });
+                }
+            });
+        },
+        saveOther(){
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    let data = {...this.form}
+                    data.id = ''
+                    this.$axios({
+                        method: "post",
+                        url: this.$api.algorithmsLibrary.addOrUpdate,
+                        data: data,
+                    }).then((res) => {
+                        if (res.code == 200) {
+                            this.$message.success("保存成功");
+                            this.cancel();
+                        } else {
+                            this.$message.error(res.message || "保存失败");
+                        }
+                    });
+                }
+            });
+        },
+        cancel(){
+            this.$router.replace({ 
+                path: "/algorithmsLibraryList", 
+                query:{activeName: this.$route.query.activeName}
+            });
+        }
         /* typeChange(val) {
             if (val === "1") {
                 this.rules = {
@@ -148,8 +250,6 @@ export default {
             this.type = val;
         }, */
     },
-
-    // mounted: {},
 };
 </script>
 
@@ -163,6 +263,9 @@ export default {
         .el-select {
             width: 100%;
         }
+        /deep/ .el-input__suffix{
+            right: 0;
+        }
     }
 
     .testLinkPanel {

+ 23 - 2
src/views/index.vue

@@ -1,6 +1,6 @@
 <template>
     <div id="main" v-bind:class="{ fold: isFold }">
-        <page-menu @menuFold="menuFold" ref="menu"></page-menu>
+        <page-menu @menuFold="menuFold" :menuItems="menuItems" ref="menu"></page-menu>
         <bread-crumb></bread-crumb>
         <router-view class="mainBox" ref="curRouter"></router-view>
     </div>
@@ -20,12 +20,26 @@ export default {
     data() {
         return {
             isFold: false, // menu是否折叠
+            menuItems:[]
         };
     },
     methods: {
         menuFold(flag) {
             this.isFold = flag;
         },
+        getMenuItems(){
+            this.$axios({
+                method: "POST",
+                url: this.$api.common.getMyMenuTree,
+                data:{}
+            }).then(res => {
+                if (res.code == 200 && res.info) {
+                    this.menuItems = res.info
+                }else{
+                    this.$message.error(res.message || '获取用户菜单失败')
+                }
+            })
+        },
     },
     created() {
         let { code, ticket } = this.$route.query;
@@ -40,16 +54,23 @@ export default {
                 if (res.code == 200 && !!res.info.access_token) {
                     localStorage.setItem(
                         "Authorization",
-                        "Bearer " + res.info.access_token
+                        res.info.token_type + ' ' + res.info.access_token
                     );
+                    localStorage.setItem("refreshToken", res.info.refresh_token);
+                    localStorage.setItem("expiresTime", res.info.expires_time);
+
                     this.$nextTick(() => {
                         this.$refs.curRouter.init &&
                             this.$refs.curRouter.init();
+
+                        this.getMenuItems()
                     });
                 } else {
                     this.$message.error(res.message || "网络异常");
                 }
             });
+        }else{
+            this.getMenuItems()
         }
     },
 };

+ 11 - 39
src/views/login.vue

@@ -48,7 +48,7 @@ export default {
                 password: [
                     {
                         required: true,
-                        message: "请输入最多16位密码",
+                        message: "请输入密码",
                         trigger: "blur",
                     },
                 ],
@@ -69,8 +69,7 @@ export default {
                         data: this.form,
                     }).then((res) => {
                         if (res.code == 200 && res.info) {
-                            let Authorization =
-                                "Bearer " + res.info.access_token;
+                            let Authorization = res.info.token_type + ' ' + res.info.access_token;
                             let refreshToken = res.info.refresh_token;
                             let expiresTime = res.info.expires_time;
 
@@ -81,26 +80,18 @@ export default {
                             );
                             localStorage.setItem("refreshToken", refreshToken);
                             localStorage.setItem("expiresTime", expiresTime);
+                            localStorage.setItem("username", this.form.username)
 
                             let tokenTimer = null;
                             let toExpiresTime =
                                 new Date(expiresTime).getTime() -
                                 new Date().getTime();
-
-                            console.log("go1", toExpiresTime);
-                            // 过期时间前60秒即可发送获取新的token
-                            if (toExpiresTime > 60 * 1000) {
-                                tokenTimer = setTimeout(() => {
-                                    this.getRefreshToken();
-                                    clearTimeout(tokenTimer);
-                                    // }, toExpiresTime - 60 * 1000);
-                                }, 15 * 1000);
-                            } else {
-                                this.getRefreshToken();
+                            if (toExpiresTime < 5*60 * 1000) {
+                                this.getRefreshToken()
+                            }else{
+                                this.$router.push({ path: "/mainPage" });
                             }
-
-                            this.$message.success("登录成功");
-                            this.$router.push({ path: "/mainPage" });
+                            
                         } else {
                             this.$message.error(res.message || "登录失败");
                         }
@@ -117,7 +108,7 @@ export default {
                 },
             }).then((res) => {
                 if (res.code == 200 && res.info) {
-                    let Authorization = "Bearer " + res.info.access_token;
+                    let Authorization = res.info.token_type + ' ' + res.info.access_token;
                     let refreshToken = res.info.refresh_token;
                     let expiresTime = res.info.expires_time;
 
@@ -126,27 +117,8 @@ export default {
                     localStorage.setItem("refreshToken", refreshToken);
                     localStorage.setItem("expiresTime", expiresTime);
 
-                    let tokenTimer = null;
-                    let toExpiresTime =
-                        new Date(expiresTime).getTime() - new Date().getTime();
-
-                    // 过期时间前60秒即可发送获取新的token
-                    console.log("go", toExpiresTime);
-                    if (toExpiresTime > 60 * 1000) {
-                        tokenTimer = setTimeout(() => {
-                            this.i++;
-                            if (this.i >= 10) {
-                                clearTimeout(tokenTimer);
-                                return;
-                            }
-                            this.getRefreshToken();
-                            clearTimeout(tokenTimer);
-                            // }, toExpiresTime - 60 * 1000);
-                            // Bearer 59d5d321-f16c-4412-9177-7f7d1e9180aa
-                        }, 15 * 1000);
-                    } else {
-                        this.getRefreshToken();
-                    }
+                    this.$router.push({ path: "/mainPage" });
+                    
                 } else {
                     this.$message.error(res.message || "获取refresh_token失败");
                 }

+ 8 - 0
src/views/mainPage.vue

@@ -373,6 +373,14 @@ export default {
     mounted() {
         if (localStorage.getItem("Authorization")) {
             this.init();
+        }else{  //如果没有Authorization
+            /*this.$alert('用户信息过期,请重新登陆','提示',{
+                confirmButtonText:'确定',
+                callback: action => {
+                    let loginUrl = window.location.origin + '/login'
+                    window.location.href = loginUrl
+                }
+            })*/
         }
     },
 };

+ 26 - 9
src/views/modelLibrary/components/canvasVehicleConfiguration.vue

@@ -73,8 +73,11 @@ export default {
                 // 摄像头从自己左上角的原点开始绘制,需要移到自己的中心点
                 let x = +data.x * rate;
                 let y = +data.y * rate;
-                let h1 = 90 - +data.h / 2;
-                let h2 = 90 + +data.h / 2;
+                // let h1 = 90 - +data.h / 2;
+                // let h2 = 90 + +data.h / 2;
+
+                let h1 = +data.h;
+                let h2 = Math.abs(h1);
 
                 this.ctx.clearRect(-250, -40, 500, 1000);
                 // this.ctx.drawImage(this.imgIcon, x - 6, y - 6, 20.5, 14.5);
@@ -84,13 +87,27 @@ export default {
                 //定义起点
                 this.ctx.moveTo(x, y);
                 //以起点为圆心,画一个半径为100的圆弧
-                this.ctx.arc(
-                    x,
-                    y,
-                    400,
-                    (h1 * Math.PI) / 180,
-                    (h2 * Math.PI) / 180
-                );
+                if (h1 > 0) {
+                    this.ctx.arc(
+                        x,
+                        y,
+                        400,
+                        // (h1 * Math.PI) / 180,
+                        // (h2 * Math.PI) / 180
+                        0.5 * Math.PI,
+                        (0.5 - h2 / 180) * Math.PI,
+                        true
+                    );
+                } else {
+                    this.ctx.arc(
+                        x,
+                        y,
+                        400,
+                        0.5 * Math.PI,
+                        (h2 / 180 + 0.5) * Math.PI
+                    );
+                }
+
                 this.ctx.closePath();
                 this.ctx.fillStyle = "rgba(252,222,147,0.54)";
                 this.ctx.fill();

+ 1 - 1
src/views/page/breadCrumb.vue

@@ -22,7 +22,7 @@
                         >
                             <i
                                 class="el-icon-folder-opened"
-                                v-if="index > 1"
+                                v-if="index > 0 && index === list.length - 1"
                             ></i>
                             {{ item.meta.tabname }}
                         </router-link>

+ 156 - 64
src/views/page/pageMenu.vue

@@ -14,11 +14,12 @@
                 >
                     <b class="my-icon-home is"></b>
                 </li>
+                <!--
                 <li
                     @click="menuFoldHandle(1)"
                     v-bind:class="{ isOpened: opened === 'modelLibrary' }"
                 >
-                    <b class="my-icon-menuA"></b>
+                    <b class="my-icon-model"></b>
                 </li>
                 <li
                     @click="menuFoldHandle(1)"
@@ -38,18 +39,20 @@
                 >
                     <b class="my-icon-menuD"></b>
                 </li>
-                <!-- <li
-                    @click="menuFoldHandle(1)"
-                    v-bind:class="{ isOpened: opened === 'systemManagement' }"
-                >
-                    <b class="my-icon-menuE"></b>
-                </li>
                 <li
                     @click="menuFoldHandle(1)"
                     v-bind:class="{ isOpened: opened === 'systemManagement' }"
                 >
                     <b class="my-icon-menuF"></b>
-                </li> -->
+                </li> 
+                -->
+                <li 
+                    v-for="(item, i) in menuItems" :key="i"
+                    @click="menuFoldHandle(1)"
+                    :class="{ isOpened: opened === item.id }"
+                >
+                    <b :class="item.icon"></b>
+                </li>
             </ul>
 
             <div class="menuList" v-show="!menuFold">
@@ -67,77 +70,93 @@
                         <i class="my-icon-home"></i>
                         <span>首页</span>
                     </el-menu-item>
+                    
+                    <!--
                     <el-submenu :index="menus[1]">
                         <template slot="title">
-                            <i class="my-icon-menuA"></i>
+                            <i class="my-icon-model"></i>
                             <span>模型库</span>
                         </template>
-                        <el-menu-item index="sensorModel"
+                        <el-menu-item index="/sensorModel"
                             >传感器模型</el-menu-item
                         >
-                        <el-menu-item index="vehicleModel"
+                        <el-menu-item index="/vehicleModel"
                             >车辆模型</el-menu-item
                         >
-                        <el-menu-item index="vehicleConfigurationList"
+                        <el-menu-item index="/vehicleConfigurationList"
                             >车辆配置</el-menu-item
                         >
                     </el-submenu>
                     <el-submenu :index="menus[2]">
                         <template slot="title">
-                            <i class="my-icon-menuB"></i>
+                            <i class="my-icon-algo"></i>
                             <span>算法库</span>
                         </template>
-                        <el-menu-item index="algorithmsLibraryList"
+                        <el-menu-item index="/algorithmsLibraryList"
                             >算法库列表</el-menu-item
                         >
-                        <el-menu-item index="algorithmsPlatformList"
+                        <el-menu-item index="/algorithmsPlatformList"
                             >算法平台</el-menu-item
                         >
                     </el-submenu>
                     <el-submenu :index="menus[3]">
                         <template slot="title">
-                            <i class="my-icon-menuC"></i>
+                            <i class="my-icon-scene"></i>
                             <span>场景库</span>
                         </template>
-                        <el-menu-item index="naturalDrivingScenarioList"
+                        <el-menu-item index="/naturalDrivingScenarioList"
                             >自然驾驶场景</el-menu-item
                         >
                         <el-menu-item
-                            index="standardRegulationSimulationScenarioList"
+                            index="/standardRegulationSimulationScenarioList"
                             >标准法规仿真场景</el-menu-item
                         >
                         <el-menu-item
-                            index="trafficAccidentSimulationScenarioList"
+                            index="/trafficAccidentSimulationScenarioList"
                             >交通事故仿真场景</el-menu-item
                         >
-                        <el-menu-item index="scenarioTestPackageManagementList"
+                        <el-menu-item index="/scenarioTestPackageManagementList"
                             >场景测试包管理</el-menu-item
                         >
-                        <el-menu-item index="gradingRulesList"
+                        <el-menu-item index="/gradingRulesList"
                             >评分规则</el-menu-item
                         >
                     </el-submenu>
                     <el-submenu :index="menus[4]">
                         <template slot="title">
-                            <i class="my-icon-menuD"></i>
+                            <i class="my-icon-work"></i>
                             <span>工作管理</span>
                         </template>
-                        <el-menu-item index="manualRunProjectList"
+                        <el-menu-item index="/manualRunProjectList"
                             >手动运行项目</el-menu-item
                         >
                     </el-submenu>
-                    <!-- <el-submenu index="systemManagement">
+                    <el-submenu :index="menus[5]">
                         <template slot="title">
-                            <i class="my-icon-menuF"></i>
+                            <i class="my-icon-system"></i>
                             <span>系统管理</span>
                         </template>
-                        <el-menu-item index="accountManagement"
+                        <el-menu-item index="/accountManagement"
                             >账户管理</el-menu-item
                         >
-                        <el-menu-item index="parameterManagement"
+                        <el-menu-item index="/parameterManagement"
                             >参数管理</el-menu-item
                         >    
-                    </el-submenu> -->
+                        <el-menu-item index="/clusteringManagement"
+                            >集群管理</el-menu-item>
+                    </el-submenu>
+                    -->
+
+                    <el-submenu v-for="(item, i) in menuItems" :index="item.id" :key="i">
+                        <template slot="title">
+                            <i :class="item.icon"></i>
+                            <span>{{item.name}}</span>  
+                        </template>
+                        <el-menu-item v-for="(item2, i2) in item.children" :index="item2.router" :key="i2">
+                            {{item2.name}}
+                        </el-menu-item>
+                    </el-submenu>
+
                 </el-menu>
             </div>
         </div>
@@ -149,6 +168,12 @@ import { mapState } from "vuex";
 
 export default {
     name: "pageMenu",
+    props:{
+        menuItems:{
+            type: Array,
+            default(){return []}
+        }
+    },
     data() {
         return {
             menuFold: false, // menu是否折叠
@@ -161,13 +186,43 @@ export default {
                 "workManagement",
             ],
             activeMenu: "mainPage", // 当前menu
+            expiresTime: '',
+            toExpiresTime: '',
+            tokenTimer: undefined,
         };
     },
-
     computed: {
         ...mapState(["themeColor"]),
     },
+    mounted() {
+        let menuKind = this.$route.meta.menuKind;
 
+        if (menuKind && menuKind !== "mainPage") {
+            this.$refs.menu.open(menuKind);
+        }
+
+        //设置一个定时器,定时在距离过期前5min,这个定时器会发送refreshToken请求
+        
+        this.expiresTime = localStorage.getItem('expiresTime')
+        if(this.expiresTime){
+            this.toExpiresTime = new Date(this.expiresTime).getTime() - new Date().getTime();
+            let that = this;
+            if(this.toExpiresTime < 5*60*1000){
+                this.refreshToken()
+            }else{
+                if(this.toExpiresTime < 24*60*60*1000){   //当过期时间小于一天时才会定时执行,否则会因为过期时间过大无法执行
+                    this.tokenTimer = setTimeout(function(){
+                        that.refreshToken()
+                    }, this.toExpiresTime - 5*60*1000)
+                }
+            }
+        }
+    },
+    watch:{
+        activeMenu(newV){
+            console.log(newV)
+        }
+    },
     methods: {
         menuFoldHandle(val) {
             if (val) {
@@ -188,13 +243,50 @@ export default {
                 });
             }
         },
-    },
-
-    mounted() {
-        let menuKind = this.$route.meta.menuKind;
-
-        if (menuKind && menuKind !== "mainPage") {
-            this.$refs.menu.open(menuKind);
+        checkExpiresTime(){
+            this.toExpiresTime = new Date(this.expiresTime).getTime() - new Date().getTime();
+            if(this.toExpiresTime < 5*60*1000){
+                this.refreshToken()
+            }
+        },
+        refreshToken(){
+            this.$axios({
+                method: "post",
+                url: this.$api.common.refreshToken,
+                noLoading: true,
+                data: {
+                    refreshToken: localStorage.getItem("refreshToken"),
+                },
+            }).then((res) => {
+                if (res.code == 200 && res.info) {
+                    let Authorization = res.info.token_type + ' ' + res.info.access_token;
+                    let refreshToken = res.info.refresh_token;
+                    let expiresTime = res.info.expires_time;
+                    localStorage.clear();
+                    localStorage.setItem("Authorization", Authorization);
+                    localStorage.setItem("refreshToken", refreshToken);
+                    localStorage.setItem("expiresTime", expiresTime);
+                    
+                    this.expiresTime = expiresTime
+                    this.toExpiresTime = new Date(this.expiresTime).getTime() - new Date().getTime();
+                    clearTimeout(this.tokenTimer)
+                    if(this.toExpiresTime < 5*60*1000){
+                        //this.refreshToken()
+                    }else{
+                        if(this.toExpiresTime < 24*60*60*1000){  
+                            this.tokenTimer = setTimeout(function(){
+                                let that = this;
+                                that.refreshToken()
+                            }, this.toExpiresTime - 5*60*1000)
+                        }
+                    }
+                }else{
+                    if(res.code == 400){  //refreshToken请求返回400则跳回登录页
+                        let loginUrl = window.location.origin + '/login'
+                        window.location.href = loginUrl
+                    }
+                }
+            })
         }
     },
 };
@@ -286,34 +378,6 @@ export default {
     }
 }
 
-.my-icon-home {
-    background: url("../../assets/common/image/menu/home.png") center no-repeat;
-}
-
-.my-icon-menuA {
-    background: url("../../assets/common/image/menu/menuA.png") center no-repeat;
-}
-
-.my-icon-menuB {
-    background: url("../../assets/common/image/menu/menuB.png") center no-repeat;
-}
-
-.my-icon-menuC {
-    background: url("../../assets/common/image/menu/menuC.png") center no-repeat;
-}
-
-.my-icon-menuD {
-    background: url("../../assets/common/image/menu/menuD.png") center no-repeat;
-}
-
-.my-icon-menuE {
-    background: url("../../assets/common/image/menu/menuE.png") center no-repeat;
-}
-
-.my-icon-menuF {
-    background: url("../../assets/common/image/menu/menuF.png") center no-repeat;
-}
-
 .menuFold {
     li {
         display: flex;
@@ -410,4 +474,32 @@ export default {
         bottom: 30px;
     }
 }
+
+.my-icon-home {
+    background: url("../../assets/common/image/menu/home.png") center no-repeat;
+}
+
+.my-icon-model {
+    background: url("../../assets/common/image/menu/menuA.png") center no-repeat;
+}
+
+.my-icon-algo {
+    background: url("../../assets/common/image/menu/menuB.png") center no-repeat;
+}
+
+.my-icon-scene {
+    background: url("../../assets/common/image/menu/menuC.png") center no-repeat;
+}
+
+.my-icon-work {
+    background: url("../../assets/common/image/menu/menuD.png") center no-repeat;
+}
+
+.my-icon-menuE {
+    background: url("../../assets/common/image/menu/menuE.png") center no-repeat;
+}
+
+.my-icon-system {
+    background: url("../../assets/common/image/menu/menuF.png") center no-repeat;
+}
 </style>

+ 150 - 58
src/views/systemManagement/accountManagement.vue

@@ -4,17 +4,7 @@
             <template slot="searchItem1">
                 <span class="label">账户名称</span>
                 <el-input
-                    v-model="searchParams.id"
-                    size="small"
-                    clearable
-                    placeholder="请输入"
-                >
-                </el-input>
-            </template>
-            <template slot="searchItem2">
-                <span class="label">所属公司</span>
-                <el-input
-                    v-model="searchParams.clientOrgName"
+                    v-model="searchParams.username"
                     size="small"
                     clearable
                     placeholder="请输入"
@@ -23,18 +13,28 @@
             </template>
             <template slot="searchItem3">
                 <span class="label">账户类型</span>
-                <el-select v-model="searchParams.status">
+                <el-select v-model="searchParams.roleCode">
                     <el-option
-                        v-for="item in list"
+                        v-for="item in roleCodeList"
                         :label="item.caption"
                         :value="item.code"
                         :key="item.code"
                     ></el-option>
                 </el-select>
             </template>
+            <template slot="searchItem2">
+                <span class="label">所属公司</span>
+                <el-input
+                    v-model="searchParams.company"
+                    size="small"
+                    clearable
+                    placeholder="请输入"
+                >
+                </el-input>
+            </template>
             <template slot="searchItem4">
                 <span class="label">状态</span>
-                <el-select v-model="searchParams.status">
+                <el-select v-model="searchParams.visible">
                     <el-option
                         v-for="item in list"
                         :label="item.caption"
@@ -44,25 +44,25 @@
                 </el-select>
             </template>
             <template slot="searchBtn1">
-                <el-button type="primary">查询</el-button>
+                <el-button type="primary" @click="search">查询</el-button>
             </template>
             <template slot="searchBtn2">
-                <el-button type="primary">重置</el-button>
+                <el-button type="primary" @click="reset">重置</el-button>
             </template>
         </search-layout>
 
         <div class="btnsPanel">
-            <el-button type="primary" plain icon="el-icon-video-pause"
+            <!--<el-button type="primary" plain icon="el-icon-video-pause"
                 >批量停用</el-button
             >
             <el-button type="primary" plain icon="el-icon-video-play"
                 >批量启用</el-button
-            >
+            >-->
             <el-button
                 type="primary"
                 icon="el-icon-circle-plus-outline"
-                @click="addConfig"
-                >创建</el-button
+                @click="addAccount"
+                >创建账户</el-button
             >
         </div>
 
@@ -73,17 +73,25 @@
             :getDataWay="getDataWay"
             :pagination="pagination"
             index
-            selection
         >
+            <el-table-column label="停/启用" slot="visible" align="center">
+                <template v-slot="scope">
+                    <el-switch
+                        v-model="scope.row.visible"
+                        active-value="1"
+                        inactive-value="0"
+                        active-color="#3397ff"
+                        inactive-color="#ff4949"
+                        @change="$event=>{switchVisible($event, scope.row)}"
+                    ></el-switch>
+                </template>
+            </el-table-column>
             <el-table-column label="操作" slot="cgInfos" align="center">
                 <template v-slot="scope">
                     <i
-                        @click="addMarkDia(scope.row)"
+                        @click="editAccount(scope.row)"
                         class="el-icon-edit-outline elIcon"
-                    ></i>
-                    <i
-                        @click="addMarkDia(scope.row)"
-                        class="el-icon-video-pause elIcon"
+                        title="编辑"
                     ></i>
                 </template>
             </el-table-column>
@@ -102,46 +110,59 @@ export default {
         return {
             searchParams: {
                 //搜索参数
-                id: "", //ID
-                clientOrgName: "", //车辆名称
-                clientOrgName1: "", //配置名称
-                clientOrgName2: "", //配置描述
-                status: "",
+                username: "", //账户名
+                company:"",  //所属公司
+                roleCode:"",  //账户类型
+                visible:""  //启用状态
             },
-            list: [],
+            roleCodeList:[],
+            list: [
+                {
+                    code:'1',
+                    caption:'启用'
+                },
+                {
+                    code:'0',
+                    caption:'停用'
+                }
+            ],
             columns: [
                 //表格列
                 {
                     label: "账户名称",
-                    prop: "id",
+                    prop: "username",
                 },
                 {
                     label: "账户类型",
-                    prop: "aid",
+                    prop: "roleCode",
                 },
                 {
                     label: "所属公司",
-                    prop: "ktName",
+                    prop: "company",
                 },
                 {
                     label: "联系人",
-                    prop: "jbSource",
+                    prop: "nickname",
                 },
                 {
                     label: "联系方式",
-                    prop: "aid",
+                    prop: "phone",
                 },
                 {
-                    label: "状态",
-                    prop: "ktName",
+                    label: "停/启用",
+                    prop: "visible",
+                    template: true
                 },
                 {
                     label: "创建人",
-                    prop: "jbSource",
+                    prop: "createUserName",
                 },
                 {
                     label: "创建时间",
-                    prop: "jbSource",
+                    prop: "createTime",
+                    formatter: (data) => {
+                        return this.$timeFormatter(data.createTime)
+                    }
                 },
                 {
                     label: "操作",
@@ -159,31 +180,101 @@ export default {
             },
             getDataWay: {
                 //加载表格数据
-                dataType: "data",
+                dataType: "url",
                 type: "post",
-                firstRequest: false,
-                data: [
-                    {
-                        id: 1,
-                        ktName: "kjdhfkjsdhfkjsjhdfksdjhfkhwoieyrhfisdhfksjhdf",
-                        jbSource: "收到就好付款时间的回复可见收到货覅无痕",
-                    },
-                    { id: 2 },
-                    { id: 3 },
-                    { id: 4 },
-                    { id: 51 },
-                    { id: 6 },
-                ],
-                // data: this.$api.scientificStatistics.typeProjectStatistics,
+                // firstRequest: false,
+                data: this.$api.systemManagement.getUserPageList,
                 param: {},
             },
         };
     },
+    async mounted() {
+        await this.$dicsListsInit({
+            roleCodeList: "roleCode",
+        });
+    },
     methods: {
-        addConfig() {
+        addAccount() {
             this.$router.push({ path: "/addAccount" });
         },
-        addMarkDia() {},
+        editAccount(row) {
+            let query = {...row}
+            console.log(row)
+            this.$router.push({
+                path: "/editAccount",
+                query
+            })
+        },
+        search(){
+            let searchParam = {
+                    username: this.searchParams.username,
+                    company: this.searchParams.company,
+                    roleCode: this.searchParams.roleCode,
+                    visible: this.searchParams.visible
+            }
+            this.refreshList(searchParam)
+        },
+        reset(){
+            this.searchParams={
+                username: '',
+                company: '',
+                roleCode: '',
+                visible: ''
+            }
+            this.search()
+        },
+        refreshList(param) {
+            param
+                ? this.$refs["table"].loadData(param)
+                : this.$refs["table"].loadData();
+        },
+        switchVisible(value, row){  //停用启用账户
+            if(value == '0'){
+                row.visible = '1'
+                this.$confirm("确认停用该账户?", "提示", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning",
+                }).then(()=>{
+                    this.$axios({
+                        method:'POST',
+                        url: this.$api.systemManagement.saveVisible,
+                        data:{
+                            id: row.id,
+                            visible: '0'
+                        }
+                    }).then(res=>{
+                        if(res.code == '200'){
+                            row.visible = '0'
+                        }else{
+                            this.$message.error(res.message || "停用失败");
+                        }
+                    })
+                }).catch(()=>{})
+            }else{
+                row.visible = '0'
+                this.$confirm("确认启用该账户?", "提示", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning",
+                }).then(()=>{this.$axios({
+                        method:'POST',
+                        url: this.$api.systemManagement.saveVisible,
+                        data:{
+                            id: row.id,
+                            visible: '1'
+                        }
+                    }).then(res=>{
+                        if(res.code == '200'){
+                            row.visible = '1'
+                        }else{
+                            this.$message.error(res.message || "启用失败");
+                        }
+                    })
+                }).catch(()=>{})
+            }
+            
+        }
     },
 };
 </script>
@@ -191,5 +282,6 @@ export default {
 <style scoped lang="less">
 .btnsPanel {
     margin: 45px 40px 15px;
+    text-align: right;
 }
 </style>

+ 97 - 129
src/views/systemManagement/addAccount.vue

@@ -1,7 +1,7 @@
 <template>
     <div>
-        <div class="flexBox box">
-            <div class="fileBox">
+        <div style="padding: 45px 30px 0;">
+            <!--<div class="fileBox">
                 <div class="til">头像</div>
                 <div class="photo">
                     <img :src="imgSrc" width="100%" height="100%" />
@@ -11,165 +11,101 @@
                         >上传文件</el-button
                     >
                 </div>
-            </div>
-            <el-form
+            </div>-->
+            <el-row>
+                <el-col :span="16" :offset="4">
+                <el-form
                 ref="form"
                 :model="form"
                 :rules="rules"
                 label-width="108px"
             >
-                <el-form-item label="账户名称:" prop="name" v-show="isEdited">
+                <el-form-item label="账户名称:" prop="username">
                     <el-input
                         placeholder="请输入"
                         maxlength="30"
-                        v-autoTrim="{ obj: form, key: 'name' }"
-                        v-model="form.name"
+                        v-autoTrim="{ obj: form, key: 'username' }"
+                        v-model="form.username"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="账户名称:" prop="name" v-show="!isEdited">
-                    {{ form.name }}
-                </el-form-item>
-
-                <el-form-item label="账户类型:" prop="des" v-show="isEdited">
-                    <el-select v-model="form.des">
+                <el-form-item label="账户类型:" prop="roleCode">
+                    <el-select v-model="form.roleCode">
                         <el-option
-                            v-for="item in list"
+                            v-for="item in roleCodeList"
                             :label="item.caption"
                             :value="item.code"
                             :key="item.code"
                         ></el-option>
                     </el-select>
                 </el-form-item>
-                <el-form-item label="账户类型:" prop="des" v-show="!isEdited">
-                    {{ form.name }}
-                </el-form-item>
 
-                <el-form-item label="所属公司:" prop="x" v-show="isEdited">
+                <el-form-item label="所属公司:" prop="company">
                     <el-input
                         placeholder="请输入"
-                        maxlength="15"
-                        v-autoTrim="{ obj: form, key: 'x' }"
-                        v-model="form.x"
+                        maxlength="30"
+                        v-autoTrim="{ obj: form.company, key: 'company' }"
+                        v-model="form.company"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="所属公司:" prop="x" v-show="!isEdited">
-                    {{ form.name }}
-                </el-form-item>
 
-                <el-form-item label="联系人:" prop="x" v-show="isEdited">
+                <el-form-item label="联系人:" prop="nickname">
                     <el-input
                         placeholder="请输入"
                         maxlength="15"
-                        v-autoTrim="{ obj: form, key: 'x' }"
-                        v-model="form.x"
+                        v-autoTrim="{ obj: form.nickname, key: 'nickname' }"
+                        v-model="form.nickname"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="联系人:" prop="x" v-show="!isEdited">
-                    {{ form.name }}
-                </el-form-item>
-
-                <el-form-item label="联系方式:" prop="x" v-show="isEdited">
+                
+                <el-form-item label="联系方式:" prop="phone">
                     <el-input
                         placeholder="请输入"
                         maxlength="15"
-                        v-autoTrim="{ obj: form, key: 'x' }"
-                        v-model="form.x"
+                        v-autoTrim="{ obj: form.phone, key: 'phone' }"
+                        v-model="form.phone"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="联系方式:" prop="x" v-show="!isEdited">
-                    {{ form.name }}
-                </el-form-item>
-
-                <el-form-item label="密码:" prop="x" v-show="isEdited">
+                <!--
+                <el-form-item label="密码:" prop="password">
                     <el-input
                         placeholder="请输入"
                         type="password"
                         maxlength="15"
-                        v-autoTrim="{ obj: form, key: 'x' }"
-                        v-model="form.x"
+                        v-autoTrim="{ obj: form.password, key: 'password' }"
+                        v-model="form.password"
                     >
                     </el-input>
                 </el-form-item>
 
-                <el-form-item label="确认密码:" prop="x" v-show="isEdited">
+                <el-form-item label="确认密码:" prop="password">
                     <el-input
                         placeholder="请输入"
                         type="password"
                         maxlength="15"
-                        v-autoTrim="{ obj: form, key: 'x' }"
-                        v-model="form.x"
+                        v-autoTrim="{ obj: form.password, key: 'password' }"
+                        v-model="form.password"
                     >
                     </el-input>
                 </el-form-item>
-
-                <el-form-item label="状态:" prop="y" v-show="isEdited">
-                    <el-radio v-model="form.z" label="1">启用</el-radio>
-                    <el-radio v-model="form.z" label="2">停用</el-radio>
-                </el-form-item>
-                <el-form-item label="状态:" prop="y" v-show="!isEdited">
-                    {{ form.name }}
+                -->
+                <el-form-item label="独占类型:" prop="useType">
+                    <el-radio v-for="item in useTypeList" :key="item.code" :label="item.code" v-model="form.useType">{{item.caption}}</el-radio>
                 </el-form-item>
 
-                <div class="btns" v-show="isEdited">
-                    <el-button type="primary">保存</el-button>
-                    <el-button type="primary" plain @click="cancelForm"
-                        >取消</el-button
-                    >
+                <div class="btns">
+                    <el-button type="primary" @click="saveForm">保存</el-button>
+                    <el-button type="primary" plain @click="cancel"
+                    >取消</el-button>
                 </div>
             </el-form>
-            <div class="editBox">
-                <el-button
-                 v-show="isEdited"
-                    type="primary"
-                    icon="el-icon-edit-outline"
-                    @click="editForm"
-                    >编辑</el-button
-                >
-            </div>
+                </el-col>
+            </el-row>    
         </div>
 
-        <el-dialog
-            title="编辑"
-            :visible.sync="dialogVisible"
-            width="690px"
-            :close-on-click-modal="false"
-            :close-on-press-escape="false"
-        >
-            <el-form
-                ref="formA"
-                :model="formA"
-                :rules="rulesA"
-                label-width="108px"
-            >
-                <el-form-item
-                    label="手机验证码:"
-                    prop="name"
-                    class="getCodeBox"
-                >
-                    <el-input
-                        placeholder="请输入"
-                        maxlength="30"
-                        class="name"
-                        v-autoTrim="{ obj: form, key: 'name' }"
-                        v-model="formA.name"
-                    >
-                        <el-button slot="append" type="primary"
-                            >获取验证码</el-button
-                        >
-                    </el-input>
-                </el-form-item>
-            </el-form>
-            <span slot="footer">
-                <el-button type="primary" @click="dialogVisible = false"
-                    >确 定</el-button
-                >
-                <el-button @click="dialogVisible = false">取 消</el-button>
-            </span>
-        </el-dialog>
     </div>
 </template>
 
@@ -182,45 +118,77 @@ export default {
     data() {
         return {
             list: [],
-            isEdited: true,
+            roleCodeList: [],
+            useTypeList:[],  //占用类型
             imgSrc: require("@/assets/common/image/photoF.png"),
             form: {
-                name: "创建账户",
-                des: "",
-                x: "",
-                y: "1",
-                z: "2",
+                id: "",
+                username: "",
+                roleCode: "",
+                company: "",
+                nickname: "",
+                phone: "",
+                //password: "",
+                useType: ""
             },
             rules: {
-                name: [{ required: true, message: "请输入", trigger: "blur" }],
-                des: [{ required: true, message: "请输入", trigger: "blur" }],
-                x: [{ required: true, message: "请输入", trigger: "blur" }],
-                y: [{ required: true, message: "请选择", trigger: "change" }],
-                z: [{ required: true, message: "请选择", trigger: "change" }],
-            },
-            formA: {
-                name: "",
+                username: [{ required: true, message: "请输入", trigger: "blur" }],
+                roleCode: [{ required: true, message: "请选择", trigger: "change" }],
+                company: [{ required: true, message: "请输入", trigger: "blur" }],
+                nickname: [{ required: true, message: "请输入", trigger: "blur" }],
+                phone: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                    {
+                        validator: (rule, value, callback) => {
+                            if(this.$validatePhone(value)){
+                                callback()
+                            }else{
+                                callback(new Error('格式错误'))
+                            }
+                        },
+                        trigger: "blur"
+                    }
+                ],
+                //password: [{ required: true, message: "请输入", trigger: "blur" }],
+                useType: [{ required: true, message: "请选择", trigger: "change" }],
             },
-            rulesA: {
-                name: [{ required: true, message: "请输入", trigger: "blur" }],
-            },
-            dialogVisible: false,
         };
     },
+    async created(){
 
-    computed: {},
+    },
+    async mounted() {
+        await this.$dicsListsInit({
+            roleCodeList: "roleCode",
+            useTypeList: "useType"
+        });
+    },
+    computed: {
 
+    },
     methods: {
-        editForm() {
-            this.isEdited = true;
-            this.dialogVisible = true;
+        saveForm(){
+            this.$axios({
+                method:'POST',
+                url:this.$api.systemManagement.saveUser,
+                data:{
+                    ...this.form
+                }
+            }).then(res => {
+                if(res.code == 200){
+                    this.$message.success("保存成功");
+                    this.cancel()
+                }else{
+                    this.$message.error(res.message || "保存失败");
+                }
+            })
         },
-        cancelForm() {
-            this.isEdited = false;
-            this.dialogVisible = false;
+        cancel() {
+            this.$router.replace({
+                path: '/accountManagement'
+            })
         },
     },
-
     // mounted: {},
 };
 </script>

+ 111 - 46
src/views/systemManagement/clusteringDetail.vue

@@ -9,53 +9,73 @@
             class="flexBox"
         >
             <div class="formItemBox">
-                <el-form-item label="节点名称:" prop="a1">
+                <el-form-item label="账户名称:" prop="userName">
                     <el-input
                         placeholder="请输入"
-                        maxlength="30"
-                        v-autoTrim="{ obj: form, key: 'a1' }"
-                        v-model="form.a1"
+                        disabled
+                        v-model="form.userName"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="节点地址:" prop="a2">
+                <el-form-item label="独占类型:" prop="useType">
+                    <!--<el-select v-model="form.useType" disabled>
+                        <el-option
+                            v-for="item in useTypeList"
+                            :label="item.caption"
+                            :value="item.code"
+                            :key="item.code"
+                        ></el-option>
+                    </el-select>-->
                     <el-input
                         placeholder="请输入"
-                        maxlength="100"
-                        v-autoTrim="{ obj: form, key: 'a2' }"
-                        v-model="form.a2"
+                        disabled
+                        v-model="form.useType"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="节点类型:" prop="a3">
+                <el-form-item label="仿真软件license数量:" prop="numSimulationLicense">
                     <el-input
                         placeholder="请输入"
-                        maxlength="100"
-                        v-autoTrim="{ obj: form, key: 'a3' }"
-                        v-model="form.a3"
+                        maxlength="20"
+                        v-autoTrim="{ obj: form, key: 'numSimulationLicense' }"
+                        v-model="form.numSimulationLicense"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="适用类型:" prop="a4">
+                <el-form-item label="到期时间:" prop="dateSimulationLicense">
+                    <el-date-picker
+                        v-model="form.dateSimulationLicense"
+                        type="date"
+                        placeholder="选择日期"
+                        value-format="yyyy-MM-dd"
+                    ></el-date-picker>
+                </el-form-item>
+                <el-form-item label="动力学软件license数量:" prop="numDynamicLicense">
                     <el-input
                         placeholder="请输入"
-                        maxlength="100"
-                        v-autoTrim="{ obj: form, key: 'a4' }"
-                        v-model="form.a4"
+                        maxlength="20"
+                        v-autoTrim="{ obj: form, key: 'numDynamicLicense' }"
+                        v-model="form.numDynamicLicense"
                     >
                     </el-input>
                 </el-form-item>
+                <el-form-item label="到期时间:" prop="dateDynamicLicense">
+                    <el-date-picker
+                        v-model="form.dateDynamicLicense"
+                        type="date"
+                        placeholder="选择日期"
+                        value-format="yyyy-MM-dd"
+                    ></el-date-picker>
+                </el-form-item>
             </div>
         </el-form>
-        <div class="title">公有</div>
+        <div class="title">历史记录</div>
         <tableList
             ref="table"
             style="width:60%;min-width: 900px;margin: auto;"
             :columns="columns"
             :getDataWay="getDataWay"
-            :checkedData="checkedData"
             index
-            selection
         >   
         </tableList>
         <div class="btns">
@@ -73,60 +93,105 @@ export default {
     components: {tableList},
     data() {
         return {
+            useTypeList: [],
             getDataWay:{
-                //dataType: "url",
-                dataType: "data",
+                dataType: "url",
                 type: "post",
-                // firstRequest: false,
-                // data: this.$api.algorithmsLibrary.selectSharedAlgorithmList,
-                data:[{a1:'1',a2:'2',a3:'3',a4:'4'}],
-                param: {},
+                firstRequest: false,
+                data: this.$api.systemManagement.getClusterHistory,
+                param: {
+                    //userId: this.$route.query.userId
+                },
             },
             columns: [
                 //表格列
                 {
-                    label: "账户名",
-                    prop: "a1",
+                    label: "仿真软件license",
+                    prop: "numSimulationLicense",
                 },
                 {
-                    label: "账户类型",
-                    prop: "a2",
+                    label: "到期时间",
+                    prop: "dateSimulationLicense",
+                    formatter:(data)=>{
+                        return data.dateSimulationLicense.slice(0,10)
+                    }
                 },
                 {
-                    label: "联系人",
-                    prop: "a3",
+                    label: "动力学软件license",
+                    prop: "numDynamicLicense",
                 },
                 {
-                    label: "联系方式",
-                    prop: "a4",
+                    label: "到期时间",
+                    prop: "dateDynamicLicense",
+                    formatter:(data)=>{
+                        return data.dateDynamicLicense.slice(0,10)
+                    }
                 },
+                {
+                    label: "操作时间",
+                    prop: "modifyTime",
+                    formatter:(data)=>{
+                        return this.$timeFormatter(data.modifyTime)
+                    }
+                }
             ],
             form: {
-                a1:'',
-                a2:'',
-                a3:'',
-                a4:''
+                userName:"",
+                useType: "",
+                id: "",
+                userId: "",
+                numSimulationLicense: "",
+                dateSimulationLicense: "",
+                numDynamicLicense: "",
+                dateDynamicLicense: ""
             },
-            
             rules: {
+                numSimulationLicense: [{ required: true, message: "请输入", trigger: "blur" }],
+                dateSimulationLicense: [{ required: true, message: "请选择", trigger: "blur" }],
+                numDynamicLicense: [{ required: true, message: "请输入", trigger: "blur" }],
+                dateDynamicLicense: [{ required: true, message: "请选择", trigger: "blur" }]
             }
         };
     },
-
+    created(){
+        if(this.$route.query.userId){
+            this.form = {...this.$route.query}
+            delete this.form.modifyTime
+        }
+    },
+    async mounted() {
+        if(this.$route.query.userId){
+            this.getDataWay.param = {
+                userId: this.$route.query.userId
+            }
+            this.$refs.table.loadData()
+        }
+        await this.$dicsListsInit({
+            useTypeList: "useType"
+        });
+    },
     computed: {},
-
     methods: {
         save(){
-
+            this.$axios({
+                method:"POST",
+                url:this.$api.systemManagement.saveCluster,
+                data:{
+                    ...this.form
+                }
+            }).then(res=>{
+                if(res.code == 200){
+                    this.$message.success("保存成功");
+                    this.cancel()
+                }else{
+                    this.$message.error(res.message || "保存失败");
+                }
+            })
         },
         cancel(){
-
+            this.$router.replace({path: '/clusteringManagement'})
         },
     },
-
-    mounted() {
-        
-    },
 };
 </script>
 

+ 127 - 35
src/views/systemManagement/clusteringManagement.vue

@@ -5,41 +5,60 @@
             <template slot="searchItem1">
                 <span class="label">分配账户</span>
                 <el-input
-                    v-model="searchParams.a1"
+                    v-model="searchParams.userName"
                     size="small"
                     clearable
                     placeholder="请输入"
                 >
                 </el-input>
             </template>
+            <template slot="searchItem2">
+                <span class="label">操作时间</span>
+                <el-date-picker
+                    v-model="modifyTimeRange"
+                    type="daterange"
+                    format="yyyy-MM-dd"
+                    value-format="yyyy-MM-dd"
+                    range-separator="至"
+                    start-placeholder="开始日期"
+                    end-placeholder="结束日期"
+                >
+                </el-date-picker>
+            </template>
             <template slot="searchItem3">
-                <span class="label">节点类型</span>
-                <el-select v-model="searchParams.a2">
-                    <el-option
-                        v-for="item in list"
-                        :label="item.caption"
-                        :value="item.code"
-                        :key="item.code"
-                    ></el-option>
-                </el-select>
+                <span class="label">到期时间</span>
+                <el-date-picker
+                    v-model="dueTimeRange"
+                    type="daterange"
+                    format="yyyy-MM-dd"
+                    value-format="yyyy-MM-dd"
+                    range-separator="至"
+                    start-placeholder="开始日期"
+                    end-placeholder="结束日期"
+                >
+                </el-date-picker>
             </template>
             <template slot="searchBtn1">
-                <el-button type="primary">查询</el-button>
+                <el-button type="primary" @click="doSearch">查询</el-button>
             </template>
             <template slot="searchBtn2">
-                <el-button type="primary">重置</el-button>
+                <el-button type="primary" @click="reset">重置</el-button>
             </template>
         </search-layout>
 
-        <div class="btnsPanel">
+        <!--<div class="btnsPanel">
             <el-button
                 type="primary"
                 icon="el-icon-circle-plus-outline"
                 @click="addConfig"
                 >新建配置</el-button
             >
-        </div>
+        </div>-->
 
+        <div style="border-top: none; margin: 30px 40px 10px 40px">
+            <span>仿真软件已分配未到期节点数量:{{totalSimulation}}</span>
+            <span style="margin-left: 20%">动力学软件已分配未到期节点数量:{{totalDynamic}}</span>
+        </div>
         <tableList
             ref="table"
             style="border-top: none; margin: 0 30px"
@@ -47,18 +66,20 @@
             :getDataWay="getDataWay"
             :pagination="pagination"
             index
-            selection
         >
+            <!--<el-table-column label="独占类型" slot="useType" align="center">
+                <template v-slot="scope">
+                    <span>
+                        {{(useTypeList.find(item=>item.code==scope.row.useType)||{}).caption||''}}
+                    </span>
+                </template>
+            </el-table-column>-->
             <el-table-column label="操作" slot="cgInfos" align="center">
                 <template v-slot="scope">
                     <i
                         @click="addMarkDia(scope.row)"
                         class="el-icon-edit-outline elIcon"
                     ></i>
-                    <i
-                        @click="addMarkDia(scope.row)"
-                        class="el-icon-video-pause elIcon"
-                    ></i>
                 </template>
             </el-table-column>
         </tableList>
@@ -76,26 +97,50 @@ export default {
         return {
             searchParams: {
                 //搜索参数
-
+                userName: "",
+                dueTimeStart: "",
+                dueTimeEnd: "",
+                modifyTimeStart: "",
+                modifyTimeEnd: ""
             },
+            modifyTimeRange:[],
+            dueTimeRange:[],
             list: [],
+            totalSimulation:0,
+            totalDynamic:0,
+            useTypeList:[],
             columns: [
                 //表格列
                 {
-                    label: "节点ID",
-                    prop: "a1",
+                    label: "账户名称",
+                    prop: "userName",
                 },
                 {
-                    label: "节点类型",
-                    prop: "a2",
+                    label: "独占类型",
+                    prop: "useType",
+                    //template:true
                 },
                 {
-                    label: "适用类型",
-                    prop: "a3",
+                    label: "仿真软件license",
+                    prop: "numSimulationLicense",
                 },
                 {
-                    label: "分配账户",
-                    prop: "a4",
+                    label: "到期时间",
+                    prop: "dateSimulationLicense",
+                    formatter:(data)=>{
+                        return data.dateSimulationLicense?data.dateSimulationLicense.slice(0,10):''
+                    }
+                },
+                {
+                    label: "动力学软件license",
+                    prop: "numDynamicLicense",
+                },
+                {
+                    label: "到期时间",
+                    prop: "dateDynamicLicense",
+                    formatter:(data)=>{
+                        return data.dateDynamicLicense?data.dateDynamicLicense.slice(0,10):''
+                    }
                 },
                 {
                     label: "操作",
@@ -112,21 +157,68 @@ export default {
                 layout: "sizes, total, prev, pager, next, jumper",
             },
             getDataWay: {
-                //dataType: "url",
-                dataType: "data",
+                dataType: "url",
                 type: "post",
-                // firstRequest: false,
-                // data: this.$api.algorithmsLibrary.selectSharedAlgorithmList,
-                data:[{a1:'1',a2:'2',a3:'3',a4:'4',a5:'5',a6:'6'}],
+                data: this.$api.systemManagement.getClusterList,
                 param: {},
             },
         };
     },
+    created(){
+        //获取未到期已分配节点数量
+        this.$axios({
+            method:'POST',
+            url:this.$api.systemManagement.getClusterNum,
+            data:{}
+        }).then(res=>{
+            if(res.code=='200'){
+                this.totalSimulation=res.info.totalSimulation
+                this.totalDynamic=res.info.totalDynamic
+            }
+        })
+    },
+    async mounted(){
+        await this.$dicsListsInit({
+            useTypeList: "useType"
+        });
+    },
     methods: {
+        doSearch(){
+            this.searchParams.modifyTimeStart=this.modifyTimeRange[0]||''
+            this.searchParams.modifyTimeEnd=this.modifyTimeRange[1]||''
+            this.searchParams.dueTimeStart=this.modifyTimeRange[0]||''
+            this.searchParams.dueTimeEnd=this.modifyTimeRange[1]||''
+            this.refreshList(this.searchParams)
+        },
+        reset(){
+            this.searchParams = {
+                userName: "",
+                dueTimeStart: "",
+                dueTimeEnd: "",
+                modifyTimeStart: "",
+                modifyTimeEnd: ""
+            }
+            this.modifyTimeRange=[]
+            this.dueTimeRange=[]
+            this.refreshList(this.searchParams)
+        },
+        refreshList(param) {
+            param
+                ? this.$refs["table"].loadData(param)
+                : this.$refs["table"].loadData();
+        },
         addConfig() {
-            this.$router.push({ path: "/clusteringDetail" });
+            this.$router.push({
+                path:'/clusteringDetail'
+            })
+        },
+        addMarkDia(row) {
+            let query = {...row}
+            this.$router.push({
+                path:'/clusteringDetail',
+                query
+            })
         },
-        addMarkDia() {},
     },
 };
 </script>

+ 327 - 0
src/views/systemManagement/editAccount.vue

@@ -0,0 +1,327 @@
+<template>
+    <div>
+        <div  style="padding: 45px 30px 0;">
+            <el-row>
+                <el-col :span="14" :offset="2">
+                     <el-form
+                ref="form"
+                :model="form"
+                :rules="rules"
+                label-width="108px"
+            >
+                <el-form-item label="账户名称:" prop="username">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="30"
+                        v-autoTrim="{ obj: form, key: 'username' }"
+                        v-model="form.username"
+                    >
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="账户类型:" prop="roleCode">
+                    <el-select v-model="form.roleCode" disabled>
+                        <el-option
+                            v-for="item in roleCodeList"
+                            :label="item.caption"
+                            :value="item.code"
+                            :key="item.code"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+
+                <el-form-item label="所属公司:" prop="company">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="30"
+                        v-autoTrim="{ obj: form, key: 'company' }"
+                        v-model="form.company"
+                    >
+                    </el-input>
+                </el-form-item>
+
+                <el-form-item label="联系人:" prop="nickname">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="15"
+                        v-autoTrim="{ obj: form, key: 'nickname' }"
+                        v-model="form.nickname"
+                    >
+                    </el-input>
+                </el-form-item>
+                
+                <el-form-item label="联系方式:" prop="phone">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="15"
+                        v-autoTrim="{ obj: form, key: 'password' }"
+                        v-model="form.phone"
+                    >
+                    </el-input>
+                </el-form-item>
+                <!--
+                <el-form-item label="密码:" prop="password">
+                    <el-input
+                        placeholder="请输入"
+                        type="password"
+                        maxlength="15"
+                        v-autoTrim="{ obj: form.password, key: 'password' }"
+                        v-model="form.password"
+                    >
+                    </el-input>
+                </el-form-item>
+                
+                <el-form-item label="确认密码:" prop="password">
+                    <el-input
+                        placeholder="请输入"
+                        type="password"
+                        maxlength="15"
+                        v-autoTrim="{ obj: form.password, key: 'password' }"
+                        v-model="form.password"
+                    >
+                    </el-input>
+                </el-form-item>
+                -->
+                <el-form-item label="独占类型:" prop="useType">
+                    <el-radio v-for="item in useTypeList" :key="item.code" :label="item.code" v-model="form.useType">{{item.caption}}</el-radio>
+                </el-form-item>
+
+                <div class="btns">
+                    <el-button type="primary" @click="resetPassword">重置密码</el-button>
+                    <el-button type="primary" @click="saveForm">保存</el-button>
+                    <el-button type="primary" plain @click="cancel"
+                    >取消</el-button>
+                </div>
+            </el-form>
+                </el-col>
+                <el-col :span="6">
+                <div class="fileBox">
+                <div class="photo">
+                    <img :src="imgSrc" width="100%" height="100%" />
+                </div>
+                <!--<div class="uploadBox">
+                    <el-button type="primary" plain icon="el-icon-upload2"
+                        >上传头像</el-button
+                    >
+                </div>-->
+            </div>
+                </el-col>
+            </el-row>
+        </div>
+
+        <el-dialog
+            title="编辑账户"
+            :visible.sync="dialogVisible"
+            width="690px"
+            :close-on-click-modal="false"
+            :close-on-press-escape="false"
+        >
+            <el-form
+                ref="formA"
+                :model="formA"
+                :rules="rulesA"
+                label-width="108px"
+            >
+                <el-form-item
+                    label="手机验证码:"
+                    prop="name"
+                    class="getCodeBox"
+                >
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="10"
+                        class="name"
+                        v-autoTrim="{ obj: form, key: 'name' }"
+                        v-model="formA.name"
+                    >
+                        <el-button slot="append" type="primary"
+                            >获取验证码</el-button
+                        >
+                    </el-input>
+                </el-form-item>
+            </el-form>
+            <span slot="footer">
+                <el-button type="primary" @click="dialogVisible = false"
+                    >确 定</el-button
+                >
+                <el-button @click="dialogVisible = false">取 消</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+//import  from '';
+
+export default {
+    name: "editAccount", // 创建账户
+    components: {},
+    data() {
+        return {
+            list: [],
+            roleCodeList: [],
+            useTypeList:[],  //占用类型
+            imgSrc: require("@/assets/common/image/photoF.png"),
+            form: {
+                id: "",
+                username: "",
+                roleCode: "",
+                company: "",
+                nickname: "",
+                phone: "",
+                password: "",
+                useType: ""
+            },
+            rules: {
+                username: [{ required: true, message: "请输入", trigger: "blur" }],
+                roleCode: [{ required: true, message: "请选择", trigger: "change" }],
+                company: [{ required: true, message: "请输入", trigger: "blur" }],
+                nickname: [{ required: true, message: "请输入", trigger: "blur" }],
+                phone: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                    {
+                        validator: (rule, value, callback) => {
+                            if(this.$validatePhone(value)){
+                                callback()
+                            }else{
+                                callback(new Error('格式错误'))
+                            }
+                        },
+                        trigger: "blur"
+                    }
+                ],
+                //password: [{ required: true, message: "请输入", trigger: "blur" }],
+                useType: [{ required: true, message: "请选择", trigger: "change" }],
+            },
+            formA: {
+                name: "",
+            },
+            rulesA: {
+                name: [{ required: true, message: "请输入", trigger: "blur" }],
+            },
+            dialogVisible: false,
+        };
+    },
+    async created(){
+        if(this.$route.query){
+            this.form = {...this.$route.query}
+        }
+    },
+    async mounted() {
+        await this.$dicsListsInit({
+            roleCodeList: "roleCode",
+            useTypeList: "useType"
+        });
+    },
+    computed: {
+
+    },
+    methods: {
+        saveForm(){
+            this.$axios({
+                method:'POST',
+                url:this.$api.systemManagement.saveUser,
+                data:{
+                    ...this.form
+                }
+            }).then(res => {
+                if(res.code == 200){
+                    this.$message.success("保存成功");
+                    this.cancel()      
+                }else{
+                    this.$message.error(res.message || "保存失败");
+                }
+            })
+        },
+        cancel() {
+            this.$router.replace({
+                path: '/accountManagement'
+            })
+        },
+        resetPassword(){
+            this.$axios({
+                method: "POST",
+                url: this.$api.systemManagement.saveDefaultPassword,
+                data: {
+                    id: this.form.id,
+                    username: this.form.username
+                }
+            }).then(res => {
+                if(res.code == "200"){
+                    this.$message.success("重置密码成功")
+                }else{
+                    this.$message.warning(res.message||"重置密码失败")
+                }
+            })
+        }
+    },
+    // mounted: {},
+};
+</script>
+
+<style lang='less' scoped>
+.flexBox.box {
+    padding-top: 45px;
+}
+
+.el-form {
+    flex: 1;
+    padding-bottom: 45px;
+
+    /deep/ .el-input,
+    .el-select {
+        width: 100%;
+    }
+}
+
+.fileBox {
+    text-align: right;
+    padding: 0 5% 0 10%;
+
+    .til {
+        width: 210px;
+        padding-bottom: 10px;
+        margin: 0 auto;
+        text-align: left;
+    }
+
+    .photo {
+        display: inline-block;
+        width: 210px;
+        height: 210px;
+        line-height: 210px;
+        // border-radius: 50%;
+        overflow: hidden;
+
+        // img {
+        //     vertical-align: middle;
+        // }
+    }
+}
+
+.uploadBox {
+    padding-top: 30px;
+    text-align: center;
+}
+
+.editBox {
+    width: 15%;
+    padding-left: 4%;
+    text-align: left;
+}
+
+.btns {
+    padding-top: 30px;
+    text-align: center;
+}
+
+.getCodeBox {
+    .el-button {
+        background-color: @themeColor;
+        color: #ffffff;
+    }
+
+    /deep/ .el-input-group__append {
+        border: 1px solid transparent;
+    }
+}
+</style>

+ 69 - 53
src/views/systemManagement/parameterDetail.vue

@@ -1,7 +1,7 @@
 <!--新增、编辑、查看参数详情-->
 <template>
     <div>
-        <div class="title">选择普通账户</div>
+        <!--<div class="title">选择普通账户</div>
         <tableList
             ref="table"
             style="width:60%;min-width: 900px;margin: auto;"
@@ -12,39 +12,45 @@
             selection
         >
             
-        </tableList>
+        </tableList>-->
         <el-form
             ref="form"
             :model="form"
             :rules="rules"
-            label-width="200px"
+            label-width="220px"
             class="flexBox"
         >
             <div class="formItemBox">
-                <el-form-item label="可创建子账户数量:" prop="projectName">
+                <el-form-item label="账户名称:" prop="userName">
+                    {{form.userName}}
+                </el-form-item>
+                <el-form-item label="可创建子账户数量:" prop="numCreateUser">
                     <el-input
+                        type="number"
                         placeholder="请输入"
-                        maxlength="30"
-                        v-autoTrim="{ obj: form, key: 'projectName' }"
-                        v-model="form.projectName"
+                        maxlength="10"
+                        v-autoTrim="{ obj: form, key: 'numCreateUser' }"
+                        v-model="form.numCreateUser"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="最多可创建场景测试包数量:" prop="parallelism">
+                <el-form-item label="最多可创建场景测试包数量:" prop="numCreateScenePackage">
                     <el-input
+                        type="number"
                         placeholder="请输入"
-                        maxlength="100"
-                        v-autoTrim="{ obj: form, key: 'parallelism' }"
-                        v-model="form.parallelism"
+                        maxlength="10"
+                        v-autoTrim="{ obj: form, key: 'numCreateScenePackage' }"
+                        v-model="form.numCreateScenePackage"
                     >
                     </el-input>
                 </el-form-item>
-                <el-form-item label="场景数据包的最大场景数量:" prop="maxSimulationTime">
+                <el-form-item label="场景数据包的最大场景数量:" prop="numScenePerPackage">
                     <el-input
+                        type="number"
                         placeholder="请输入"
-                        maxlength="100"
-                        v-autoTrim="{ obj: form, key: 'maxSimulationTime' }"
-                        v-model="form.maxSimulationTime"
+                        maxlength="10"
+                        v-autoTrim="{ obj: form, key: 'numScenePerPackage' }"
+                        v-model="form.numScenePerPackage"
                     >
                     </el-input>
                 </el-form-item>
@@ -67,57 +73,60 @@ export default {
     components: {tableList},
     data() {
         return {
-            getDataWay:{
-                //dataType: "url",
-                dataType: "data",
-                type: "post",
-                // firstRequest: false,
-                // data: this.$api.algorithmsLibrary.selectSharedAlgorithmList,
-                data:[{a1:'1',a2:'2',a3:'3',a4:'4'}],
-                param: {},
-            },
-            columns: [
-                //表格列
-                {
-                    label: "账户名",
-                    prop: "a1",
-                },
-                {
-                    label: "账户类型",
-                    prop: "a2",
-                },
-                {
-                    label: "联系人",
-                    prop: "a3",
-                },
-                {
-                    label: "联系方式",
-                    prop: "a4",
-                },
-            ],
             form: {
-                
+                id:'',
+                userId:'',
+                userName:'111',
+                numCreateUser: '',
+                numCreateScenePackage: '',
+                numScenePerPackage: '',
             },
-            
             rules: {
+                numCreateUser:  [{ required: true, message: "请输入", trigger: "blur" }],
+                numCreateScenePackage:  [{ required: true, message: "请输入", trigger: "blur" }],
+                numScenePerPackage:  [{ required: true, message: "请输入", trigger: "blur" }],
             }
         };
     },
-
     computed: {},
-
+    async created(){
+        if(this.$route.query){
+            this.form = {...this.$route.query}
+            delete this.form.modifyTime
+        }
+        /*获取修改历史
+        this.$axios({
+            method:'POST',
+            url:this.$api.systemManagement.getParamHistory,
+            data:{
+                userId: this.$route.query.userId
+            }
+        })
+        */
+    },
     methods: {
         save(){
-
+            this.$axios({
+                method:'POST',
+                url:this.$api.systemManagement.saveParameter,
+                data:{
+                    ...this.form
+                }
+            }).then(res => {
+                if(res.code == 200){
+                    this.$message.success("保存成功");
+                    this.cancel()    
+                }else{
+                    this.$message.error(res.message || "保存失败");
+                }
+            })
         },
         cancel(){
-
+            this.$router.replace({
+                path: '/parameterManagement'
+            })
         },
     },
-
-    mounted() {
-        
-    },
 };
 </script>
 
@@ -156,4 +165,11 @@ export default {
     font-size: 16px;
     font-weight: bold;
 }
+/deep/ input::-webkit-outer-spin-button,
+/deep/ input::-webkit-inner-spin-button {
+  -webkit-appearance: none !important;
+}
+/deep/ input[type='number'] {
+  -moz-appearance: textfield !important;
+}
 </style>

+ 27 - 20
src/views/systemManagement/parameterManagement.vue

@@ -5,7 +5,7 @@
             <template slot="searchItem1">
                 <span class="label">账户名</span>
                 <el-input
-                    v-model="searchParams.algorithmCode"
+                    v-model="searchParams.userName"
                     size="small"
                     clearable
                     placeholder="请输入"
@@ -23,13 +23,13 @@
         </search-layout>
 
         <div class="myTabsBox myTabsBoxThreeTabs">
-            <el-button
+            <!--<el-button
                 v-bind:class="{ addBtn: true}"
                 icon="el-icon-circle-plus-outline"
                 @click="addOne"
                 type="primary"
                 >新增参数配置</el-button
-            >
+            >-->
         </div>
 
         <tableList
@@ -47,11 +47,11 @@
                         class="el-icon-edit-outline elIcon"
                         title="编辑"
                     ></i>
-                    <i
+                    <!--<i
                         @click="delOne(scope.row)"
                         class="el-icon-delete elIcon"
                         title="删除"
-                    ></i>
+                    ></i>-->
                 </template>
             </el-table-column>
         </tableList>
@@ -69,35 +69,38 @@ export default{
         return {
             searchParams: {
                 //搜索参数
-                
+                userName:''
             },
-            validationStatusList: [],
             getDataWay:{
-                //dataType: "url",
-                dataType: "data",
+                dataType: "url",
                 type: "post",
-                // firstRequest: false,
-                // data: this.$api.algorithmsLibrary.selectSharedAlgorithmList,
-                data:[{a1:'1',a2:'2',a3:'3',a4:'4'}],
+                data: this.$api.systemManagement.getParameterList,
                 param: {},
             },
             columns: [
                 //表格列
                 {
-                    label: "账户名",
-                    prop: "a1",
+                    label: "账户名",
+                    prop: "userName",
                 },
                 {
                     label: "可创建子账户数量",
-                    prop: "a2",
+                    prop: "numCreateUser",
                 },
                 {
                     label: "最多可创建场景测试包数量",
-                    prop: "a3",
+                    prop: "numCreateScenePackage",
                 },
                 {
                     label: "场景数量包的最大场景数",
-                    prop: "a4",
+                    prop: "numScenePerPackage",
+                },
+                {
+                    label: "创建时间",
+                    prop: "modifyTime",
+                    formatter: (data) => {
+                        return this.$timeFormatter(data.modifyTime)
+                    }
                 },
                 {
                     label: "操作",
@@ -128,7 +131,7 @@ export default{
         },
         doReset() {
             this.searchParams = {
-                
+                userName:''
             };
             this.doSearch();
         },
@@ -136,7 +139,11 @@ export default{
             this.$router.push("/parameterDetail")
         },
         editRow(row) {
-            
+            let query = {...row}
+            this.$router.push({
+                path: 'parameterDetail',
+                query
+            })
         },
         delOne(row) {
             this.$confirm("确认是否删除?", "提示", {
@@ -163,6 +170,6 @@ export default{
     }
 }
 .myTabsBox{
-    min-height:99px;
+    min-height:29px;
 }
 </style>

+ 514 - 0
src/views/workManagement/autoRunProjectDetail.vue

@@ -0,0 +1,514 @@
+<template>
+    <div>
+        <el-form
+            ref="form"
+            :model="form"
+            :rules="rules"
+            label-width="120px"
+            class="flexBox"
+        >
+            <div class="formItemBox">
+                <el-form-item label="项目名称:" prop="projectName">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="30"
+                        v-autoTrim="{ obj: form, key: 'projectName' }"
+                        v-model="form.projectName"
+                    >
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="项目描述:" prop="projectDescribe">
+                    <el-input
+                        type="textarea"
+                        :autosize="{ minRows: 4, maxRows: 4 }"
+                        placeholder="请输入"
+                        maxlength="300"
+                        v-autoTrim="{ obj: form, key: 'projectDescribe' }"
+                        v-model="form.projectDescribe"
+                    >
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="算法来源:" prop="algorithmType">
+                    <el-radio
+                        v-model="form.algorithmType"
+                        label="1"
+                        @change="typeChange"
+                        >私有导入</el-radio
+                    >
+                    <el-radio
+                        v-model="form.algorithmType"
+                        label="3"
+                        @change="typeChange"
+                        >算法平台</el-radio
+                    >
+                </el-form-item>
+                <el-form-item label="选择算法:" prop="algorithm">
+                    <el-select v-model="form.algorithm">
+                        <el-option
+                            v-for="item in algorithmList"
+                            :label="item.name"
+                            :value="item.id"
+                            :key="item.id"
+                            :title="item.description"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="选择车辆:" prop="vehicle">
+                    <el-select
+                        v-model="form.vehicle"
+                        @change="vehicleSelChange"
+                    >
+                        <el-option
+                            v-for="item in vehicleList"
+                            :label="item.name"
+                            :value="item.id"
+                            :key="item.id"
+                            :title="item.description"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="选择场景:" prop="scene">
+                    <el-select v-model="form.scene" @change="sceneSelChange">
+                        <el-option
+                            v-for="item in sceneList"
+                            :label="item.name"
+                            :value="item.id"
+                            :key="item.id"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="并行度:" prop="parallelism">
+                    <el-input
+                        :disabled="runDisabled"
+                        placeholder="请输入"
+                        maxlength="10"
+                        v-autoTrim="{ obj: form, key: 'parallelism' }"
+                        v-model="form.parallelism"
+                    >
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="最大仿真时间:" prop="maxSimulationTime">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="10"
+                        v-autoTrim="{ obj: form, key: 'maxSimulationTime' }"
+                        v-model="form.maxSimulationTime"
+                    >
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="运行周期:" prop="operationCycle">
+                    <el-input
+                        placeholder="请输入"
+                        maxlength="60"
+                        v-autoTrim="{ obj: form, key: 'operationCycle' }"
+                        v-model="form.operationCycle"
+                    >
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="是否选择GPU:" prop="isChoiceGpu">
+                    <el-radio v-model="form.isChoiceGpu" label="0">是</el-radio>
+                    <el-radio v-model="form.isChoiceGpu" label="1">否</el-radio>
+                </el-form-item>
+            </div>
+
+            <div class="tipBox">
+                <div class="tip tipA">
+                    <!-- (传感器1:根据车辆自动带出;传感器2:根据车辆自动带出) -->
+                    <span
+                        v-for="item in sensors"
+                        :key="item"
+                        v-bind:class="{
+                            iconA: item === 'camera',
+                            iconB: item === 'ogt',
+                            iconC: item === 'lidar',
+                            iconE: item === 'gps',
+                        }"
+                    ></span>
+                </div>
+                <div class="tip">(场景数量:{{ sceneCount }})</div>
+                <!-- <div class="tip flexBox">
+                    <div>(下次运行时间:XX时XX分XX秒)</div>
+                    <div class="tipBtnBox">
+                        <el-button type="primary">规则查看</el-button>
+                    </div>
+                </div> -->
+                <div class="tip">(最多可用资源:{{ maxCount }})</div>
+                <div class="tip">(最小是5,最大是60)</div>
+            </div>
+        </el-form>
+
+        <div class="ruleTip">
+            <el-collapse v-model="activeNames">
+                <el-collapse-item title="运行周期规则查看" name="1">
+                    <div class="collapseInfo">
+                        运行周期规则查看
+                    </div>
+                </el-collapse-item>
+            </el-collapse>
+        </div>
+
+        <div class="btns">
+            <el-button type="primary" @click="save(false)">保存</el-button>
+            <el-button
+                type="primary"
+                @click="save(true)"
+                v-if="this.$route.query.id"
+                >另存为</el-button
+            >
+            <el-button
+                type="primary"
+                @click="save(false, true)"
+                :disabled="runDisabled"
+                >提交</el-button
+            >
+            <el-button type="primary" plain @click="cancel">取消</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+//import  from '';
+let maxCount = 0; // 用于校验
+let validateNum = (rule, value, callback) => {
+    !/^(\d+)$/.test(value) && callback(new Error(rule.message));
+    if (value <= 0 || value > maxCount) callback(new Error(rule.message));
+    callback();
+};
+let validateNumA = (rule, value, callback) => {
+    !/^(\d+)$/.test(value) && callback(new Error(rule.message));
+    if (value < 5 || value > 60) callback(new Error(rule.message));
+    callback();
+};
+let validateNumB = (rule, value, callback) => {
+    !/^(\d+)$/.test(value) && callback(new Error(rule.message));
+    if (value <= 0) callback(new Error(rule.message));
+    callback();
+};
+
+export default {
+    name: "autoRunProjectDetail", // 自动运行项目详情
+    components: {},
+    data() {
+        return {
+            form: {
+                id: "",
+                projectName: "", // 项目名称
+                projectDescribe: "", // 项目描述
+                algorithmType: "1", // 算法来源
+                algorithm: "", // 选择算法
+                vehicle: "", // 选择车辆
+                scene: "", // 选择场景
+                parallelism: "", // 并行度
+                maxSimulationTime: "", // 最大仿真时间
+                isChoiceGpu: "0", // 是否选择GPU
+                nowRunState: "10", // 运行状态
+                operationCycle: "", // 运行周期
+            },
+            algorithmList: [], // 算法对应列表
+            vehicleList: [], // 车辆对应列表
+            sceneList: [], // 场景对应列表
+            maxCount: 0, // 最多可用资源
+            sceneCount: 0, // 场景数量
+            rules: {
+                projectName: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                ],
+                projectDescribe: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                ],
+                algorithmType: [
+                    { required: true, message: "请选择", trigger: "change" },
+                ],
+                algorithm: [
+                    { required: true, message: "请选择", trigger: "change" },
+                ],
+                vehicle: [
+                    { required: true, message: "请选择", trigger: "change" },
+                ],
+                scene: [
+                    { required: true, message: "请选择", trigger: "change" },
+                ],
+                parallelism: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                ],
+                maxSimulationTime: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                    {
+                        validator: validateNumA,
+                        message: "请输入不小于5且不大于60的正整数",
+                        trigger: ["blur"],
+                    },
+                ],
+                isChoiceGpu: [
+                    { required: true, message: "请选择", trigger: "change" },
+                ],
+                operationCycle: [
+                    { required: true, message: "请输入", trigger: "blur" },
+                ],
+            },
+            sensors: [], // 选中车辆后对应的传感器数组
+            activeNames: [""],
+            runDisabled: false, // 若最多可用资源为0,则不可点击"提交"
+        };
+    },
+
+    computed: {},
+
+    methods: {
+        async getLists(dropDownType = "") {
+            await this.$axios({
+                method: "post",
+                url: this.$api.workManagement.selectDropDownByType,
+                data: {
+                    dropDownType,
+                    algorithmType: this.form.algorithmType,
+                },
+            }).then((res) => {
+                if (res.code == 200 && res.info) {
+                    res.info.forEach((item) => {
+                        if (item.type === "1") {
+                            this.algorithmList = item.dropDownList;
+                        } else if (item.type === "2") {
+                            this.vehicleList = item.dropDownList;
+                        } else if (item.type === "3") {
+                            this.sceneList = item.dropDownList;
+                        }
+                        // 空表示第一次进,有值表示在切换算法来源,需要清空选择算法的值
+                        if (dropDownType) {
+                            this.form.algorithm = "";
+                            this.$nextTick(() => {
+                                this.$refs.form.clearValidate("algorithm");
+                            });
+                        }
+                    });
+                } else {
+                    this.$message.error(res.message || "获取信息失败");
+                }
+            });
+        },
+        typeChange() {
+            this.getLists("1");
+        },
+        async getMaxSimulationTime() {
+            await this.$axios({
+                method: "post",
+                url: this.$api.workManagement.selectMaxParallelism,
+                data: {},
+            }).then((res) => {
+                // res.info = 10;
+                if (res.code == 200 && res.info && res.info != 0) {
+                    this.maxCount = maxCount = res.info;
+                    if (res.info == -1) {
+                        this.rules.parallelism.push({
+                            validator: validateNumB,
+                            message: "请输入正整数",
+                            trigger: ["blur"],
+                        });
+                    } else {
+                        this.rules.parallelism.push({
+                            validator: validateNum,
+                            message: "请输入不大于最多可用资源的正整数",
+                            trigger: ["blur"],
+                        });
+                    }
+                } else if (res.code == 200 && res.info == 0) {
+                    this.maxCount = maxCount = 0;
+                    this.runDisabled = true;
+                    this.form.parallelism = 0;
+                } else {
+                    this.$message.error(res.message || "获取信息失败");
+                }
+            });
+        },
+        sceneSelChange(item) {
+            this.sceneCount = this.sceneList.find(
+                (i) => i.id === item
+            ).sceneNum;
+        },
+        vehicleSelChange(item) {
+            let sensor = this.vehicleList.find((i) => i.id === item).sensor;
+
+            if (!sensor) {
+                this.sensors = [];
+            } else {
+                this.sensors = sensor.split(",");
+            }
+        },
+        save(isAdd = false, needChange = false) {
+            // isAdd是否强制新增,needChange是否需要改变状态
+            this.$refs.form.validate((valid) => {
+                if (valid) {
+                    if (isAdd) {
+                        // 另存为
+                        this.form.id = "";
+                    }
+
+                    this.form.nowRunState = "10";
+
+                    this.$axios({
+                        method: "post",
+                        url: this.$api.workManagement
+                            .addOrUpdateAutomaticProject,
+                        data: {
+                            ...this.form,
+                        },
+                    }).then((res) => {
+                        if (res.code == 200) {
+                            this.$message.success("保存成功");
+                            if (needChange) {
+                                this.form.id = res.info;
+                                this.stateChange();
+                            } else {
+                                this.cancel();
+                            }
+                        } else {
+                            this.$message.error(res.message || "保存失败");
+                        }
+                    });
+                }
+            });
+        },
+        cancel() {
+            this.$router.replace({ path: "/autoRunProjectList" });
+        },
+        stateChange() {
+            this.$axios({
+                method: "post",
+                url: this.$api.workManagement.updateAutomaticRunState,
+                data: {
+                    id: this.form.id,
+                    automaticRunState: "0",
+                },
+            }).then((res) => {
+                if (res.code == 200) {
+                    this.$message.success("提交成功");
+                    this.cancel();
+                } else {
+                    this.$message.error(res.message || "提交失败");
+                }
+            });
+        },
+    },
+
+    mounted() {
+        if (this.$route.query.id) {
+            let id = "";
+            this.form.id = id = this.$route.query.id;
+
+            if (id) {
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.selectAutomaticProjectById,
+                    data: {
+                        id,
+                    },
+                }).then(async (res) => {
+                    if (res.code == 200 && res.info) {
+                        this.form = res.info;
+                        await this.getLists();
+                        await this.getMaxSimulationTime();
+                        this.vehicleSelChange(res.info.vehicle);
+                        this.sceneSelChange(res.info.scene);
+                    } else {
+                        this.$message.error(res.message || "获取信息失败");
+                    }
+                });
+            }
+        } else {
+            this.getLists();
+            this.getMaxSimulationTime();
+        }
+    },
+};
+</script>
+
+<style lang='less' scoped>
+.el-form {
+    width: 60%;
+    min-width: 900px;
+    padding-top: 60px;
+    margin: 0 auto;
+
+    .formItemBox {
+        flex: 1;
+
+        /deep/ .el-input,
+        .el-select {
+            width: 100%;
+        }
+    }
+
+    .el-textarea {
+        height: 96px;
+    }
+
+    .tipBox {
+        min-width: 270px;
+        margin-left: 20px;
+
+        .tip {
+            margin-bottom: 22px;
+            line-height: 32px;
+        }
+
+        .tipA {
+            height: 32px;
+            // 按54往上加
+            margin-top: 280px;
+
+            .iconA {
+                background: url("../../assets/common/image/sensor/001.png")
+                    center no-repeat;
+                background-size: contain;
+            }
+            .iconB {
+                background: url("../../assets/common/image/sensor/002.png")
+                    center no-repeat;
+                background-size: contain;
+            }
+            .iconC {
+                background: url("../../assets/common/image/sensor/003.png")
+                    center no-repeat;
+                background-size: contain;
+            }
+            .iconD {
+                background: url("../../assets/common/image/sensor/004.png")
+                    center no-repeat;
+                background-size: contain;
+            }
+            .iconE {
+                background: url("../../assets/common/image/sensor/005.png")
+                    center no-repeat;
+                background-size: contain;
+            }
+
+            span {
+                display: inline-block;
+                width: 18px;
+                height: 18px;
+                margin-top: 7px;
+                margin-right: 6px;
+            }
+        }
+
+        .tipB {
+            padding-top: 54px;
+        }
+
+        .tipBtnBox {
+            margin-left: 20px;
+        }
+    }
+}
+
+.ruleTip {
+    width: 60%;
+    min-width: 900px;
+    margin: 0 auto;
+}
+
+.btns {
+    padding-top: 30px;
+    text-align: center;
+}
+</style>

+ 391 - 0
src/views/workManagement/autoRunProjectList.vue

@@ -0,0 +1,391 @@
+<template>
+    <div>
+        <div v-if="!$route.path.includes('autoRunSubProjectList')">
+            <search-layout :needBox="true">
+                <template slot="searchItem1">
+                    <span class="label">项目ID</span>
+                    <el-input
+                        v-model="searchParams.projectId"
+                        size="small"
+                        clearable
+                        placeholder="请输入"
+                        maxlength="60"
+                        @keyup.enter.native="doSearch"
+                    >
+                    </el-input>
+                </template>
+                <template slot="searchItem2">
+                    <span class="label">项目名称</span>
+                    <el-input
+                        v-model="searchParams.projectName"
+                        size="small"
+                        clearable
+                        placeholder="请输入"
+                        maxlength="60"
+                        @keyup.enter.native="doSearch"
+                    >
+                    </el-input>
+                </template>
+                <template slot="searchItem3">
+                    <span class="label">创建时间</span>
+                    <el-date-picker
+                        v-model="createDate"
+                        type="daterange"
+                        format="yyyy-MM-dd"
+                        value-format="yyyy-MM-dd"
+                        range-separator="至"
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期"
+                    >
+                    </el-date-picker>
+                </template>
+
+                <template slot="searchBtn1">
+                    <el-button type="primary" @click="doSearch">查询</el-button>
+                </template>
+                <template slot="searchBtn2">
+                    <el-button type="primary" @click="doReset">重置</el-button>
+                </template>
+            </search-layout>
+
+            <div class="btnsPanel">
+                <el-button
+                    type="primary"
+                    plain
+                    icon="el-icon-delete"
+                    @click="delRows"
+                    >批量删除</el-button
+                >
+                <el-button
+                    type="primary"
+                    icon="el-icon-circle-plus-outline"
+                    @click="addOne"
+                    >创建</el-button
+                >
+            </div>
+
+            <tableList
+                ref="table"
+                style="margin: 0 30px"
+                :columns="columns"
+                :getDataWay="getDataWay"
+                :pagination="pagination"
+                :checkedData="checkedArr"
+                selection
+                index
+            >
+                <el-table-column
+                    label="停/启用"
+                    slot="automaticRunState"
+                    align="center"
+                >
+                    <template v-slot="scope">
+                        <el-switch
+                            v-model="scope.row.automaticRunState"
+                            active-value="0"
+                            inactive-value="1"
+                            active-color="#3397FF"
+                            inactive-color="#ff4949"
+                            @change="
+                                ($event) => {
+                                    switchVisible($event, scope.row);
+                                }
+                            "
+                        ></el-switch>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" slot="cgInfos" align="center">
+                    <template v-slot="scope">
+                        <i
+                            @click="runRow(scope.row.id, scope.row.parallelism)"
+                            class="el-icon-video-play elIcon"
+                            title="运行"
+                        ></i>
+                        <i
+                            @click="editRow(scope.row)"
+                            class="el-icon-edit-outline elIcon"
+                            title="编辑"
+                        ></i>
+                        <i
+                            @click="viewRow(scope.row.id)"
+                            class="el-icon-view elIcon"
+                            title="查看"
+                        ></i>
+                        <i
+                            v-if="scope.row.automaticRunState === '1'"
+                            @click="delRow(scope.row.id)"
+                            class="el-icon-delete elIcon"
+                            title="删除"
+                        ></i>
+                        <!-- 停用的时候显示删除 automaticRunState 0是启用 1是停用 -->
+                    </template>
+                </el-table-column>
+            </tableList>
+        </div>
+        <router-view v-else></router-view>
+    </div>
+</template>
+
+<script>
+import searchLayout from "@/components/grid/searchLayout";
+import tableList from "@/components/grid/TableList";
+
+export default {
+    name: "autoRunProjectList", // 自动运行项目列表
+    components: { searchLayout, tableList },
+    data() {
+        return {
+            searchParams: {
+                //搜索参数
+                projectId: "", //项目ID
+                projectName: "", //项目名称
+                createStartDate: "", //创建时间起
+                createEndDate: "", //创建时间止
+            },
+            createDate: "",
+            columns: [
+                {
+                    label: "项目ID",
+                    prop: "projectId",
+                },
+                {
+                    label: "项目名称",
+                    prop: "projectName",
+                },
+                {
+                    label: "创建时间",
+                    prop: "createTimeFmt",
+                },
+                {
+                    label: "算法名称",
+                    prop: "algorithm",
+                },
+                {
+                    label: "自动运行次数",
+                    prop: "automaticRunTimes",
+                },
+                {
+                    label: "最近运行时间",
+                    prop: "lastRunTimeFmt",
+                },
+                {
+                    label: "停/启用",
+                    prop: "automaticRunState",
+                    template: true,
+                },
+                {
+                    label: "操作",
+                    prop: "cgInfos",
+                    template: true,
+                },
+            ],
+            pagination: {
+                //分页使用
+                currentPage: 1,
+                pageSize: 10,
+                position: "right",
+                pageSizes: [10, 30, 50, 100, 200],
+                layout: "sizes, total, prev, pager, next, jumper",
+            },
+            getDataWay: {
+                //加载表格数据
+                dataType: "url",
+                type: "post",
+                // firstRequest: false,
+                data: this.$api.workManagement.selectAutomaticProject,
+                param: {},
+            },
+            checkedArr: [],
+            curRow: {}, // 当前row
+        };
+    },
+    methods: {
+        doSearch() {
+            if (this.createDate) {
+                this.searchParams.createStartDate = `${this.createDate[0]}`;
+                this.searchParams.createEndDate = `${this.createDate[1]}`;
+            } else {
+                this.searchParams.createStartDate = "";
+                this.searchParams.createEndDate = "";
+            }
+
+            let pageMap = {
+                projectId: this.searchParams.projectId,
+                projectName: this.searchParams.projectName,
+                createStartDate: this.searchParams.createStartDate,
+                createEndDate: this.searchParams.createEndDate,
+            };
+            this.refreshList(pageMap);
+        },
+        //刷新table
+        refreshList(param) {
+            param
+                ? this.$refs["table"].loadData(param)
+                : this.$refs["table"].loadData();
+        },
+        doReset() {
+            this.searchParams = {
+                projectId: "",
+                projectName: "",
+                createStartDate: "",
+                createEndDate: "",
+            };
+            this.createDate = "";
+            this.doSearch();
+        },
+        addOne() {
+            this.$router.push({ path: "/autoRunProjectDetail" });
+        },
+        switchVisible(value, row) {
+            // 停用
+            if (value === "1") {
+                row.automaticRunState = "0";
+                this.$confirm("确认该项目停用自动运行?", "提示", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning",
+                }).then(() => {
+                    this.$axios({
+                        method: "POST",
+                        url: this.$api.workManagement.updateAutomaticRunState,
+                        data: {
+                            id: row.id,
+                            automaticRunState: "1",
+                        },
+                    }).then((res) => {
+                        if (res.code == 200) {
+                            row.automaticRunState = "1";
+                            this.$message.success("停用成功");
+                        } else {
+                            this.$message.error(res.message || "停用失败");
+                        }
+                    });
+                });
+            } else {
+                // 启用
+                row.automaticRunState = "1";
+                this.$confirm("确认该项目启用自动运行?", "提示", {
+                    confirmButtonText: "确定",
+                    cancelButtonText: "取消",
+                    type: "warning",
+                }).then(() => {
+                    this.$axios({
+                        method: "POST",
+                        url: this.$api.workManagement.updateAutomaticRunState,
+                        data: {
+                            id: row.id,
+                            automaticRunState: "0",
+                        },
+                    }).then((res) => {
+                        if (res.code == 200) {
+                            row.automaticRunState = "0";
+                            this.$message.success("启用成功");
+                        } else {
+                            this.$message.error(res.message || "启用失败");
+                        }
+                    });
+                });
+            }
+        },
+        editRow(row) {
+            this.$router.push({
+                path: "/autoRunProjectDetail",
+                query: {
+                    id: row.id,
+                },
+            });
+        },
+        runRow(id, parallelism) {
+            this.$confirm("确认是否运行?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            }).then(() => {
+                if (parallelism == "0") {
+                    this.$message.error("并行度为0,不能运行");
+                    return;
+                }
+
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.createAutomaticSubProject,
+                    data: { id },
+                }).then((res) => {
+                    if (res.code == 200) {
+                        this.$message.success("运行成功");
+                    } else {
+                        this.$message.error(res.message || "运行失败");
+                    }
+                    this.doSearch();
+                });
+            });
+        },
+        delRow(ids) {
+            this.$confirm("确认是否删除?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            }).then(() => {
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.deleteAutomaticProjectByids,
+                    data: {
+                        ids,
+                    },
+                }).then((res) => {
+                    if (res.code == 200) {
+                        this.$message.success("删除成功");
+                    } else {
+                        this.$message.error(res.message || "删除失败");
+                    }
+                    this.doSearch();
+                });
+            });
+        },
+        delRows() {
+            let checkedArr = this.checkedArr;
+            if (checkedArr.length <= 0) {
+                this.$message.info("请先选择数据");
+                return;
+            }
+
+            let arr = [];
+
+            for (let index = 0; index < checkedArr.length; index++) {
+                const row = checkedArr[index];
+                if (row.automaticRunState != "1") {
+                    this.$message.error("存在未停用数据,请重新选择");
+                    return;
+                }
+                arr.push(row.id);
+            }
+
+            this.delRow(arr.join(","));
+        },
+
+        viewRow(id) {
+            this.$router.push({
+                path: "/autoRunProjectList/autoRunSubProjectList",
+                query: { id },
+            });
+        },
+    },
+
+    mounted() {},
+};
+</script>
+
+<style lang='less' scoped>
+.btnsPanel {
+    margin: 45px 40px 15px;
+    text-align: right;
+}
+
+.checkboxPanel {
+    text-align: center;
+
+    .labelA {
+        margin-right: 60px;
+    }
+}
+</style>

+ 390 - 0
src/views/workManagement/autoRunSubProjectList.vue

@@ -0,0 +1,390 @@
+<template>
+    <div>
+        <div v-if="!$route.path.includes('projectInfo')">
+            <div class="box">
+                <div class="info">
+                    <span>项目名称:</span>
+                    <b>{{ info.projectName }}</b>
+                </div>
+                <div class="info">
+                    <span>项目描述:</span>
+                    <b>{{ info.projectDescribe }}</b>
+                </div>
+                <div class="info">
+                    <span>算法名称:</span>
+                    <b>{{ info.algorithmName }}</b>
+                </div>
+                <div class="info">
+                    <span>车辆:</span>
+                    <b>{{ info.vehicle }}</b>
+                </div>
+                <div class="info">
+                    <span>场景:</span>
+                    <b>{{ info.sceneName }}</b>
+                </div>
+                <div class="info">
+                    <span>最大仿真时间:</span>
+                    <b>{{ info.maxSimulationTime }}</b>
+                </div>
+                <div class="info">
+                    <span>运行周期:</span>
+                    <b>{{ info.operationCycle }}</b>
+                </div>
+                <div class="info">
+                    <span>并行度:</span>
+                    <b>{{ info.parallelism }}</b>
+                </div>
+                <div class="info">
+                    <span>是否选择GPU:</span>
+                    <b>{{ info.isChoiceGpu }}</b>
+                </div>
+            </div>
+
+            <tableList
+                ref="table"
+                style="margin: 0 30px"
+                :columns="columns"
+                :getDataWay="getDataWay"
+                :pagination="pagination"
+                index
+            >
+                <el-table-column label="操作" slot="cgInfos" align="center">
+                    <template v-slot="scope">
+                        <i
+                            @click="viewRow(scope.row.id)"
+                            class="el-icon-view elIcon"
+                            title="查看"
+                        ></i>
+                        <i
+                            v-if="scope.row.nowRunState === '30'"
+                            @click="downRow(scope.row)"
+                            class="el-icon-download elIcon"
+                            title="下载"
+                        ></i>
+                        <i
+                            v-if="scope.row.nowRunState != '20'"
+                            @click="delRow(scope.row.id)"
+                            class="el-icon-delete elIcon"
+                            title="删除"
+                        ></i>
+                        <i
+                            v-if="scope.row.nowRunState === '20'"
+                            @click="stopRow(scope.row.id)"
+                            class="el-icon-video-pause elIcon"
+                            title="中止"
+                        ></i>
+                        <!-- 下载只有执行完成才可展示 nowRunState 30展示  -->
+                        <!-- 只要nowRunState不是20 即执行中的时候都可以删除 -->
+                        <!-- 只有执行中可中止 即等于20的时候 -->
+                    </template>
+                </el-table-column>
+            </tableList>
+
+            <el-dialog
+                title="下载"
+                :visible.sync="dialogVisible"
+                width="690px"
+                :close-on-click-modal="false"
+                :close-on-press-escape="false"
+                :before-close="cancelDown"
+            >
+                <div class="checkboxPanel">
+                    <el-checkbox-group v-model="downType">
+                        <el-checkbox
+                            label="工作报告"
+                            class="labelA"
+                            :disabled="downDisabled"
+                        ></el-checkbox>
+                        <el-checkbox label="任务文件包"></el-checkbox>
+                    </el-checkbox-group>
+                </div>
+                <span slot="footer">
+                    <el-button type="primary" @click="confirmDown"
+                        >确 定</el-button
+                    >
+                    <el-button @click="cancelDown">取 消</el-button>
+                </span>
+            </el-dialog>
+        </div>
+        <router-view v-else></router-view>
+    </div>
+</template>
+
+<script>
+import tableList from "@/components/grid/TableList";
+
+export default {
+    name: "autoRunSubProjectList", // 自动运行子项目列表
+    components: { tableList },
+    data() {
+        return {
+            id: "",
+            columns: [
+                {
+                    label: "项目ID",
+                    prop: "projectId",
+                },
+                {
+                    label: "项目名称",
+                    prop: "projectName",
+                },
+                {
+                    label: "开始时间",
+                    prop: "createTimeFmt",
+                },
+                {
+                    label: "结束时间",
+                    prop: "finishTimeFmt",
+                },
+                {
+                    label: "进度",
+                    prop: "nowRunStateDict",
+                },
+                {
+                    label: "评测等级",
+                    prop: "evaluationLevelDict",
+                },
+                {
+                    label: "操作",
+                    prop: "cgInfos",
+                    template: true,
+                },
+            ],
+            pagination: {
+                //分页使用
+                currentPage: 1,
+                pageSize: 10,
+                position: "right",
+                pageSizes: [10, 30, 50, 100, 200],
+                layout: "sizes, total, prev, pager, next, jumper",
+            },
+            getDataWay: {
+                //加载表格数据
+                dataType: "url",
+                type: "post",
+                // firstRequest: false,
+                data: this.$api.workManagement.selectSubProjectList,
+                param: {
+                    parentId: this.$route.query.id,
+                },
+            },
+            downType: [],
+            dialogVisible: false,
+            curRow: {}, // 当前row
+            downDisabled: false, // 用于判断是否可下载工作报告
+            info: {},
+        };
+    },
+    methods: {
+        doSearch() {
+            this.refreshList();
+        },
+        //刷新table
+        refreshList(param) {
+            param
+                ? this.$refs["table"].loadData(param)
+                : this.$refs["table"].loadData();
+        },
+        editRow(row) {
+            this.$router.push({
+                path: "/autoRunProjectDetail",
+                query: {
+                    id: row.id,
+                },
+            });
+        },
+        runRow(id) {
+            this.$confirm("确认是否运行?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            }).then(() => {
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.updateProjectNowRunState,
+                    data: {
+                        id,
+                        nowRunState: "20",
+                    },
+                }).then((res) => {
+                    if (res.code == 200) {
+                        this.$message.success("运行成功");
+                    } else {
+                        this.$message.error(res.message || "运行失败");
+                    }
+                    this.doSearch();
+                });
+            });
+        },
+        delRow(ids) {
+            this.$confirm("确认是否删除?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            }).then(() => {
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.deleteAutomaticSubProjectByIds,
+                    data: {
+                        ids,
+                    },
+                }).then((res) => {
+                    if (res.code == 200) {
+                        this.$message.success("删除成功");
+                    } else {
+                        this.$message.error(res.message || "删除失败");
+                    }
+                    this.doSearch();
+                });
+            });
+        },
+        stopRow(id) {
+            this.$confirm("确认是否中止?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            }).then(() => {
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.updateAutoProjectNowRunState,
+                    data: {
+                        id,
+                        nowRunState: "40",
+                    },
+                }).then((res) => {
+                    if (res.code == 200) {
+                        this.$message.success("中止成功");
+                    } else {
+                        this.$message.error(res.message || "中止失败");
+                    }
+                    this.doSearch();
+                });
+            });
+        },
+        viewRow(id) {
+            this.$router.push({
+                path: "/autoRunProjectList/autoRunSubProjectList/projectInfo",
+                query: { id, projectType: "2" },
+            });
+        },
+        downRow(row) {
+            this.curRow = row;
+            this.downDisabled = row.nowRunState === "30" ? false : true;
+            this.dialogVisible = true;
+        },
+        confirmDown() {
+            let url = "";
+            let fileName = this.curRow.projectName;
+
+            if (this.downType.length === 0) {
+                this.$message.info("请先选择下载类型");
+                return;
+            } else if (this.downType.length === 1) {
+                if (this.downType[0] === "工作报告") {
+                    url = this.$api.workManagement.exportProjectReportById;
+                    fileName += ".pdf";
+                } else {
+                    url = this.$api.workManagement.exportProjectTaskFileById;
+                    fileName += ".zip";
+                }
+            } else {
+                url =
+                    this.$api.workManagement.exportProjectReportAndTaskFileById;
+                fileName += ".zip";
+            }
+
+            let id = this.curRow.id;
+            this.curRow = {};
+
+            this.$axios({
+                method: "post",
+                url,
+                responseType: "blob",
+                data: {
+                    id,
+                    projectType: "2",
+                },
+            }).then((res) => {
+                let blob = new Blob([res]);
+                if ("download" in document.createElement("a")) {
+                    // 非IE下载
+                    let emlink = document.createElement("a");
+                    emlink.download = fileName;
+                    emlink.style.display = "none";
+                    emlink.href = URL.createObjectURL(blob);
+                    document.body.appendChild(emlink);
+                    emlink.click();
+                    URL.revokeObjectURL(emlink.href);
+                    document.body.removeChild(emlink);
+                } else {
+                    // IE下载
+                    navigator.msSaveBlob(blob, fileName);
+                }
+            });
+
+            this.downType = [];
+            this.dialogVisible = false;
+        },
+        cancelDown() {
+            this.downType = [];
+            this.dialogVisible = false;
+        },
+    },
+
+    mounted() {
+        if (this.$route.query.id) {
+            this.id = this.$route.query.id;
+
+            if (this.id) {
+                this.$axios({
+                    method: "post",
+                    url: this.$api.workManagement.selectSubProjectInfo,
+                    data: {
+                        id: this.id,
+                    },
+                }).then((res) => {
+                    if (res.code == 200 && res.info) {
+                        this.info = res.info;
+                    } else {
+                        this.$message.error(res.message || "获取信息失败");
+                    }
+                });
+            }
+        }
+    },
+};
+</script>
+
+<style lang='less' scoped>
+.box {
+    display: flex;
+    flex-wrap: wrap;
+    padding: 20px 40px;
+
+    .info {
+        display: flex;
+        width: 345px;
+        margin: 0 12px 22px 0;
+        word-break: break-all;
+
+        span {
+            display: block;
+            width: 105px;
+            color: @gray;
+        }
+
+        b {
+            flex: 1;
+            font-weight: normal;
+        }
+    }
+}
+
+.checkboxPanel {
+    text-align: center;
+
+    .labelA {
+        margin-right: 60px;
+    }
+}
+</style>

+ 86 - 24
src/views/workManagement/evaluationReport.vue

@@ -81,6 +81,7 @@ export default {
     data() {
         return {
             id: "",
+            projectType: "",
             columns: [
                 {
                     label: "测试项目",
@@ -196,13 +197,19 @@ export default {
         arraySpanMethod({ row, column, rowIndex, columnIndex }) {
             if (columnIndex === 0 || columnIndex === this.columnsB.length - 1) {
                 if (this.subIndexArr[0].includes(rowIndex)) {
-                    return [this.sublistNameObj[0][row.sublistName1], 1];
+                    return [
+                        this.sublistNameObj[0][row.sublistName1 + rowIndex],
+                        1,
+                    ];
                 } else {
                     return [0, 0];
                 }
             } else if (columnIndex === 1) {
                 if (this.subIndexArr[1].includes(rowIndex)) {
-                    return [this.sublistNameObj[1][row.sublistName2], 1];
+                    return [
+                        this.sublistNameObj[1][row.sublistName2 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName2) {
                         return [0, 0];
@@ -212,7 +219,10 @@ export default {
                 }
             } else if (columnIndex === 2) {
                 if (this.subIndexArr[2].includes(rowIndex)) {
-                    return [this.sublistNameObj[2][row.sublistName3], 1];
+                    return [
+                        this.sublistNameObj[2][row.sublistName3 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName3) {
                         return [0, 0];
@@ -222,7 +232,10 @@ export default {
                 }
             } else if (columnIndex === 3) {
                 if (this.subIndexArr[3].includes(rowIndex)) {
-                    return [this.sublistNameObj[3][row.sublistName4], 1];
+                    return [
+                        this.sublistNameObj[3][row.sublistName4 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName4) {
                         return [0, 0];
@@ -232,7 +245,10 @@ export default {
                 }
             } else if (columnIndex === 4) {
                 if (this.subIndexArr[4].includes(rowIndex)) {
-                    return [this.sublistNameObj[4][row.sublistName5], 1];
+                    return [
+                        this.sublistNameObj[4][row.sublistName5 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName5) {
                         return [0, 0];
@@ -242,7 +258,10 @@ export default {
                 }
             } else if (columnIndex === 5) {
                 if (this.subIndexArr[5].includes(rowIndex)) {
-                    return [this.sublistNameObj[5][row.sublistName6], 1];
+                    return [
+                        this.sublistNameObj[5][row.sublistName6 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName6) {
                         return [0, 0];
@@ -255,13 +274,19 @@ export default {
         arraySpanMethodA({ row, column, rowIndex, columnIndex }) {
             if (columnIndex === 0) {
                 if (this.subIndexArrA[0].includes(rowIndex)) {
-                    return [this.sublistNameObjA[0][row.sublistName1], 1];
+                    return [
+                        this.sublistNameObjA[0][row.sublistName1 + rowIndex],
+                        1,
+                    ];
                 } else {
                     return [0, 0];
                 }
             } else if (columnIndex === 1) {
                 if (this.subIndexArrA[1].includes(rowIndex)) {
-                    return [this.sublistNameObjA[1][row.sublistName2], 1];
+                    return [
+                        this.sublistNameObjA[1][row.sublistName2 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName2) {
                         return [0, 0];
@@ -271,7 +296,10 @@ export default {
                 }
             } else if (columnIndex === 2) {
                 if (this.subIndexArrA[2].includes(rowIndex)) {
-                    return [this.sublistNameObjA[2][row.sublistName3], 1];
+                    return [
+                        this.sublistNameObjA[2][row.sublistName3 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName3) {
                         return [0, 0];
@@ -281,7 +309,10 @@ export default {
                 }
             } else if (columnIndex === 3) {
                 if (this.subIndexArrA[3].includes(rowIndex)) {
-                    return [this.sublistNameObjA[3][row.sublistName4], 1];
+                    return [
+                        this.sublistNameObjA[3][row.sublistName4 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName4) {
                         return [0, 0];
@@ -291,7 +322,10 @@ export default {
                 }
             } else if (columnIndex === 4) {
                 if (this.subIndexArrA[4].includes(rowIndex)) {
-                    return [this.sublistNameObjA[4][row.sublistName5], 1];
+                    return [
+                        this.sublistNameObjA[4][row.sublistName5 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName5) {
                         return [0, 0];
@@ -301,7 +335,10 @@ export default {
                 }
             } else if (columnIndex === 5) {
                 if (this.subIndexArrA[5].includes(rowIndex)) {
-                    return [this.sublistNameObjA[5][row.sublistName6], 1];
+                    return [
+                        this.sublistNameObjA[5][row.sublistName6 + rowIndex],
+                        1,
+                    ];
                 } else {
                     if (row.sublistName6) {
                         return [0, 0];
@@ -341,70 +378,93 @@ export default {
             let subIndexArr5 = [];
             let subIndexArr6 = [];
 
+            let lastI1 = 0;
+            let lastI2 = 0;
+            let lastI3 = 0;
+            let lastI4 = 0;
+            let lastI5 = 0;
+            let lastI6 = 0;
+
             arr.forEach((item, i) => {
                 let sublistName1 = item.sublistName1;
                 if (sublistName1 === lastRowSublistName1) {
-                    sublistNameObj1[sublistName1]++;
+                    sublistNameObj1[sublistName1 + lastI1]++;
                 } else {
                     lastRowSublistName1 = sublistName1;
                     subIndexArr1.push(i);
-                    sublistNameObj1[sublistName1] = 1;
+                    lastI1 = i;
+                    sublistNameObj1[sublistName1 + lastI1] = 1;
                 }
 
                 if (item.sublistName2) {
                     // 一级后的指标名称可能不存在
                     let sublistName2 = item.sublistName2;
                     if (sublistName2 === lastRowSublistName2) {
-                        sublistNameObj2[sublistName2]++;
+                        sublistNameObj2[sublistName2 + lastI2]++;
                     } else {
                         lastRowSublistName2 = sublistName2;
                         subIndexArr2.push(i);
-                        sublistNameObj2[sublistName2] = 1;
+                        lastI2 = i;
+                        sublistNameObj2[sublistName2 + lastI2] = 1;
                     }
+                } else {
+                    lastRowSublistName2 = "";
                 }
 
                 if (item.sublistName3) {
                     let sublistName3 = item.sublistName3;
                     if (sublistName3 === lastRowSublistName3) {
-                        sublistNameObj3[sublistName3]++;
+                        sublistNameObj3[sublistName3 + lastI3]++;
                     } else {
                         lastRowSublistName3 = sublistName3;
                         subIndexArr3.push(i);
-                        sublistNameObj3[sublistName3] = 1;
+                        lastI3 = i;
+                        sublistNameObj3[sublistName3 + lastI3] = 1;
                     }
+                } else {
+                    lastRowSublistName3 = "";
                 }
 
                 if (item.sublistName4) {
                     let sublistName4 = item.sublistName4;
                     if (sublistName4 === lastRowSublistName4) {
-                        sublistNameObj4[sublistName4]++;
+                        sublistNameObj4[sublistName4 + lastI4]++;
                     } else {
                         lastRowSublistName4 = sublistName4;
                         subIndexArr4.push(i);
-                        sublistNameObj4[sublistName4] = 1;
+                        lastI4 = i;
+                        sublistNameObj4[sublistName4 + lastI4] = 1;
                     }
+                } else {
+                    lastRowSublistName4 = "";
                 }
 
                 if (item.sublistName5) {
                     let sublistName5 = item.sublistName5;
                     if (sublistName5 === lastRowSublistName5) {
-                        sublistNameObj5[sublistName5]++;
+                        sublistNameObj5[sublistName5 + lastI5]++;
                     } else {
                         lastRowSublistName5 = sublistName5;
                         subIndexArr5.push(i);
-                        sublistNameObj5[sublistName5] = 1;
+                        lastI5 = i;
+                        sublistNameObj5[sublistName5 + lastI5] = 1;
                     }
+                } else {
+                    lastRowSublistName5 = "";
                 }
 
                 if (item.sublistName6) {
                     let sublistName6 = item.sublistName6;
                     if (sublistName6 === lastRowSublistName6) {
-                        sublistNameObj6[sublistName6]++;
+                        sublistNameObj6[sublistName6 + lastI6]++;
                     } else {
                         lastRowSublistName6 = sublistName6;
                         subIndexArr6.push(i);
-                        sublistNameObj6[sublistName6] = 1;
+                        lastI6 = i;
+                        sublistNameObj6[sublistName6 + lastI6] = 1;
                     }
+                } else {
+                    lastRowSublistName6 = "";
                 }
             });
 
@@ -439,6 +499,7 @@ export default {
     mounted() {
         if (this.$route.query.id) {
             this.id = this.$route.query.id;
+            this.projectType = this.$route.query.projectType || "1";
 
             if (this.id) {
                 this.$axios({
@@ -446,6 +507,7 @@ export default {
                     url: this.$api.workManagement.selectProjectReportById,
                     data: {
                         id: this.id,
+                        projectType: this.projectType,
                     },
                 }).then((res) => {
                     if (res.code == 200 && res.info) {

+ 46 - 22
src/views/workManagement/manualRunProjectDetail.vue

@@ -79,8 +79,9 @@
                 </el-form-item>
                 <el-form-item label="并行度:" prop="parallelism">
                     <el-input
+                        :disabled="runDisabled"
                         placeholder="请输入"
-                        maxlength="100"
+                        maxlength="10"
                         v-autoTrim="{ obj: form, key: 'parallelism' }"
                         v-model="form.parallelism"
                     >
@@ -89,7 +90,7 @@
                 <el-form-item label="最大仿真时间:" prop="maxSimulationTime">
                     <el-input
                         placeholder="请输入"
-                        maxlength="100"
+                        maxlength="10"
                         v-autoTrim="{ obj: form, key: 'maxSimulationTime' }"
                         v-model="form.maxSimulationTime"
                     >
@@ -122,7 +123,7 @@
                         <el-button type="primary">规则查看</el-button>
                     </div>
                 </div> -->
-                <div class="tip">(最多可用资源{{ maxCount }})</div>
+                <div class="tip">(最多可用资源{{ maxCount }})</div>
                 <div class="tip">(最小是5,最大是60)</div>
             </div>
         </el-form>
@@ -134,7 +135,10 @@
                 v-if="this.$route.query.id"
                 >另存为</el-button
             >
-            <el-button type="primary" @click="save(false, true)"
+            <el-button
+                type="primary"
+                @click="save(false, true)"
+                :disabled="runDisabled"
                 >提交</el-button
             >
             <el-button type="primary" plain @click="cancel">取消</el-button>
@@ -145,22 +149,26 @@
 <script>
 //import  from '';
 let maxCount = 0; // 用于校验
+let validateNum = (rule, value, callback) => {
+    !/^(\d+)$/.test(value) && callback(new Error(rule.message));
+    if (value <= 0 || value > maxCount) callback(new Error(rule.message));
+    callback();
+};
+let validateNumA = (rule, value, callback) => {
+    !/^(\d+)$/.test(value) && callback(new Error(rule.message));
+    if (value < 5 || value > 60) callback(new Error(rule.message));
+    callback();
+};
+let validateNumB = (rule, value, callback) => {
+    !/^(\d+)$/.test(value) && callback(new Error(rule.message));
+    if (value <= 0) callback(new Error(rule.message));
+    callback();
+};
+
 export default {
     name: "manualRunProjectDetail", // 手动运行项目详情
     components: {},
     data() {
-        let validateNum = (rule, value, callback) => {
-            !/^(\d+)$/.test(value) && callback(new Error(rule.message));
-            if (value <= 0 || value > maxCount)
-                callback(new Error(rule.message));
-            callback();
-        };
-        let validateNumA = (rule, value, callback) => {
-            !/^(\d+)$/.test(value) && callback(new Error(rule.message));
-            if (value < 5 || value > 60) callback(new Error(rule.message));
-            callback();
-        };
-
         return {
             form: {
                 id: "",
@@ -201,11 +209,11 @@ export default {
                 ],
                 parallelism: [
                     { required: true, message: "请输入", trigger: "blur" },
-                    {
-                        validator: validateNum,
-                        message: "请输入不大于最多可用资源的正整数",
-                        trigger: ["blur"],
-                    },
+                    // {
+                    //     validator: validateNum,
+                    //     message: "请输入不大于最多可用资源的正整数",
+                    //     trigger: ["blur"],
+                    // },
                 ],
                 maxSimulationTime: [
                     { required: true, message: "请输入", trigger: "blur" },
@@ -220,6 +228,7 @@ export default {
                 ],
             },
             sensors: [], // 选中车辆后对应的传感器数组
+            runDisabled: false, // 若最多可用资源为0,则不可点击"提交"
         };
     },
 
@@ -266,10 +275,25 @@ export default {
                 url: this.$api.workManagement.selectMaxParallelism,
                 data: {},
             }).then((res) => {
-                if (res.code == 200 && res.info) {
+                if (res.code == 200 && res.info && res.info != 0) {
                     this.maxCount = maxCount = res.info;
+                    if (res.info == -1) {
+                        this.rules.parallelism.push({
+                            validator: validateNumB,
+                            message: "请输入正整数",
+                            trigger: ["blur"],
+                        });
+                    } else {
+                        this.rules.parallelism.push({
+                            validator: validateNum,
+                            message: "请输入不大于最多可用资源的正整数",
+                            trigger: ["blur"],
+                        });
+                    }
                 } else if (res.code == 200 && res.info == 0) {
                     this.maxCount = maxCount = 0;
+                    this.runDisabled = true;
+                    this.form.parallelism = 0;
                 } else {
                     this.$message.error(res.message || "获取信息失败");
                 }

+ 194 - 179
src/views/workManagement/manualRunProjectList.vue

@@ -1,188 +1,193 @@
 <template>
     <div>
-        <search-layout :needBox="true">
-            <template slot="searchItem1">
-                <span class="label">项目ID</span>
-                <el-input
-                    v-model="searchParams.projectId"
-                    size="small"
-                    clearable
-                    placeholder="请输入"
-                    maxlength="60"
-                    @keyup.enter.native="doSearch"
-                >
-                </el-input>
-            </template>
-            <template slot="searchItem2">
-                <span class="label">项目名称</span>
-                <el-input
-                    v-model="searchParams.projectName"
-                    size="small"
-                    clearable
-                    placeholder="请输入"
-                    maxlength="60"
-                    @keyup.enter.native="doSearch"
-                >
-                </el-input>
-            </template>
-            <template slot="searchItem3">
-                <span class="label">进度</span>
-                <el-select v-model="searchParams.nowRunState">
-                    <el-option
-                        v-for="item in nowRunStateList"
-                        :label="item.caption"
-                        :value="item.code"
-                        :key="item.code"
-                    ></el-option>
-                </el-select>
-            </template>
-            <template slot="searchItem4">
-                <span class="label">评测等级</span>
-                <el-select v-model="searchParams.evaluationLevel">
-                    <el-option
-                        v-for="item in evaluationLevelList"
-                        :label="item.caption"
-                        :value="item.code"
-                        :key="item.code"
-                    ></el-option>
-                </el-select>
-            </template>
-            <template slot="searchItem5">
-                <span class="label">创建时间</span>
-                <el-date-picker
-                    v-model="createDate"
-                    type="daterange"
-                    format="yyyy-MM-dd"
-                    value-format="yyyy-MM-dd"
-                    range-separator="至"
-                    start-placeholder="开始日期"
-                    end-placeholder="结束日期"
+        <div v-if="!$route.path.includes('projectInfo')">
+            <search-layout :needBox="true">
+                <template slot="searchItem1">
+                    <span class="label">项目ID</span>
+                    <el-input
+                        v-model="searchParams.projectId"
+                        size="small"
+                        clearable
+                        placeholder="请输入"
+                        maxlength="60"
+                        @keyup.enter.native="doSearch"
+                    >
+                    </el-input>
+                </template>
+                <template slot="searchItem2">
+                    <span class="label">项目名称</span>
+                    <el-input
+                        v-model="searchParams.projectName"
+                        size="small"
+                        clearable
+                        placeholder="请输入"
+                        maxlength="60"
+                        @keyup.enter.native="doSearch"
+                    >
+                    </el-input>
+                </template>
+                <template slot="searchItem3">
+                    <span class="label">进度</span>
+                    <el-select v-model="searchParams.nowRunState">
+                        <el-option
+                            v-for="item in nowRunStateList"
+                            :label="item.caption"
+                            :value="item.code"
+                            :key="item.code"
+                        ></el-option>
+                    </el-select>
+                </template>
+                <template slot="searchItem4">
+                    <span class="label">评测等级</span>
+                    <el-select v-model="searchParams.evaluationLevel">
+                        <el-option
+                            v-for="item in evaluationLevelList"
+                            :label="item.caption"
+                            :value="item.code"
+                            :key="item.code"
+                        ></el-option>
+                    </el-select>
+                </template>
+                <template slot="searchItem5">
+                    <span class="label">创建时间</span>
+                    <el-date-picker
+                        v-model="createDate"
+                        type="daterange"
+                        format="yyyy-MM-dd"
+                        value-format="yyyy-MM-dd"
+                        range-separator="至"
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期"
+                    >
+                    </el-date-picker>
+                </template>
+                <template slot="searchItem6">
+                    <span class="label">完成时间</span>
+                    <el-date-picker
+                        v-model="finishDate"
+                        type="daterange"
+                        format="yyyy-MM-dd"
+                        value-format="yyyy-MM-dd"
+                        range-separator="至"
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期"
+                    >
+                    </el-date-picker>
+                </template>
+
+                <template slot="searchBtn1">
+                    <el-button type="primary" @click="doSearch">查询</el-button>
+                </template>
+                <template slot="searchBtn2">
+                    <el-button type="primary" @click="doReset">重置</el-button>
+                </template>
+            </search-layout>
+
+            <div class="btnsPanel">
+                <el-button
+                    type="primary"
+                    plain
+                    icon="el-icon-delete"
+                    @click="delRows"
+                    >批量删除</el-button
                 >
-                </el-date-picker>
-            </template>
-            <template slot="searchItem6">
-                <span class="label">完成时间</span>
-                <el-date-picker
-                    v-model="finishDate"
-                    type="daterange"
-                    format="yyyy-MM-dd"
-                    value-format="yyyy-MM-dd"
-                    range-separator="至"
-                    start-placeholder="开始日期"
-                    end-placeholder="结束日期"
+                <el-button
+                    type="primary"
+                    icon="el-icon-circle-plus-outline"
+                    @click="addOne"
+                    >创建</el-button
                 >
-                </el-date-picker>
-            </template>
-
-            <template slot="searchBtn1">
-                <el-button type="primary" @click="doSearch">查询</el-button>
-            </template>
-            <template slot="searchBtn2">
-                <el-button type="primary" @click="doReset">重置</el-button>
-            </template>
-        </search-layout>
+            </div>
 
-        <div class="btnsPanel">
-            <el-button
-                type="primary"
-                plain
-                icon="el-icon-delete"
-                @click="delRows"
-                >批量删除</el-button
+            <tableList
+                ref="table"
+                style="margin: 0 30px"
+                :columns="columns"
+                :getDataWay="getDataWay"
+                :pagination="pagination"
+                :checkedData="checkedArr"
+                selection
+                index
             >
-            <el-button
-                type="primary"
-                icon="el-icon-circle-plus-outline"
-                @click="addOne"
-                >创建</el-button
+                <el-table-column label="操作" slot="cgInfos" align="center">
+                    <template v-slot="scope">
+                        <i
+                            v-if="
+                                scope.row.nowRunState === '10' ||
+                                scope.row.nowRunState === '30' ||
+                                scope.row.nowRunState === '40'
+                            "
+                            @click="runRow(scope.row.id, scope.row.parallelism)"
+                            class="el-icon-video-play elIcon"
+                            title="运行"
+                        ></i>
+                        <i
+                            v-if="
+                                scope.row.nowRunState === '10' ||
+                                scope.row.nowRunState === '40'
+                            "
+                            @click="editRow(scope.row)"
+                            class="el-icon-edit-outline elIcon"
+                            title="编辑"
+                        ></i>
+                        <i
+                            @click="viewRow(scope.row.id)"
+                            class="el-icon-view elIcon"
+                            title="查看"
+                        ></i>
+                        <i
+                            v-if="scope.row.nowRunState === '20'"
+                            @click="stopRow(scope.row.id)"
+                            class="el-icon-video-pause elIcon"
+                            title="中止"
+                        ></i>
+                        <i
+                            v-if="
+                                scope.row.nowRunState === '10' ||
+                                scope.row.nowRunState === '30' ||
+                                scope.row.nowRunState === '40'
+                            "
+                            @click="delRow(scope.row.id)"
+                            class="el-icon-delete elIcon"
+                            title="删除"
+                        ></i>
+                        <i
+                            v-if="scope.row.nowRunState != '10'"
+                            @click="downRow(scope.row)"
+                            class="el-icon-download elIcon"
+                            title="下载"
+                        ></i>
+                    </template>
+                </el-table-column>
+            </tableList>
+
+            <el-dialog
+                title="下载"
+                :visible.sync="dialogVisible"
+                width="690px"
+                :close-on-click-modal="false"
+                :close-on-press-escape="false"
+                :before-close="cancelDown"
             >
+                <div class="checkboxPanel">
+                    <el-checkbox-group v-model="downType">
+                        <el-checkbox
+                            label="工作报告"
+                            class="labelA"
+                            :disabled="downDisabled"
+                        ></el-checkbox>
+                        <el-checkbox label="任务文件包"></el-checkbox>
+                    </el-checkbox-group>
+                </div>
+                <span slot="footer">
+                    <el-button type="primary" @click="confirmDown"
+                        >确 定</el-button
+                    >
+                    <el-button @click="cancelDown">取 消</el-button>
+                </span>
+            </el-dialog>
         </div>
-
-        <tableList
-            ref="table"
-            style="margin: 0 30px"
-            :columns="columns"
-            :getDataWay="getDataWay"
-            :pagination="pagination"
-            :checkedData="checkedArr"
-            selection
-            index
-        >
-            <el-table-column label="操作" slot="cgInfos" align="center">
-                <template v-slot="scope">
-                    <i
-                        v-if="
-                            scope.row.nowRunState === '10' ||
-                            scope.row.nowRunState === '30' ||
-                            scope.row.nowRunState === '40'
-                        "
-                        @click="runRow(scope.row.id)"
-                        class="el-icon-video-play elIcon"
-                        title="运行"
-                    ></i>
-                    <i
-                        v-if="
-                            scope.row.nowRunState === '10' ||
-                            scope.row.nowRunState === '40'
-                        "
-                        @click="editRow(scope.row)"
-                        class="el-icon-edit-outline elIcon"
-                        title="编辑"
-                    ></i>
-                    <i
-                        @click="viewRow(scope.row.id)"
-                        class="el-icon-view elIcon"
-                        title="查看"
-                    ></i>
-                    <i
-                        v-if="scope.row.nowRunState === '20'"
-                        @click="stopRow(scope.row.id)"
-                        class="el-icon-video-pause elIcon"
-                        title="中止"
-                    ></i>
-                    <i
-                        v-if="
-                            scope.row.nowRunState === '10' ||
-                            scope.row.nowRunState === '30' ||
-                            scope.row.nowRunState === '40'
-                        "
-                        @click="delRow(scope.row.id)"
-                        class="el-icon-delete elIcon"
-                        title="删除"
-                    ></i>
-                    <i
-                        v-if="scope.row.nowRunState != '10'"
-                        @click="downRow(scope.row)"
-                        class="el-icon-download elIcon"
-                        title="下载"
-                    ></i>
-                </template>
-            </el-table-column>
-        </tableList>
-
-        <el-dialog
-            title="下载"
-            :visible.sync="dialogVisible"
-            width="690px"
-            :close-on-click-modal="false"
-            :close-on-press-escape="false"
-            :before-close="cancelDown"
-        >
-            <div class="checkboxPanel">
-                <el-checkbox-group v-model="downType">
-                    <el-checkbox
-                        label="工作报告"
-                        class="labelA"
-                        :disabled="downDisabled"
-                    ></el-checkbox>
-                    <el-checkbox label="任务文件包"></el-checkbox>
-                </el-checkbox-group>
-            </div>
-            <span slot="footer">
-                <el-button type="primary" @click="confirmDown">确 定</el-button>
-                <el-button @click="cancelDown">取 消</el-button>
-            </span>
-        </el-dialog>
+        <router-view v-else></router-view>
     </div>
 </template>
 
@@ -331,12 +336,17 @@ export default {
                 },
             });
         },
-        runRow(id) {
+        runRow(id, parallelism) {
             this.$confirm("确认是否运行?", "提示", {
                 confirmButtonText: "确定",
                 cancelButtonText: "取消",
                 type: "warning",
             }).then(() => {
+                if (parallelism == "0") {
+                    this.$message.error("并行度为0,不能运行");
+                    return;
+                }
+
                 this.$axios({
                     method: "post",
                     url: this.$api.workManagement.updateProjectNowRunState,
@@ -421,7 +431,10 @@ export default {
         },
 
         viewRow(id) {
-            this.$router.push({ path: "/projectInfo", query: { id } });
+            this.$router.push({
+                path: "/manualRunProjectList/projectInfo",
+                query: { id, projectType: "1" },
+            });
         },
         downRow(row) {
             this.curRow = row;
@@ -458,6 +471,7 @@ export default {
                 responseType: "blob",
                 data: {
                     id,
+                    projectType: "1",
                 },
             }).then((res) => {
                 let blob = new Blob([res]);
@@ -487,6 +501,7 @@ export default {
     },
 
     async mounted() {
+        // console.log(666);
         await this.$dicsListsInit({
             nowRunStateList: "projectRunState",
             evaluationLevelList: "evaluationLevel",

+ 255 - 189
src/views/workManagement/projectInfo.vue

@@ -1,189 +1,214 @@
 <template>
     <div class="projectInfoPanel">
-        <div class="headPanel panel">
-            <div class="titlePanel">
-                <div class="titlePanelBor">基本信息</div>
-            </div>
-            <div class="boxContent">
-                <div class="info">
-                    <span>项目ID:</span>
-                    <b>{{ info.projectId }}</b>
-                </div>
-                <div class="info">
-                    <span>项目名称:</span>
-                    <b>{{ info.projectName }}</b>
-                </div>
-                <div class="info">
-                    <span>并行度:</span>
-                    <b>{{ info.parallelism }}</b>
-                </div>
-                <div class="info">
-                    <span>最大仿真时间:</span>
-                    <b>{{ info.maxSimulationTime }}</b>
-                </div>
-                <div class="info">
-                    <span>是否选择GPU:</span>
-                    <b>{{ info.isChoiceGpu }}</b>
-                </div>
-                <div class="info">
-                    <span>创建时间:</span>
-                    <b>{{ info.startTime }}</b>
-                </div>
-                <div class="info">
-                    <span>完成时间:</span>
-                    <b>{{ info.finishTime }}</b>
-                </div>
-                <div class="info">
-                    <span>完成进度:</span>
-                    <b>{{ info.nowRunStateName }}</b>
-                </div>
-                <div class="info">
-                    <span>结果等级:</span>
-                    <b>{{ info.evaluationLevel }}</b>
-                </div>
-                <div class="info">
-                    <span>项目描述:</span>
-                    <b>{{ info.projectDescribe }}</b>
-                </div>
-            </div>
-        </div>
-
-        <div class="flexBox topPanel">
-            <div class="box panel boxB">
+        <div
+            v-if="
+                !$route.path.includes('taskInfo') &&
+                !$route.path.includes('evaluationReport')
+            "
+        >
+            <div class="headPanel panel">
                 <div class="titlePanel">
-                    <div class="titlePanelBor">算法配置</div>
+                    <div class="titlePanelBor">基本信息</div>
                 </div>
                 <div class="boxContent">
                     <div class="info">
-                        <span>算法名称:</span>
-                        <b>{{ info.algorithmName }}</b>
+                        <span>项目ID:</span>
+                        <b>{{ info.projectId }}</b>
+                    </div>
+                    <div class="info">
+                        <span>项目名称:</span>
+                        <b>{{ info.projectName }}</b>
+                    </div>
+                    <div class="info">
+                        <span>并行度:</span>
+                        <b>{{ info.parallelism }}</b>
+                    </div>
+                    <div class="info">
+                        <span>最大仿真时间:</span>
+                        <b>{{ info.maxSimulationTime }}</b>
+                    </div>
+                    <div class="info">
+                        <span>是否选择GPU:</span>
+                        <b>{{ info.isChoiceGpu }}</b>
                     </div>
                     <div class="info">
-                        <span>算法描述:</span>
-                        <b>{{ info.algorithmDescribe }}</b>
+                        <span>创建时间:</span>
+                        <b>{{ info.startTime }}</b>
+                    </div>
+                    <div class="info">
+                        <span>完成时间:</span>
+                        <b>{{ info.finishTime }}</b>
+                    </div>
+                    <div class="info">
+                        <span>完成进度:</span>
+                        <b>{{ info.nowRunStateName }}</b>
+                    </div>
+                    <div class="info">
+                        <span>结果等级:</span>
+                        <b>{{ info.evaluationLevel }}</b>
+                    </div>
+                    <div class="info">
+                        <span>场景测试包:</span>
+                        <b>{{ info.packageName }}</b>
+                    </div>
+                    <div class="info">
+                        <span>项目描述:</span>
+                        <b>{{ info.projectDescribe }}</b>
                     </div>
                 </div>
             </div>
-            <div class="box panel">
+
+            <div class="scorePanel panel">
                 <div class="titlePanel">
-                    <div class="titlePanelBor">测试报告</div>
-                    <i
-                        class="el-icon-download download"
-                        v-bind:class="{ cursor: info.nowRunState === '30' }"
-                        @click="downReport"
-                    ></i>
+                    <div class="titlePanelBor">测评得分</div>
                 </div>
-                <div class="boxContent boxContentC">
-                    <div class="cbox" @click="toReport">
-                        <img
-                            :src="downImgSrc"
-                            width="100%"
-                            v-bind:class="{ cursor: info.nowRunState === '30' }"
-                        />
-                        <div
-                            v-bind:class="{ cursor: info.nowRunState === '30' }"
-                        >
-                            仿真云测试报告
-                        </div>
-                    </div>
+                <div class="box">
+                    <tableList
+                        style="margin: 30px 0"
+                        :columns="columnsA"
+                        :getDataWay="getDataWayA"
+                    >
+                    </tableList>
                 </div>
             </div>
-        </div>
 
-        <div class="centerPanel panel">
-            <div class="titlePanel">
-                <div class="titlePanelBor">车辆配置</div>
-            </div>
-            <div class="box">
-                <div class="boxContentA">
-                    <div class="info">
-                        <span>车辆名称:</span>
-                        <b>{{ info.vehicleName }}</b>
+            <div class="flexBox topPanel">
+                <div class="box panel boxB">
+                    <div class="titlePanel">
+                        <div class="titlePanelBor">算法配置</div>
                     </div>
-                    <div class="info">
-                        <span>车辆描述:</span>
-                        <b>{{ info.vehicleDescribe }}</b>
+                    <div class="boxContent">
+                        <div class="info">
+                            <span>算法名称:</span>
+                            <b>{{ info.algorithmName }}</b>
+                        </div>
+                        <div class="info">
+                            <span>算法描述:</span>
+                            <b>{{ info.algorithmDescribe }}</b>
+                        </div>
                     </div>
                 </div>
-                <div class="boxContentB">
-                    <div class="list">
-                        <handle-config-list
-                            :showBtns="false"
-                            :curOne="curOne"
-                            :configList="configList"
-                            @curItem="curItem"
-                            :needHighline="false"
-                        ></handle-config-list>
+                <div class="box panel">
+                    <div class="titlePanel">
+                        <div class="titlePanelBor">测试报告</div>
+                        <i
+                            class="el-icon-download download"
+                            v-bind:class="{ cursor: info.nowRunState === '30' }"
+                            @click="downReport"
+                        ></i>
                     </div>
-                    <div class="canvasBox">
-                        <!-- <img
-                            src="../../assets/common/image/others/2.png"
-                            width="100%"
-                        /> -->
-                        <canvas-sensor
-                            v-if="modelImgSrc"
-                            :modelImgSrc="modelImgSrc"
-                            :configList="configList"
-                        ></canvas-sensor>
+                    <div class="boxContent boxContentC">
+                        <div class="cbox" @click="toReport">
+                            <img
+                                :src="downImgSrc"
+                                width="100%"
+                                v-bind:class="{
+                                    cursor: info.nowRunState === '30',
+                                }"
+                            />
+                            <div
+                                v-bind:class="{
+                                    cursor: info.nowRunState === '30',
+                                }"
+                            >
+                                仿真云测试报告
+                            </div>
+                        </div>
                     </div>
                 </div>
             </div>
-        </div>
 
-        <div class="bottomPanel panel">
-            <div class="titlePanel">
-                <div class="titlePanelBor">任务信息</div>
-            </div>
-            <div class="box">
-                <div class="boxContentA">
-                    <div class="chart">
-                        <div class="pieTitle">任务运行状态统计:</div>
-                        <div class="pie">
-                            <pie-chart-project-info
-                                id="projectInfoPieA"
-                                :stateList="stateList"
-                                stateName="stateName"
-                                seriesName="任务运行状态统计"
-                            ></pie-chart-project-info>
+            <div class="centerPanel panel">
+                <div class="titlePanel">
+                    <div class="titlePanelBor">车辆配置</div>
+                </div>
+                <div class="box">
+                    <div class="boxContentA">
+                        <div class="info">
+                            <span>车辆名称:</span>
+                            <b>{{ info.vehicleName }}</b>
+                        </div>
+                        <div class="info">
+                            <span>车辆描述:</span>
+                            <b>{{ info.vehicleDescribe }}</b>
                         </div>
                     </div>
-                    <div class="chart">
-                        <div class="pieTitle">结果动态统计:</div>
-                        <div class="pie">
-                            <pie-chart-project-info
-                                id="projectInfoPieB"
-                                :stateList="resultList"
-                                stateName="resultName"
-                                seriesName="结果动态统计"
-                            ></pie-chart-project-info>
+                    <div class="boxContentB">
+                        <div class="list">
+                            <handle-config-list
+                                :showBtns="false"
+                                :curOne="curOne"
+                                :configList="configList"
+                                @curItem="curItem"
+                                :needHighline="false"
+                            ></handle-config-list>
+                        </div>
+                        <div class="canvasBox">
+                            <canvas-sensor
+                                v-if="modelImgSrc"
+                                :modelImgSrc="modelImgSrc"
+                                :configList="configList"
+                            ></canvas-sensor>
                         </div>
                     </div>
                 </div>
-                <div>
-                    <tableList
-                        ref="table"
-                        style="margin: 0 30px"
-                        :columns="columns"
-                        :getDataWay="getDataWay"
-                        :pagination="pagination"
-                    >
-                        <el-table-column
-                            label="操作"
-                            slot="cgInfos"
-                            align="center"
+            </div>
+
+            <div class="bottomPanel panel">
+                <div class="titlePanel">
+                    <div class="titlePanelBor">任务信息</div>
+                </div>
+                <div class="box">
+                    <div class="boxContentA">
+                        <div class="chart">
+                            <div class="pieTitle">任务运行状态统计:</div>
+                            <div class="pie">
+                                <pie-chart-project-info
+                                    id="projectInfoPieA"
+                                    :stateList="stateList"
+                                    stateName="stateName"
+                                    seriesName="任务运行状态统计"
+                                ></pie-chart-project-info>
+                            </div>
+                        </div>
+                        <div class="chart">
+                            <div class="pieTitle">得分统计:</div>
+                            <div class="pie">
+                                <pie-chart-project-info
+                                    id="projectInfoPieB"
+                                    :stateList="resultList"
+                                    stateName="resultName"
+                                    seriesName="得分统计"
+                                ></pie-chart-project-info>
+                            </div>
+                        </div>
+                    </div>
+                    <div>
+                        <tableList
+                            ref="table"
+                            :columns="columns"
+                            :getDataWay="getDataWay"
+                            :pagination="pagination"
                         >
-                            <template v-slot="scope">
-                                <i
-                                    @click="viewRow(scope.row)"
-                                    class="el-icon-view elIcon"
-                                    title="查看"
-                                ></i>
-                            </template>
-                        </el-table-column>
-                    </tableList>
+                            <el-table-column
+                                label="操作"
+                                slot="cgInfos"
+                                align="center"
+                            >
+                                <template v-slot="scope">
+                                    <i
+                                        @click="viewRow(scope.row)"
+                                        class="el-icon-view elIcon"
+                                        title="查看"
+                                    ></i>
+                                </template>
+                            </el-table-column>
+                        </tableList>
+                    </div>
                 </div>
             </div>
         </div>
+        <router-view v-else></router-view>
     </div>
 </template>
 
@@ -205,6 +230,7 @@ export default {
     data() {
         return {
             id: "",
+            projectType: "", // 1手动 2自动
             info: {},
             columns: [
                 {
@@ -231,12 +257,38 @@ export default {
                     label: "运行结果",
                     prop: "runResult",
                 },
+                {
+                    label: "得分",
+                    prop: "score",
+                },
                 {
                     label: "操作",
                     prop: "cgInfos",
                     template: true,
                 },
             ],
+            columnsA: [
+                {
+                    label: "测试项目",
+                    prop: "projectName",
+                },
+                {
+                    label: "场景数量",
+                    prop: "sceneNum",
+                },
+                {
+                    label: "测试权重%",
+                    prop: "weight",
+                },
+                {
+                    label: "测试得分",
+                    prop: "score",
+                },
+                {
+                    label: "得分率%",
+                    prop: "scoreRatio",
+                },
+            ],
             pagination: {
                 //分页使用
                 currentPage: 1,
@@ -253,8 +305,17 @@ export default {
                 data: this.$api.workManagement.selectProjectTaskList,
                 param: {
                     id: this.$route.query.id,
+                    projectType: this.$route.query.projectType,
                 },
             },
+            getDataWayA: {
+                //加载表格数据
+                dataType: "data",
+                type: "post",
+                firstRequest: false,
+                data: [],
+                param: {},
+            },
             // 传感器对象集合
             configList: {
                 camera: [],
@@ -282,18 +343,19 @@ export default {
     methods: {
         viewRow(row) {
             this.$router.push({
-                path: "/taskInfo",
+                path: "/manualRunProjectList/projectInfo/taskInfo",
                 query: {
                     taskId: row.id,
                     id: row.pid,
+                    projectType: this.projectType,
                 },
             });
         },
         toReport() {
             if (this.info.nowRunState === "30") {
                 this.$router.push({
-                    path: "/evaluationReport",
-                    query: { id: this.id },
+                    path: "/manualRunProjectList/projectInfo/evaluationReport",
+                    query: { id: this.id, projectType: this.projectType },
                 });
             }
         },
@@ -303,7 +365,7 @@ export default {
                 method: "post",
                 url: this.$api.workManagement.exportProjectReportById,
                 responseType: "blob",
-                data: { id: this.id },
+                data: { id: this.id, projectType: this.projectType },
             }).then((res) => {
                 let blob = new Blob([res]);
                 let fileName = "测试报告.pdf";
@@ -341,42 +403,42 @@ export default {
     },
 
     mounted() {
+        // console.log(this.$route);
         if (this.$route.query.id) {
             this.id = this.$route.query.id;
+            this.projectType = this.$route.query.projectType || "1";
+
+            this.$axios({
+                method: "post",
+                url: this.$api.workManagement.selectProjectDetailsById,
+                data: {
+                    id: this.id,
+                    projectType: this.projectType,
+                },
+            }).then((res) => {
+                if (res.code == 200 && res.info) {
+                    this.info = res.info;
+                    this.configList.camera = res.info.sensorCameraList || [];
+                    this.configList.ogt = res.info.sensorOgtList || [];
+                    this.configList.lidar = res.info.sensorLidarList || [];
+                    this.configList.gps = res.info.sensorGpsList || [];
+
+                    this.modelImgSrc = this.getImgUrl(res.info.vehicleTopView);
 
-            if (this.id) {
-                this.$axios({
-                    method: "post",
-                    url: this.$api.workManagement.selectProjectDetailsById,
-                    data: {
-                        id: this.id,
-                    },
-                }).then((res) => {
-                    if (res.code == 200 && res.info) {
-                        this.info = res.info;
-                        this.configList.camera =
-                            res.info.sensorCameraList || [];
-                        this.configList.ogt = res.info.sensorOgtList || [];
-                        this.configList.lidar = res.info.sensorLidarList || [];
-                        this.configList.gps = res.info.sensorGpsList || [];
-
-                        this.modelImgSrc = this.getImgUrl(
-                            res.info.vehicleTopView
-                        );
-
-                        if (this.info.nowRunState === "30") {
-                            this.downImgSrc = require("@/assets/common/image/others/hasDoc.png");
-                        } else {
-                            this.downImgSrc = require("@/assets/common/image/others/noDoc.png");
-                        }
-
-                        this.stateList = res.info.stateList || [];
-                        this.resultList = res.info.resultList || [];
+                    if (this.info.nowRunState === "30") {
+                        this.downImgSrc = require("@/assets/common/image/others/hasDoc.png");
                     } else {
-                        this.$message.error(res.message || "获取信息失败");
+                        this.downImgSrc = require("@/assets/common/image/others/noDoc.png");
                     }
-                });
-            }
+
+                    this.stateList = res.info.stateList || [];
+                    this.resultList = res.info.resultScoreList || [];
+
+                    this.getDataWayA.data = res.info.algorithmScoreList;
+                } else {
+                    this.$message.error(res.message || "获取信息失败");
+                }
+            });
         }
     },
 };
@@ -398,7 +460,7 @@ export default {
         border-bottom: 1px dotted @gray;
     }
 
-    .headPanel{
+    .headPanel {
         margin-bottom: 25px;
 
         .box {
@@ -430,6 +492,10 @@ export default {
         }
     }
 
+    .scorePanel {
+        margin-bottom: 25px;
+    }
+
     .topPanel {
         .box {
             flex: 1;

+ 30 - 3
src/views/workManagement/taskInfo.vue

@@ -36,6 +36,20 @@
             </div>
         </div>
 
+        <div class="panel">
+            <div class="titlePanel">
+                <div class="titlePanelBor">得分详情</div>
+            </div>
+            <div class="box">
+                <tableList
+                    style="margin: 30px 0"
+                    :columns="columnsB"
+                    :getDataWay="getDataWayB"
+                >
+                </tableList>
+            </div>
+        </div>
+
         <div class="panel boxB">
             <div class="titlePanel">
                 <div class="titlePanelBor">仿真动画</div>
@@ -194,7 +208,7 @@
                             id="taskInfoLineG"
                             :xList="xList"
                             :yList="yListG"
-                            yUnit="m/s"
+                            yUnit="km/h"
                         ></line-chart-task-info>
                     </div>
                 </div>
@@ -212,7 +226,6 @@ export default {
     components: { tableList, lineChartTaskInfo },
     data() {
         return {
-            // id: "",
             info: {},
             columns: [
                 {
@@ -276,6 +289,15 @@ export default {
                 ],
                 param: {},
             },
+            columnsB: [],
+            getDataWayB: {
+                //加载表格数据
+                dataType: "data",
+                type: "post",
+                firstRequest: false,
+                data: [],
+                param: {},
+            },
             xList: [],
             yListA: [],
             yListB: [],
@@ -301,6 +323,7 @@ export default {
     mounted() {
         let taskId = this.$route.query.taskId;
         let id = this.$route.query.id;
+        let projectType = this.$route.query.projectType || "1";
 
         if (taskId && id) {
             let id = this.$route.query.id;
@@ -311,6 +334,7 @@ export default {
                 data: {
                     id,
                     taskId,
+                    projectType,
                 },
             }).then((res) => {
                 if (res.code == 200 && res.info) {
@@ -329,6 +353,9 @@ export default {
                     }
 
                     this.videoUrl = res.info.videoUrl || [];
+
+                    this.columnsB = res.info.sceneScoreLiTitle;
+                    this.getDataWayB.data = res.info.sceneScoreLi;
                 } else {
                     this.$message.error(res.message || "获取信息失败");
                 }
@@ -340,7 +367,7 @@ export default {
 
 <style lang='less' scoped>
 .taskInfoPanel {
-    padding: 18px;
+    // padding: 18px;
 
     .panel {
         border: 1px solid #dfdfdf;