From 689dd676fc0efb31236d989334122590b7198d61 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期一, 16 三月 2026 09:30:11 +0800
Subject: [PATCH] 1
---
Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue | 338 ++++++++++++++++++++++++++++++++-----------------------
1 files changed, 197 insertions(+), 141 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue
index 12eb36c..cf643a5 100644
--- a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue
+++ b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Web/src/views/DetailsView.vue
@@ -1,137 +1,118 @@
<template>
<div>
- <div v-if="loading" class="text-center py-5">
- <div class="spinner-border text-primary" role="status">
- <span class="visually-hidden">鍔犺浇涓�...</span>
- </div>
+ <div v-if="loading" class="loading-container">
+ <el-icon class="loading-icon" :size="40"><Loading /></el-icon>
+ <p>鍔犺浇涓�...</p>
</div>
<div v-else-if="errorMsg">
- <div class="alert alert-danger">{{ errorMsg }}</div>
- <router-link to="/" class="btn btn-primary">杩斿洖鍒楄〃</router-link>
+ <el-result icon="error" :title="errorMsg">
+ <template #extra>
+ <el-button type="primary" @click="$router.push('/')">杩斿洖鍒楄〃</el-button>
+ </template>
+ </el-result>
</div>
<div v-else-if="instance">
- <div class="d-flex justify-content-between align-items-center mb-4">
- <div>
- <h2 class="mb-0">
- <i class="bi bi-info-circle me-2"></i>瀹炰緥璇︽儏
+ <div class="page-header">
+ <div class="header-left">
+ <h2>
+ <el-icon :size="24"><InfoFilled /></el-icon>
+ 瀹炰緥璇︽儏
</h2>
- <p class="text-muted mb-0 mt-1">{{ instance.name }} ({{ instance.instanceId }})</p>
+ <p class="text-muted">{{ instance.name }} ({{ instance.instanceId }})</p>
</div>
- <router-link to="/" class="btn btn-outline-secondary">
- <i class="bi bi-arrow-left me-1"></i>杩斿洖鍒楄〃
- </router-link>
+ <el-button @click="$router.push('/')">
+ <el-icon><Back /></el-icon>
+ 杩斿洖鍒楄〃
+ </el-button>
</div>
<!-- 鐘舵�佸崱鐗� -->
- <div class="row mb-4">
- <div class="col-md-3">
- <div class="card text-center">
- <div class="card-body">
- <h6 class="card-subtitle mb-2 text-muted">鐘舵��</h6>
- <h4 :class="['mb-0', getStatusClass(instance.status)]">
- {{ getStatusText(instance.status) }}
- </h4>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="card text-center">
- <div class="card-body">
- <h6 class="card-subtitle mb-2 text-muted">杩炴帴瀹㈡埛绔�</h6>
- <h4 class="mb-0">
- <i class="bi bi-people-fill me-1"></i>{{ instance.clientCount }}
- </h4>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="card text-center">
- <div class="card-body">
- <h6 class="card-subtitle mb-2 text-muted">鎬昏姹傛暟</h6>
- <h4 class="mb-0">{{ instance.totalRequests }}</h4>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="card text-center">
- <div class="card-body">
- <h6 class="card-subtitle mb-2 text-muted">绔彛</h6>
- <h4 class="mb-0">{{ instance.port }}</h4>
- </div>
- </div>
- </div>
- </div>
+ <el-row :gutter="20" class="status-cards">
+ <el-col :xs="12" :sm="6">
+ <el-card shadow="hover" class="status-card">
+ <el-statistic title="鐘舵��">
+ <template #default>
+ <el-tag :type="getStatusTagType(instance.status)" size="large">
+ {{ getStatusText(instance.status) }}
+ </el-tag>
+ </template>
+ </el-statistic>
+ </el-card>
+ </el-col>
+ <el-col :xs="12" :sm="6">
+ <el-card shadow="hover" class="status-card">
+ <el-statistic title="杩炴帴瀹㈡埛绔�" :value="instance.clientCount">
+ <template #suffix>
+ <el-icon><User /></el-icon>
+ </template>
+ </el-statistic>
+ </el-card>
+ </el-col>
+ <el-col :xs="12" :sm="6">
+ <el-card shadow="hover" class="status-card">
+ <el-statistic title="鎬昏姹傛暟" :value="instance.totalRequests" />
+ </el-card>
+ </el-col>
+ <el-col :xs="12" :sm="6">
+ <el-card shadow="hover" class="status-card">
+ <el-statistic title="绔彛" :value="instance.port" />
+ </el-card>
+ </el-col>
+ </el-row>
<!-- 璇︾粏淇℃伅 -->
- <div class="card mb-4">
- <div class="card-header">
- <h5 class="mb-0">鍩烘湰淇℃伅</h5>
- </div>
- <div class="card-body">
- <table class="table table-bordered">
- <tbody>
- <tr>
- <th style="width: 30%">瀹炰緥ID</th>
- <td>{{ instance.instanceId }}</td>
- </tr>
- <tr>
- <th>瀹炰緥鍚嶇О</th>
- <td>{{ instance.name }}</td>
- </tr>
- <tr>
- <th>PLC鍨嬪彿</th>
- <td>{{ getPlcTypeText(instance.plcType) }}</td>
- </tr>
- <tr>
- <th>鐩戝惉绔彛</th>
- <td>{{ instance.port }}</td>
- </tr>
- <tr v-if="instance.startTime">
- <th>鍚姩鏃堕棿</th>
- <td>{{ formatDate(instance.startTime) }}</td>
- </tr>
- <tr v-if="instance.lastActivityTime">
- <th>鏈�鍚庢椿鍔ㄦ椂闂�</th>
- <td>{{ formatDate(instance.lastActivityTime) }}</td>
- </tr>
- <tr v-if="instance.errorMessage">
- <th>閿欒淇℃伅</th>
- <td class="text-danger">{{ instance.errorMessage }}</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
+ <el-card class="mt-4" shadow="never">
+ <template #header>
+ <span class="card-header-title">鍩烘湰淇℃伅</span>
+ </template>
+ <el-descriptions :column="2" border>
+ <el-descriptions-item label="瀹炰緥ID">{{ instance.instanceId }}</el-descriptions-item>
+ <el-descriptions-item label="瀹炰緥鍚嶇О">{{ instance.name }}</el-descriptions-item>
+ <el-descriptions-item label="PLC鍨嬪彿">{{ getPlcTypeText(instance.plcType) }}</el-descriptions-item>
+ <el-descriptions-item label="鐩戝惉绔彛">{{ instance.port }}</el-descriptions-item>
+ <el-descriptions-item v-if="instance.startTime" label="鍚姩鏃堕棿">
+ {{ formatDate(instance.startTime) }}
+ </el-descriptions-item>
+ <el-descriptions-item v-if="instance.lastActivityTime" label="鏈�鍚庢椿鍔ㄦ椂闂�">
+ {{ formatDate(instance.lastActivityTime) }}
+ </el-descriptions-item>
+ <el-descriptions-item v-if="instance.errorMessage" label="閿欒淇℃伅" :span="2">
+ <el-text type="danger">{{ instance.errorMessage }}</el-text>
+ </el-descriptions-item>
+ </el-descriptions>
+ </el-card>
<!-- 鎿嶄綔鎸夐挳 -->
- <div class="card">
- <div class="card-body">
- <div class="d-flex gap-2">
- <button
- v-if="instance.status === 'Stopped' || instance.status === 'Error'"
- class="btn btn-success"
- @click="handleStart"
- >
- <i class="bi bi-play-fill me-1"></i>鍚姩
- </button>
- <button
- v-if="instance.status === 'Running'"
- class="btn btn-warning"
- @click="handleStop"
- >
- <i class="bi bi-stop-fill me-1"></i>鍋滄
- </button>
- <router-link :to="`/edit/${instance.instanceId}`" class="btn btn-primary">
- <i class="bi bi-pencil-fill me-1"></i>缂栬緫
- </router-link>
- <router-link to="/" class="btn btn-outline-secondary">
- <i class="bi bi-arrow-left me-1"></i>杩斿洖鍒楄〃
- </router-link>
- </div>
+ <el-card class="mt-4" shadow="never">
+ <div class="action-buttons">
+ <el-button
+ v-if="instance.status === 'Stopped' || instance.status === 'Error'"
+ type="success"
+ @click="handleStart"
+ >
+ <el-icon><VideoPlay /></el-icon>
+ 鍚姩
+ </el-button>
+ <el-button
+ v-if="instance.status === 'Running'"
+ type="warning"
+ @click="handleStop"
+ >
+ <el-icon><VideoPause /></el-icon>
+ 鍋滄
+ </el-button>
+ <el-button type="primary" @click="$router.push(`/edit/${instance.instanceId}`)">
+ <el-icon><Edit /></el-icon>
+ 缂栬緫
+ </el-button>
+ <el-button @click="$router.push('/')">
+ <el-icon><Back /></el-icon>
+ 杩斿洖鍒楄〃
+ </el-button>
</div>
- </div>
+ </el-card>
</div>
</div>
</template>
@@ -139,6 +120,16 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import {
+ InfoFilled,
+ Back,
+ Loading,
+ User,
+ VideoPlay,
+ VideoPause,
+ Edit
+} from '@element-plus/icons-vue'
import * as api from '../api'
import type { InstanceState, InstanceStatus } from '../types'
@@ -183,38 +174,50 @@
})
async function handleStart() {
- if (confirm(`纭畾瑕佸惎鍔ㄥ疄渚� "${id}" 鍚�?`)) {
- try {
- await api.startInstance(id)
- await loadInstance()
- } catch (err) {
+ try {
+ await ElMessageBox.confirm(`纭畾瑕佸惎鍔ㄥ疄渚� "${id}" 鍚�?`, '纭', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'info'
+ })
+ await api.startInstance(id)
+ await loadInstance()
+ ElMessage.success('鍚姩鍛戒护宸插彂閫�')
+ } catch (err) {
+ if (err !== 'cancel') {
console.error('鍚姩瀹炰緥澶辫触:', err)
- alert('鍚姩澶辫触锛岃鏌ョ湅鎺у埗鍙�')
+ ElMessage.error('鍚姩澶辫触锛岃鏌ョ湅鎺у埗鍙�')
}
}
}
async function handleStop() {
- if (confirm(`纭畾瑕佸仠姝㈠疄渚� "${id}" 鍚�?`)) {
- try {
- await api.stopInstance(id)
- await loadInstance()
- } catch (err) {
+ try {
+ await ElMessageBox.confirm(`纭畾瑕佸仠姝㈠疄渚� "${id}" 鍚�?`, '纭', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ })
+ await api.stopInstance(id)
+ await loadInstance()
+ ElMessage.success('鍋滄鍛戒护宸插彂閫�')
+ } catch (err) {
+ if (err !== 'cancel') {
console.error('鍋滄瀹炰緥澶辫触:', err)
- alert('鍋滄澶辫触锛岃鏌ョ湅鎺у埗鍙�')
+ ElMessage.error('鍋滄澶辫触锛岃鏌ョ湅鎺у埗鍙�')
}
}
}
-function getStatusClass(status: InstanceStatus): string {
- const map: Record<InstanceStatus, string> = {
- 'Stopped': 'text-secondary',
- 'Starting': 'text-info',
- 'Running': 'text-success',
- 'Stopping': 'text-warning',
- 'Error': 'text-danger'
+function getStatusTagType(status: InstanceStatus): 'success' | 'info' | 'warning' | 'danger' {
+ const map: Record<InstanceStatus, 'success' | 'info' | 'warning' | 'danger'> = {
+ 'Stopped': 'info',
+ 'Starting': 'info',
+ 'Running': 'success',
+ 'Stopping': 'warning',
+ 'Error': 'danger'
}
- return map[status] || ''
+ return map[status] || 'info'
}
function getStatusText(status: InstanceStatus): string {
@@ -254,13 +257,66 @@
</script>
<style scoped>
-.card-subtitle {
- font-size: 0.875rem;
- font-weight: 600;
+.page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 20px;
+ flex-wrap: wrap;
+ gap: 16px;
}
-table th {
- background-color: #f8f9fa;
+.header-left h2 {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin: 0 0 8px 0;
+}
+
+.text-muted {
+ color: #909399;
+ margin: 0;
+}
+
+.loading-container {
+ text-align: center;
+ padding: 60px 0;
+ color: #909399;
+}
+
+.loading-icon {
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.status-cards {
+ margin-bottom: 20px;
+}
+
+.status-card {
+ text-align: center;
+}
+
+.card-header-title {
font-weight: 600;
+ font-size: 16px;
+}
+
+.mt-4 {
+ margin-top: 16px;
+}
+
+.action-buttons {
+ display: flex;
+ gap: 12px;
+ flex-wrap: wrap;
}
</style>
--
Gitblit v1.9.3