Browse Source

refactor: 统一存储键名前缀并优化流程节点组件

- 将存储键名前缀从'sys'改为'metro'以保持一致性
- 为流程节点添加数据变化监听器
- 优化错误消息显示为字符串拼接格式
- 调整节点添加按钮的显示逻辑
- 改进课程列表API参数处理
- 添加课程运行状态显示功能
zhanghaijun 11 months ago
parent
commit
ddcdd2a51b

+ 1 - 1
index.html

@@ -38,7 +38,7 @@
             return
           }
 
-          const themeType = localStorage.getItem('sys-theme')
+          const themeType = localStorage.getItem('metro-theme')
           if (themeType === 'dark') {
             document.documentElement.classList.add('dark')
           }

+ 12 - 1
src/api/course.api.ts

@@ -22,7 +22,18 @@ export interface Course {
 }
 
 export class CourseServer {
-  public static list = (params: Record<string, unknown>) => request.post<Course[]>('/course/list', params)
+  public static list = (params: Record<string, unknown>) => {
+    return request.post<Course[]>('/course/list', {
+      ...(params.courseID ? { courseID: Number(params.courseID) } : {}),
+      ...(params.courseName ? { courseName: params.courseName } : {}),
+      ...(params.typeID ? { typeID: Number(params.typeID) } : {}),
+      ...(params.externalTypeID ? { externalTypeID: Number(params.externalTypeID) } : {}),
+      ...(params.courseGUID ? { courseGUID: params.courseGUID } : {}),
+      ...(params.virtualRole ? { virtualRole: params.virtualRole } : {}),
+      ...(params.lineNo ? { lineNo: Number(params.lineNo) } : {}),
+      ...(params.runningMap ? { runningMap: params.runningMap } : {})
+    })
+  }
   public static detail = (courseId: string) => request.post<Course>('/course/detail/get', { courseId: Number(courseId) })
   public static add = (data: Record<string, unknown>) => {
     return request.post<{ courseId: string }>('/course/add', {

+ 2 - 2
src/components/business/EasyProcess/core/node_add.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="ep-node-add">
-    <div ref="nodeAddBtn" class="ep-node-add-btn" v-on:mouseenter="toggleVisibility(true)" v-on:mouseleave="toggleVisibility(false)">
-      <Icon v-if="isEdit" class="ep-node-add-btn-icon" :icon="'&#xe83e;'" color="#FFFFFF" />
+    <div v-if="isEdit" ref="nodeAddBtn" class="ep-node-add-btn" v-on:mouseenter="toggleVisibility(true)" v-on:mouseleave="toggleVisibility(false)">
+      <Icon class="ep-node-add-btn-icon" :icon="'&#xe83e;'" color="#FFFFFF" />
       <div ref="nodeAddSelect" :class="['ep-node-add-select-box', 'space-y-3', 'ep-node-add-right']" v-if="showSelect">
         <div class="ep-node-add-select-item" v-for="(item, index) in availableNodeTypes" :key="index" v-on:click="insertNodeIntoParent(item.type)">
           <Icon class="ep-node-add-select-item-icon" :icon="item.icon.name" :color="item.iconColor" />

+ 3 - 2
src/components/business/EasyProcess/core/node_base.vue

@@ -14,7 +14,7 @@
       <!-- 校验错误提示 -->
       <div class="ep-node-error-msg" v-if="isError">
         <div class="ep-node-error-msg-box">
-          <icon icon="svg:tips" :width="23" height="23" color="red" @mouseenter="showErrorTips(true)" @mouseleave="showErrorTips(false)" />
+          <icon icon="svg:tips" :width="23" height="23" :color="'red'" @mouseenter="showErrorTips(true)" @mouseleave="showErrorTips(false)" />
           <div class="ep-node-error-tips space-y-1" v-if="errorTips">
             <div v-for="(msg, index) in errorMessage.split(',')" :key="index">
               {{ msg }}
@@ -221,8 +221,9 @@
         left: 45px;
         z-index: 3;
         display: flex;
+        flex-direction: column;
         min-width: 150px;
-        padding: 16px;
+        padding: 8px 8px 8px 16px;
         background-color: #fff;
         border-radius: 5px;
         box-shadow: 5px 5px 10px 2px rgb(0 0 0 / 20%);

+ 7 - 1
src/components/business/EasyProcess/node/fault_node.vue

@@ -11,6 +11,12 @@
 
   const props = withDefaults(defineProps<{ node: Process.FaultNode }>(), {})
   const nodeData = ref<Record<string, unknown>>(props.node.nodeData || {})
+  watch(
+    () => props.node.nodeData,
+    (newVal) => {
+      nodeData.value = newVal || {}
+    }
+  )
   const roleIcon: string[] = ['role_default', 'role_substation', 'role_catenary', 'role_dispatch', 'role_isolator', 'role_supply']
 
   const getIcon = computed(() => {
@@ -34,6 +40,6 @@
     if (!nodeData.value?.templateID) {
       messages.push('请选择故障模板')
     }
-    return { valid: messages.length === 0, messages }
+    return { valid: messages.length === 0, message: messages.join(',') }
   })
 </script>

+ 7 - 2
src/components/business/EasyProcess/node/operation_node.vue

@@ -11,7 +11,12 @@
 
   const props = withDefaults(defineProps<{ node: Process.OperationNode }>(), {})
   const nodeData = ref<Record<string, unknown>>(props.node.nodeData || {})
-
+  watch(
+    () => props.node.nodeData,
+    (newVal) => {
+      nodeData.value = newVal || {}
+    }
+  )
   const roleIcon: string[] = ['role_default', 'role_substation', 'role_catenary', 'role_dispatch', 'role_isolator', 'role_supply']
 
   const getIcon = computed(() => {
@@ -35,6 +40,6 @@
     if (!nodeData.value?.templateID) {
       messages.push('请选择操作模板')
     }
-    return { valid: messages.length === 0, messages }
+    return { valid: messages.length === 0, message: messages.join(',') }
   })
 </script>

+ 7 - 1
src/components/business/EasyProcess/node/voice_node.vue

@@ -11,6 +11,12 @@
 
   const props = withDefaults(defineProps<{ node: Process.VoiceNode }>(), {})
   const nodeData = ref<Record<string, unknown>>(props.node.nodeData || {})
+  watch(
+    () => props.node.nodeData,
+    (newVal) => {
+      nodeData.value = newVal || {}
+    }
+  )
 
   const roleIcon: string[] = ['role_default', 'role_substation', 'role_catenary', 'role_dispatch', 'role_isolator', 'role_supply']
 
@@ -35,6 +41,6 @@
     if (!nodeData.value?.templateID) {
       messages.push('请选择语言模板')
     }
-    return { valid: messages.length === 0, messages }
+    return { valid: messages.length === 0, message: messages.join(',') }
   })
 </script>

+ 3 - 3
src/utils/storage/storage-config.ts

@@ -7,13 +7,13 @@ export class StorageConfig {
   static readonly CURRENT_VERSION = __APP_VERSION__
 
   /** 存储键前缀 */
-  static readonly STORAGE_PREFIX = 'sys-v'
+  static readonly STORAGE_PREFIX = 'metro-v'
 
   /** 版本键名 */
-  static readonly VERSION_KEY = 'sys-version'
+  static readonly VERSION_KEY = 'metro-version'
 
   /** 主题键名(index.html中使用了,如果修改,需要同步修改) */
-  static readonly THEME_KEY = 'sys-theme'
+  static readonly THEME_KEY = 'metro-theme'
 
   /** 跳过升级检查的版本 */
   static readonly SKIP_UPGRADE_VERSION = '1.0.0'

+ 20 - 2
src/views/train/course/trainer_run/index.vue

@@ -21,11 +21,19 @@
         <EasyProcess ref="processRef" :data="course?.courseDataStream" :edit="false" />
       </div>
       <div class="flex flex-col gap-4">
-        <div class="h-[180px] w-[320px] border p-4">
+        <div v-if="!runStatus || runStatus?.runCourseID === Number(courseId)" class="h-[180px] w-[320px] border p-4">
           <el-button v-if="!isRunning" type="primary" @click="courseStart">开始课程</el-button>
           <el-button v-else type="primary" @click="coursePause">暂停课程</el-button>
           <el-button type="primary" @click="courseReset">结束课程</el-button>
         </div>
+        <div v-else class="h-[180px] w-[320px] border p-4">
+          <div class="text-lg font-medium">正在运行的课程ID:{{ runStatus.runCourseID }} </div>
+          <div class="text-lg font-medium">正在运行的课程名称:{{ runStatus.runCourseName }} </div>
+          <div class="flex items-center gap-2 text-lg font-medium">
+            <i class="iconfont-sys">&#xe6f7;</i>
+            <span>{{ runStatus.runDateTime }} </span>
+          </div>
+        </div>
         <div class="flex-1 border p-4">
           <div v-if="processData" class="mb-4 text-lg font-medium">
             <div>节点名称:{{ processData?.nodeName }}</div>
@@ -46,7 +54,7 @@
   import cover2 from '@imgs/cover/img2.webp'
   import cover3 from '@imgs/cover/img3.webp'
   import { Picture as IconPicture } from '@element-plus/icons-vue'
-  import { Course, CourseServer, CourseRunServer } from '@/api/course.api'
+  import { Course, CourseServer, CourseRunServer, CourseRunStatus } from '@/api/course.api'
   import courseDetail from './course-detail.vue'
   import { useTimer } from '@/composables/useTimer'
 
@@ -85,7 +93,17 @@
     }
   })
 
+  const runStatus = ref<CourseRunStatus>()
+  const getRunStatus = () => {
+    CourseRunServer.status().then((res) => {
+      if (res.data && res.data.runCourseID) {
+        runStatus.value = res.data
+      }
+    })
+  }
+
   onMounted(async () => {
+    getRunStatus()
     const { data } = await CourseServer.detail(courseId.value)
     course.value = data
   })

+ 2 - 2
src/views/train/fault/index.vue

@@ -1,9 +1,9 @@
 <template>
-  <el-card class="art-full-height w-full">
+  <el-card class="w-full">
     <template v-slot:header>
       <span>设备视图</span>
     </template>
-    <el-row :gutter="20" class="art-full-height w-full">
+    <el-row class="art-full-height w-full">
       <el-col :span="16">
         <div class="art-full-height w-full">
           <Meta2dView :data="data" :preview="true" />