|
@@ -0,0 +1,77 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="app-container">
|
|
|
|
|
+ <el-row :gutter="16" class="mb8">
|
|
|
|
|
+ <el-col :span="4"><el-card shadow="hover"><div class="stat-card"><div class="stat-value">{{ summary.totalTypes || 0 }}</div><div class="stat-label">节点类型总数</div></div></el-card></el-col>
|
|
|
|
|
+ <el-col :span="4"><el-card shadow="hover"><div class="stat-card"><div class="stat-value" style="color:#67C23A">{{ summary.fullCount || 0 }}</div><div class="stat-label">FULL 完整</div></div></el-card></el-col>
|
|
|
|
|
+ <el-col :span="4"><el-card shadow="hover"><div class="stat-card"><div class="stat-value" style="color:#E6A23C">{{ summary.partialCount || 0 }}</div><div class="stat-label">PARTIAL</div></div></el-card></el-col>
|
|
|
|
|
+ <el-col :span="4"><el-card shadow="hover"><div class="stat-card"><div class="stat-value">{{ summary.avgMaturityStars || '-' }}</div><div class="stat-label">平均成熟度</div></div></el-card></el-col>
|
|
|
|
|
+ <el-col :span="4"><el-card shadow="hover"><div class="stat-card"><div class="stat-value">{{ registeredCount }}</div><div class="stat-label">已注册Handler</div></div></el-card></el-col>
|
|
|
|
|
+ <el-col :span="4"><el-card shadow="hover"><div class="stat-card"><div class="stat-value" style="color:#F56C6C">{{ gapCount }}</div><div class="stat-label">未注册缺口</div></div></el-card></el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form :inline="true" class="mb8">
|
|
|
|
|
+ <el-form-item label="状态">
|
|
|
|
|
+ <el-select v-model="filterStatus" placeholder="全部" clearable size="small" @change="applyFilter">
|
|
|
|
|
+ <el-option label="FULL" value="FULL" /><el-option label="PARTIAL" value="PARTIAL" />
|
|
|
|
|
+ <el-option label="STUB" value="STUB" /><el-option label="NONE" value="NONE" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item><el-button icon="el-icon-refresh" size="mini" @click="load">刷新</el-button></el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table border v-loading="loading" :data="filteredList" size="small">
|
|
|
|
|
+ <el-table-column prop="code" label="编码" width="70" />
|
|
|
|
|
+ <el-table-column prop="codeName" label="标识" width="140" />
|
|
|
|
|
+ <el-table-column prop="name" label="名称" width="120" />
|
|
|
|
|
+ <el-table-column prop="maturityStars" label="成熟度" width="100">
|
|
|
|
|
+ <template slot-scope="s"><el-rate :value="s.row.maturityStars" disabled /></template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="status" label="状态" width="90">
|
|
|
|
|
+ <template slot-scope="s"><el-tag :type="statusType(s.row.status)" size="mini">{{ s.row.status }}</el-tag></template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="handlerRegistered" label="Handler" width="90">
|
|
|
|
|
+ <template slot-scope="s"><el-tag :type="s.row.handlerRegistered?'success':'danger'" size="mini">{{ s.row.handlerRegistered?'已注册':'缺失' }}</el-tag></template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column prop="handler" label="处理器" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column prop="gapNote" label="备注" show-overflow-tooltip />
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+<script>
|
|
|
|
|
+import { getNodeCapabilities } from '@/api/workflow/lobster'
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: 'LobsterNodeCapabilities',
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return { loading: false, list: [], summary: {}, registeredCount: 0, gapCount: 0, filterStatus: '' }
|
|
|
|
|
+ },
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ filteredList() {
|
|
|
|
|
+ if (!this.filterStatus) return this.list
|
|
|
|
|
+ return this.list.filter(r => r.status === this.filterStatus)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ created() { this.load() },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ load() {
|
|
|
|
|
+ this.loading = true
|
|
|
|
|
+ getNodeCapabilities().then(res => {
|
|
|
|
|
+ const d = res.data || {}
|
|
|
|
|
+ this.summary = d.summary || {}
|
|
|
|
|
+ this.list = d.capabilities || []
|
|
|
|
|
+ this.registeredCount = d.registeredHandlerCount || 0
|
|
|
|
|
+ this.gapCount = (d.gaps || []).length
|
|
|
|
|
+ this.loading = false
|
|
|
|
|
+ }).catch(() => { this.loading = false })
|
|
|
|
|
+ },
|
|
|
|
|
+ applyFilter() {},
|
|
|
|
|
+ statusType(s) {
|
|
|
|
|
+ return s === 'FULL' ? 'success' : s === 'PARTIAL' ? 'warning' : 'info'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.stat-card { text-align:center; padding:10px 0 }
|
|
|
|
|
+.stat-value { font-size:28px; font-weight:bold; color:#409EFF }
|
|
|
|
|
+.stat-label { font-size:12px; color:#909399; margin-top:4px }
|
|
|
|
|
+</style>
|