|
@@ -1,5 +1,6 @@
|
|
|
<!--模拟演练管理-->
|
|
<!--模拟演练管理-->
|
|
|
<template>
|
|
<template>
|
|
|
|
|
+ <div class="sim-wrap">
|
|
|
<div class="app-container">
|
|
<div class="app-container">
|
|
|
<div class="sim-layout">
|
|
<div class="sim-layout">
|
|
|
<!-- ===== 左列 ===== -->
|
|
<!-- ===== 左列 ===== -->
|
|
@@ -11,7 +12,7 @@
|
|
|
<el-button type="primary" size="small" @click="handleAddProject">新增</el-button>
|
|
<el-button type="primary" size="small" @click="handleAddProject">新增</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="panel-body">
|
|
<div class="panel-body">
|
|
|
- <div class="project-item" v-for="item in projects" :key="item.id">
|
|
|
|
|
|
|
+ <div class="project-item" v-for="item in projects" :key="item.id" :class="{ selected: activeProjectId === item.id }" @click="selectProject(item)">
|
|
|
<div class="project-info">
|
|
<div class="project-info">
|
|
|
<div class="project-name">{{ item.name }}</div>
|
|
<div class="project-name">{{ item.name }}</div>
|
|
|
<div class="project-date">{{ item.date }}</div>
|
|
<div class="project-date">{{ item.date }}</div>
|
|
@@ -149,147 +150,185 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="panel-body">
|
|
<div class="panel-body">
|
|
|
<div class="metric-grid">
|
|
<div class="metric-grid">
|
|
|
- <div class="metric-item">
|
|
|
|
|
- <div class="metric-label">任务完成率</div>
|
|
|
|
|
- <div class="metric-value">33%</div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="metric-item">
|
|
|
|
|
- <div class="metric-label">平均响应时间</div>
|
|
|
|
|
- <div class="metric-value">30s</div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="metric-item">
|
|
|
|
|
- <div class="metric-label">应急评估等级</div>
|
|
|
|
|
- <div class="metric-value highlight">良好</div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="metric-item">
|
|
|
|
|
- <div class="metric-label">建议</div>
|
|
|
|
|
- <div class="metric-value small">加强指挥调度协同</div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="stat-cards">
|
|
|
|
|
- <div class="stat-card">
|
|
|
|
|
- <div class="stat-title">应急统计</div>
|
|
|
|
|
- <div class="stat-content">事件响应时间 28秒</div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="stat-card">
|
|
|
|
|
- <div class="stat-title">应急评估</div>
|
|
|
|
|
- <div class="stat-content">任务完成率 67%</div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <div class="metric-item"><div class="metric-label">任务完成率</div><div class="metric-value">{{ simResultData.task_completion_rate || '--' }}</div></div>
|
|
|
|
|
+ <div class="metric-item"><div class="metric-label">平均响应时间</div><div class="metric-value">{{ simResultData.avg_response_time || '--' }}</div></div>
|
|
|
|
|
+ <div class="metric-item"><div class="metric-label">应急评估等级</div><div class="metric-value highlight">{{ simResultData.emergency_level || '--' }}</div></div>
|
|
|
|
|
+ <div class="metric-item"><div class="metric-label">建议</div><div class="metric-value small">{{ simResultData.suggestion || '暂无' }}</div></div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 项目表单弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="projDialogVisible" title="演练项目" width="450px" destroy-on-close>
|
|
|
|
|
+ <el-form :model="projForm" label-width="80px">
|
|
|
|
|
+ <el-form-item label="项目名称"><el-input v-model="projForm.name" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="所属系统">
|
|
|
|
|
+ <el-select v-model="projForm.category" style="width:100%">
|
|
|
|
|
+ <el-option label="燃气" value="燃气" /><el-option label="排水" value="排水" /><el-option label="供水" value="供水" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer><el-button @click="projDialogVisible=false">取消</el-button><el-button type="primary" @click="handleProjSubmit">确定</el-button></template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 场景编辑弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="sceneDialogVisible" title="场景编辑" width="450px" destroy-on-close>
|
|
|
|
|
+ <el-input v-model="sceneNewTag" placeholder="输入新场景元素" style="width:70%"><template #append><el-button @click="addSceneTag()">添加</el-button></template></el-input>
|
|
|
|
|
+ <div style="margin-top:12px"><el-tag v-for="t in currentSceneTags" :key="t" closable @close="removeSceneTag(t)" style="margin:4px">{{t}}</el-tag></div>
|
|
|
|
|
+ <template #footer><el-button @click="sceneDialogVisible=false">关闭</el-button></template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 事件弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="eventDialogVisible" title="新增事件" width="450px" destroy-on-close>
|
|
|
|
|
+ <el-form :model="eventForm" label-width="80px">
|
|
|
|
|
+ <el-form-item label="事件名称"><el-input v-model="eventForm.name" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="事件描述"><el-input v-model="eventForm.description" type="textarea" :rows="3" /></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer><el-button @click="eventDialogVisible=false">取消</el-button><el-button type="primary" @click="handleEventSubmit">确定</el-button></template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 角色弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="roleDialogVisible" title="新增角色" width="450px" destroy-on-close>
|
|
|
|
|
+ <el-form :model="roleForm" label-width="80px">
|
|
|
|
|
+ <el-form-item label="角色名称"><el-input v-model="roleForm.name" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="角色类型"><el-select v-model="roleForm.roleType" style="width:100%"><el-option label="指挥类" value="指挥类"/><el-option label="救援类" value="救援类"/><el-option label="观摩类" value="观摩类"/></el-select></el-form-item>
|
|
|
|
|
+ <el-form-item label="技能"><el-input v-model="roleForm.skills" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="装备"><el-input v-model="roleForm.equipment" /></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer><el-button @click="roleDialogVisible=false">取消</el-button><el-button type="primary" @click="handleRoleSubmit">确定</el-button></template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 任务弹窗 -->
|
|
|
|
|
+ <el-dialog v-model="taskDialogVisible" title="新增任务" width="450px" destroy-on-close>
|
|
|
|
|
+ <el-form :model="taskForm" label-width="80px">
|
|
|
|
|
+ <el-form-item label="任务名称"><el-input v-model="taskForm.name" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="任务描述"><el-input v-model="taskForm.description" type="textarea" :rows="3" /></el-form-item>
|
|
|
|
|
+ <el-form-item label="绑定角色"><el-select v-model="taskForm.bindRoleId" style="width:100%"><el-option v-for="r in roles" :key="r.id" :label="r.name" :value="r.id"/></el-select></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <template #footer><el-button @click="taskDialogVisible=false">取消</el-button><el-button type="primary" @click="handleTaskSubmit">确定</el-button></template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { ref } from 'vue'
|
|
|
|
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
import {
|
|
import {
|
|
|
Folder, Edit, Delete, PictureFilled, Warning, User, List,
|
|
Folder, Edit, Delete, PictureFilled, Warning, User, List,
|
|
|
VideoPlay, Promotion, Document, DataAnalysis
|
|
VideoPlay, Promotion, Document, DataAnalysis
|
|
|
} from '@element-plus/icons-vue'
|
|
} from '@element-plus/icons-vue'
|
|
|
|
|
+import { getSimProjects, saveSimProject, deleteSimProject, addSimLog, processSimDrill, getSimScene, getSimEvent, getSimRole, getSimTask, getSimLog, getSimResult, saveSimScene, deleteSimScene, saveSimEvent, deleteSimEvent, saveSimRole, saveSimTask } from '@/api/pipeNetwork/basic'
|
|
|
|
|
|
|
|
-// ---------- 演练项目 ----------
|
|
|
|
|
-let projectId = 3
|
|
|
|
|
-const projects = ref([
|
|
|
|
|
- { id: 1, name: '化工园区毒气泄漏演练', date: '2025-01-01' },
|
|
|
|
|
- { id: 2, name: '海上溢油应急联合演练', date: '2025-01-01' },
|
|
|
|
|
- { id: 3, name: '化工园区综合应急演练', date: '2025-03-15' }
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
|
|
+const projects = ref([])
|
|
|
const projectSearch = ref('')
|
|
const projectSearch = ref('')
|
|
|
-const handleSearchProject = () => { ElMessage.success('查询项目(Mock)') }
|
|
|
|
|
-const handleAddProject = () => { ElMessage.success('新增演练项目(Mock)') }
|
|
|
|
|
-const handleEditProject = (item) => { ElMessage.success(`编辑项目: ${item.name}`) }
|
|
|
|
|
-const handleDeleteProject = (item) => {
|
|
|
|
|
- ElMessageBox.confirm('确认删除该项目?', '提示', { type: 'warning' }).then(() => {
|
|
|
|
|
- projects.value = projects.value.filter(p => p.id !== item.id)
|
|
|
|
|
- ElMessage.success('删除成功')
|
|
|
|
|
- }).catch(() => {})
|
|
|
|
|
|
|
+const handleSearchProject = () => { loadData() }
|
|
|
|
|
+// 项目弹窗
|
|
|
|
|
+const projDialogVisible = ref(false)
|
|
|
|
|
+const projForm = ref({ id: null, name: '', category: '燃气' })
|
|
|
|
|
+const handleAddProject = () => { projForm.value = { id: null, name: '', category: '燃气' }; projDialogVisible.value = true }
|
|
|
|
|
+const handleEditProject = async (item) => { projForm.value = { ...item }; projDialogVisible.value = true }
|
|
|
|
|
+const handleDeleteProject = (item) => { ElMessageBox.confirm('确认删除?', '提示', { type: 'warning' }).then(async () => { await deleteSimProject(item.id); ElMessage.success('删除成功'); loadData() }).catch(() => {}) }
|
|
|
|
|
+const handleProjSubmit = async () => {
|
|
|
|
|
+ const d = projForm.value
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (d.id) { const p = projects.value.find(x => x.id === d.id); if (p) { p.name = d.name; p.category = d.category } }
|
|
|
|
|
+ else { await saveSimProject({ name: d.name, category: d.category, createDate: new Date().toISOString().substring(0,10) }); }
|
|
|
|
|
+ ElMessage.success('保存成功'); projDialogVisible.value = false; loadData()
|
|
|
|
|
+ } catch (e) { ElMessage.error('保存失败') }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// ---------- 场景设置 ----------
|
|
|
|
|
-const currentSceneTags = ref(['控制室', '泄漏点', '氨气泄露', '火灾蔓延'])
|
|
|
|
|
-const sceneLibrary = ref(['控制室', '泄漏点', '储罐区', '氨气泄露', '火灾蔓延', '风向标'])
|
|
|
|
|
-
|
|
|
|
|
-const addSceneTag = (tag) => {
|
|
|
|
|
- if (!currentSceneTags.value.includes(tag)) {
|
|
|
|
|
- currentSceneTags.value.push(tag)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+// 选中项目时加载子数据
|
|
|
|
|
+const activeProjectId = ref(null)
|
|
|
|
|
+const activeCategory = ref('')
|
|
|
|
|
+
|
|
|
|
|
+// 场景
|
|
|
|
|
+const currentSceneTags = ref([])
|
|
|
|
|
+const sceneLibrary = ref([])
|
|
|
|
|
+const sceneDialogVisible = ref(false)
|
|
|
|
|
+const sceneNewTag = ref('')
|
|
|
|
|
+let sceneDataCache = []
|
|
|
|
|
+async function loadScene(id) { try { const r = await getSimScene(id); sceneDataCache = r.data||[]; sceneLibrary.value = sceneDataCache.map(s => s.tagName); currentSceneTags.value = sceneDataCache.filter(s => s.isActive===1).map(s => s.tagName) } catch (e) {} }
|
|
|
|
|
+const addSceneTag = async (tag) => {
|
|
|
|
|
+ const t = String(tag || sceneNewTag.value || '').trim(); if (!t) return
|
|
|
|
|
+ if (currentSceneTags.value.includes(t)) { ElMessage.warning('已存在'); return }
|
|
|
|
|
+ try {
|
|
|
|
|
+ await saveSimScene({ projectId: activeProjectId.value, tagName: t, isActive: 1 })
|
|
|
|
|
+ sceneNewTag.value = ''; loadScene(activeProjectId.value)
|
|
|
|
|
+ } catch (e) { ElMessage.error('添加失败') }
|
|
|
}
|
|
}
|
|
|
-const removeSceneTag = (tag) => {
|
|
|
|
|
- currentSceneTags.value = currentSceneTags.value.filter(t => t !== tag)
|
|
|
|
|
|
|
+const removeSceneTag = async (tag) => {
|
|
|
|
|
+ const existing = sceneDataCache.find(s => s.tagName === tag && s.isActive === 1)
|
|
|
|
|
+ if (existing) { try { await deleteSimScene(existing.id); loadScene(activeProjectId.value) } catch (e) { ElMessage.error('删除失败') } }
|
|
|
|
|
+ else { currentSceneTags.value = currentSceneTags.value.filter(t => t !== tag) }
|
|
|
}
|
|
}
|
|
|
-const handleEditScene = () => { ElMessage.success('编辑场景(Mock)') }
|
|
|
|
|
-
|
|
|
|
|
-// ---------- 事件设置 ----------
|
|
|
|
|
-const events = ref([
|
|
|
|
|
- { id: 1, name: '氯气泄漏', desc: '突发事件: 储罐区发生泄漏,需紧急处置' },
|
|
|
|
|
- { id: 2, name: '火灾蔓延', desc: '次生灾害: 爆炸引起火灾' }
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-const handleAddEvent = () => { ElMessage.success('新增事件(Mock)') }
|
|
|
|
|
-const addToScene = (evt) => { ElMessage.success(`已将"${evt.name}"添加到场景`) }
|
|
|
|
|
-
|
|
|
|
|
-// ---------- 角色设置 ----------
|
|
|
|
|
-const roles = ref([
|
|
|
|
|
- { id: 1, name: '现场指挥员', type: '指挥类', skills: '消防指挥、泄漏处置', equipment: '防护服、指挥终端' },
|
|
|
|
|
- { id: 2, name: '消防队员', type: '救援类', skills: '灭火、堵漏', equipment: '防护服、灭火器' }
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-const handleAddRole = () => { ElMessage.success('新增角色(Mock)') }
|
|
|
|
|
-
|
|
|
|
|
-// ---------- 任务设置 ----------
|
|
|
|
|
-const tasks = ref([
|
|
|
|
|
- { id: 1, name: '启动应急响应', desc: '指挥员需下达疏散命令', bindRole: '现场指挥员' },
|
|
|
|
|
- { id: 2, name: '演练整体评估', desc: '完成评价报告', bindRole: '现场指挥员' }
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-const handleAddTask = () => { ElMessage.success('新增任务(Mock)') }
|
|
|
|
|
-
|
|
|
|
|
-// ---------- 过程管理 ----------
|
|
|
|
|
-const eventLogs = ref([
|
|
|
|
|
- { time: '16:11:05', text: '演练启动' },
|
|
|
|
|
- { time: '16:11:06', text: '演练暂停' },
|
|
|
|
|
- { time: '16:11:07', text: '触发事件: 氯气泄漏 - 影响范围扩大,角色已分配' },
|
|
|
|
|
- { time: '16:11:10', text: '触发事件: 氯气泄漏 - 影响范围进一步扩大' }
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-const startDrill = () => {
|
|
|
|
|
- const now = new Date()
|
|
|
|
|
- const time = now.toTimeString().slice(0, 8)
|
|
|
|
|
- eventLogs.value.push({ time, text: '演练启动' })
|
|
|
|
|
- ElMessage.success('演练已启动')
|
|
|
|
|
|
|
+const handleEditScene = () => { sceneNewTag.value = ''; sceneDialogVisible.value = true }
|
|
|
|
|
+
|
|
|
|
|
+// 事件
|
|
|
|
|
+const events = ref([])
|
|
|
|
|
+const eventDialogVisible = ref(false)
|
|
|
|
|
+const eventForm = ref({ name: '', description: '' })
|
|
|
|
|
+async function loadEvent(id) { try { const r = await getSimEvent(id); events.value = (r.data||[]).map(e => ({ id: e.id, name: e.name, desc: e.description })) } catch (e) {} }
|
|
|
|
|
+const handleAddEvent = () => { eventForm.value = { name: '', description: '' }; eventDialogVisible.value = true }
|
|
|
|
|
+const handleEventSubmit = async () => {
|
|
|
|
|
+ try { await saveSimEvent({ projectId: activeProjectId.value, name: eventForm.value.name, description: eventForm.value.description }); ElMessage.success('新增成功'); eventDialogVisible.value = false; loadEvent(activeProjectId.value) } catch (e) { ElMessage.error('新增失败') }
|
|
|
}
|
|
}
|
|
|
-const pauseDrill = () => {
|
|
|
|
|
- const now = new Date()
|
|
|
|
|
- const time = now.toTimeString().slice(0, 8)
|
|
|
|
|
- eventLogs.value.push({ time, text: '演练暂停' })
|
|
|
|
|
- ElMessage.warning('演练已暂停')
|
|
|
|
|
|
|
+const addToScene = async (evt) => {
|
|
|
|
|
+ const existing = sceneDataCache.find(s => s.tagName === evt.name)
|
|
|
|
|
+ if (existing) {
|
|
|
|
|
+ try { await saveSimScene({ id: existing.id, projectId: activeProjectId.value, tagName: evt.name, isActive: 1 }); loadScene(activeProjectId.value); ElMessage.success(`已将"${evt.name}"添加到场景`) } catch (e) {}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ try { await saveSimScene({ projectId: activeProjectId.value, tagName: evt.name, isActive: 1 }); loadScene(activeProjectId.value); ElMessage.success(`已将"${evt.name}"添加到场景`) } catch (e) {}
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-const exitDrill = () => {
|
|
|
|
|
- ElMessageBox.confirm('确认退出演练?', '提示', { type: 'warning' }).then(() => {
|
|
|
|
|
- const now = new Date()
|
|
|
|
|
- const time = now.toTimeString().slice(0, 8)
|
|
|
|
|
- eventLogs.value.push({ time, text: '演练退出' })
|
|
|
|
|
- ElMessage.info('演练已退出')
|
|
|
|
|
- }).catch(() => {})
|
|
|
|
|
|
|
+
|
|
|
|
|
+// 角色
|
|
|
|
|
+const roles = ref([])
|
|
|
|
|
+const roleDialogVisible = ref(false)
|
|
|
|
|
+const roleForm = ref({ name: '', roleType: '指挥类', skills: '', equipment: '' })
|
|
|
|
|
+async function loadRole(id) { try { const r = await getSimRole(id); roles.value = (r.data||[]).map(rr => ({ id: rr.id, name: rr.name, type: rr.roleType, skills: rr.skills, equipment: rr.equipment })) } catch (e) {} }
|
|
|
|
|
+const handleAddRole = () => { roleForm.value = { name: '', roleType: '指挥类', skills: '', equipment: '' }; roleDialogVisible.value = true }
|
|
|
|
|
+const handleRoleSubmit = async () => {
|
|
|
|
|
+ try { await saveSimRole({ projectId: activeProjectId.value, ...roleForm.value }); ElMessage.success('新增成功'); roleDialogVisible.value = false; loadRole(activeProjectId.value) } catch (e) { ElMessage.error('新增失败') }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const triggerEvent = () => {
|
|
|
|
|
- const now = new Date()
|
|
|
|
|
- const time = now.toTimeString().slice(0, 8)
|
|
|
|
|
- eventLogs.value.push({ time, text: '触发事件(发展): 事态发展变化' })
|
|
|
|
|
- ElMessage.success('事件已触发')
|
|
|
|
|
|
|
+// 任务
|
|
|
|
|
+const tasks = ref([])
|
|
|
|
|
+const taskDialogVisible = ref(false)
|
|
|
|
|
+const taskForm = ref({ name: '', description: '', bindRoleId: null })
|
|
|
|
|
+async function loadTask(id) { try { const r = await getSimTask(id); tasks.value = (r.data||[]).map(t => ({ id: t.id, name: t.name, desc: t.description, bindRole: t.bindRoleId })) } catch (e) {} }
|
|
|
|
|
+const handleAddTask = () => { taskForm.value = { name: '', description: '', bindRoleId: roles.value[0]?.id || null }; taskDialogVisible.value = true }
|
|
|
|
|
+const handleTaskSubmit = async () => {
|
|
|
|
|
+ try { await saveSimTask({ projectId: activeProjectId.value, ...taskForm.value }); ElMessage.success('新增成功'); taskDialogVisible.value = false; loadTask(activeProjectId.value) } catch (e) { ElMessage.error('新增失败') }
|
|
|
}
|
|
}
|
|
|
-const endEvent = () => {
|
|
|
|
|
- const now = new Date()
|
|
|
|
|
- const time = now.toTimeString().slice(0, 8)
|
|
|
|
|
- eventLogs.value.push({ time, text: '事件结束' })
|
|
|
|
|
- ElMessage.info('事件已结束')
|
|
|
|
|
|
|
+
|
|
|
|
|
+// 结果数据
|
|
|
|
|
+const simResultData = ref({})
|
|
|
|
|
+async function loadResult(id) { try { const r = await getSimResult(id); simResultData.value = r.data || {} } catch (e) {} }
|
|
|
|
|
+async function loadLogs(id) { try { const r = await getSimLog(id); const rows = r.data || []; if (rows.length) eventLogs.value = rows.map(l => ({ time: (l.logTime||'').substring(11,19) || '--', text: l.content || l.action })) } catch (e) {} }
|
|
|
|
|
+
|
|
|
|
|
+// 选中项目
|
|
|
|
|
+function selectProject(item) {
|
|
|
|
|
+ activeProjectId.value = item.id
|
|
|
|
|
+ activeCategory.value = item.category || item.category_name || ''
|
|
|
|
|
+ loadScene(item.id); loadEvent(item.id); loadRole(item.id); loadTask(item.id); loadResult(item.id); loadLogs(item.id)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// ---------- 过程管理 ----------
|
|
|
|
|
+const eventLogs = ref([])
|
|
|
|
|
+
|
|
|
|
|
+async function loadData() { try { const res = await getSimProjects(); const rows = res.data || []; if (rows.length) { projects.value = rows.map(d => ({ id: d.id, name: d.name, category: d.category, date: d.create_date || d.createDate })); selectProject(projects.value[0]) } } catch (e) {} }
|
|
|
|
|
+onMounted(() => { loadData() })
|
|
|
|
|
+
|
|
|
|
|
+const doProcess = (action) => { return processSimDrill(activeProjectId.value, action, activeCategory.value) }
|
|
|
|
|
+const reloadLogs = () => { if (activeProjectId.value) loadLogs(activeProjectId.value) }
|
|
|
|
|
+const startDrill = () => { doProcess('启动').then(() => { reloadLogs(); ElMessage.success('演练已启动') }).catch(()=>{}) }
|
|
|
|
|
+const pauseDrill = () => { doProcess('暂停').then(() => { reloadLogs(); ElMessage.warning('演练已暂停') }).catch(()=>{}) }
|
|
|
|
|
+const exitDrill = () => { ElMessageBox.confirm('确认退出?','提示',{type:'warning'}).then(()=>{ doProcess('退出').then(() => reloadLogs()).catch(()=>{}) }).catch(()=>{}) }
|
|
|
|
|
+const triggerEvent = () => { doProcess('触发事件').then(() => { reloadLogs(); ElMessage.success('事件已触发') }).catch(()=>{}) }
|
|
|
|
|
+const endEvent = () => { doProcess('结束事件').then(() => { reloadLogs(); ElMessage.info('事件已结束') }).catch(()=>{}) }
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
<style scoped lang="scss">
|
|
@@ -360,7 +399,9 @@ const endEvent = () => {
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
padding: 8px 0;
|
|
padding: 8px 0;
|
|
|
border-bottom: 1px dashed #ebeef5;
|
|
border-bottom: 1px dashed #ebeef5;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
|
|
|
|
|
+ &.selected { background: #ecf5ff; border-left: 3px solid #409eff; padding-left: 8px; }
|
|
|
&:last-child { border-bottom: none; }
|
|
&:last-child { border-bottom: none; }
|
|
|
|
|
|
|
|
.project-info {
|
|
.project-info {
|