This commit is contained in:
Leo
2026-01-05 22:02:21 +08:00
parent 5367eb7834
commit af0000107f
5 changed files with 138 additions and 96 deletions

View File

@@ -7,3 +7,11 @@ export function getServer() {
method: 'get'
})
}
// 获取服务健康度检测
export function getHealth() {
return request({
url: '/monitor/server/health',
method: 'get'
})
}

View File

@@ -1,5 +1,5 @@
<template>
<div class="mobile-bottom-nav" v-if="isMobile && show">
<div class="mobile-bottom-nav" :class="{ 'scrollable': navItems.length > 5 }" v-if="isMobile && show">
<div
v-for="item in navItems"
:key="item.path"
@@ -106,7 +106,7 @@ export default {
const flatRoutes = flattenRoutes(routes)
// 过滤并选择前5个主要路由
// 过滤并获取所有主要路由(不限制数量)
const mainRoutes = flatRoutes
.filter(route => {
// 过滤掉一些特殊路由
@@ -117,7 +117,9 @@ export default {
!excludePaths.some(exclude => path.includes(exclude)) &&
!path.startsWith('/user/')
})
.slice(0, 5)
// 不限制数量,显示所有可用路由
// 但限制最多10个避免过多导致显示问题
.slice(0, 10)
// 缓存结果
if (mainRoutes.length > 0) {
@@ -215,17 +217,28 @@ export default {
z-index: 1000;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
padding-bottom: env(safe-area-inset-bottom);
overflow-x: auto;
-webkit-overflow-scrolling: touch;
// 如果导航项超过5个允许横向滚动
&.scrollable {
justify-content: flex-start;
padding: 0 8px;
}
.nav-item {
flex: 1;
min-width: 60px;
max-width: 80px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 6px 0;
padding: 6px 4px;
cursor: pointer;
transition: all 0.3s;
-webkit-tap-highlight-color: transparent;
flex-shrink: 0;
.nav-icon {
width: 28px;
@@ -252,6 +265,11 @@ export default {
font-size: 11px;
color: #909399;
transition: all 0.3s;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
text-align: center;
}
&.active {

View File

@@ -47,85 +47,8 @@ export default {
}),
...mapGetters(['sidebarRouters']),
mobileNavItems() {
// 根据业务需求配置底部导航项
// 匹配关键词来自动查找路由,如果找不到则使用指定路径
const navConfig = [
{ keywords: ['慢单', 'sloworder'], label: '下好的慢单', icon: 'el-icon-list', defaultPath: '/sloworder/index' },
{ keywords: ['指令', 'instruction', 'jd-instruction'], label: '指令执行', icon: 'el-icon-edit-outline', defaultPath: '/jd-instruction/index' },
{ keywords: ['型号', 'productJdConfig', 'product'], label: '型号配置', icon: 'el-icon-setting', defaultPath: '/jarvis/productJdConfig' },
{ keywords: ['商品', 'favorite', 'erpProduct'], label: '商品列表', icon: 'el-icon-goods', defaultPath: '/favorite/index' }
]
const routes = this.sidebarRouters || []
// 扁平化路由
const flattenRoutes = (routes, parentPath = '') => {
let result = []
if (!routes || !Array.isArray(routes)) return result
routes.forEach(route => {
if (route.hidden) return
let fullPath = route.path || ''
if (parentPath) {
if (fullPath.startsWith('/')) {
fullPath = fullPath
} else {
const basePath = parentPath.endsWith('/') ? parentPath.slice(0, -1) : parentPath
fullPath = `${basePath}/${fullPath}`.replace(/\/+/g, '/')
}
}
if (!fullPath.startsWith('/')) {
fullPath = '/' + fullPath
}
if (route.children && route.children.length > 0) {
result = result.concat(flattenRoutes(route.children, fullPath))
} else {
if (route.meta && route.meta.title && fullPath) {
result.push({
path: fullPath,
label: route.meta.title,
route: route
})
}
}
})
return result
}
const flatRoutes = flattenRoutes(routes)
// 为每个配置项查找匹配的路由
const navItems = navConfig.map(config => {
// 先尝试从路由中匹配
const matchedRoute = flatRoutes.find(route => {
const path = (route.path || '').toLowerCase()
const title = (route.label || '').toLowerCase()
return config.keywords.some(keyword =>
path.includes(keyword.toLowerCase()) || title.includes(keyword.toLowerCase())
)
})
if (matchedRoute) {
return {
path: matchedRoute.path,
label: config.label,
icon: config.icon
}
}
// 如果没找到,使用默认路径
return {
path: config.defaultPath,
label: config.label,
icon: config.icon
}
})
// 过滤掉无效的路由
return navItems.filter(item => item.path)
// 如果返回空数组,组件会使用默认逻辑从路由中自动获取所有可用路由
return []
},
classObj() {
return {

View File

@@ -171,23 +171,109 @@
</div>
</el-card>
</el-col>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header">
<span><i class="el-icon-truck"></i> 物流服务健康度</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<tbody>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">服务状态</div></td>
<td class="el-table__cell is-leaf">
<div class="cell">
<el-tag :type="health.logistics && health.logistics.healthy ? 'success' : 'danger'">
{{ health.logistics && health.logistics.status ? health.logistics.status : '未知' }}
</el-tag>
</div>
</td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">服务地址</div></td>
<td class="el-table__cell is-leaf">
<div class="cell" style="word-break: break-all;">
{{ health.logistics && health.logistics.serviceUrl ? health.logistics.serviceUrl : '-' }}
</div>
</td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">状态信息</div></td>
<td class="el-table__cell is-leaf">
<div class="cell" :class="{'text-danger': health.logistics && !health.logistics.healthy}">
{{ health.logistics && health.logistics.message ? health.logistics.message : '-' }}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
<el-col :span="12" class="card-box">
<el-card>
<div slot="header">
<span><i class="el-icon-message"></i> 微信推送服务健康度</span>
</div>
<div class="el-table el-table--enable-row-hover el-table--medium">
<table cellspacing="0" style="width: 100%;">
<tbody>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">服务状态</div></td>
<td class="el-table__cell is-leaf">
<div class="cell">
<el-tag :type="health.wxSend && health.wxSend.healthy ? 'success' : 'danger'">
{{ health.wxSend && health.wxSend.status ? health.wxSend.status : '未知' }}
</el-tag>
</div>
</td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">服务地址</div></td>
<td class="el-table__cell is-leaf">
<div class="cell" style="word-break: break-all;">
{{ health.wxSend && health.wxSend.serviceUrl ? health.wxSend.serviceUrl : '-' }}
</div>
</td>
</tr>
<tr>
<td class="el-table__cell is-leaf"><div class="cell">状态信息</div></td>
<td class="el-table__cell is-leaf">
<div class="cell" :class="{'text-danger': health.wxSend && !health.wxSend.healthy}">
{{ health.wxSend && health.wxSend.message ? health.wxSend.message : '-' }}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { getServer } from "@/api/monitor/server"
import { getServer, getHealth } from "@/api/monitor/server"
export default {
name: "Server",
data() {
return {
// 服务器信息
server: []
server: [],
// 健康度检测信息
health: {
logistics: null,
wxSend: null
}
}
},
created() {
this.getList()
this.getHealthInfo()
this.openLoading()
},
methods: {
@@ -198,6 +284,16 @@ export default {
this.$modal.closeLoading()
})
},
/** 查询健康度检测信息 */
getHealthInfo() {
getHealth().then(response => {
if (response.data) {
this.health = response.data
}
}).catch(error => {
console.error("获取健康度检测信息失败", error)
})
},
// 打开加载层
openLoading() {
this.$modal.loading("正在加载服务监控数据,请稍候!")

View File

@@ -9,20 +9,20 @@
<el-form-item label="输入指令">
<el-input v-model="form.command" type="textarea" :rows="8" placeholder="例如:京今日统计 / 京昨日订单 / 慢搜关键词 / 录单20250101-20250107" />
</el-form-item>
<el-form-item class="button-group button-group-primary">
<div class="button-group button-group-primary">
<el-button type="success" size="medium" @click="run" :loading="loading">执行</el-button>
<el-button type="danger" size="medium" @click="clearAll">清空</el-button>
<el-button size="warning" @click="fillMan">慢单</el-button>
<el-button size="success" @click="fillSheng"></el-button>
</el-form-item>
<el-form-item class="button-group button-group-secondary">
</div>
<div class="button-group button-group-secondary">
<el-button size="primary" @click="fillTF">腾峰</el-button>
<el-button type="primary" size="medium" @click="fillFan"></el-button>
<el-button type="primary" size="medium" @click="fillWen"></el-button>
<el-button type="primary" size="medium" @click="fillHong">鸿</el-button>
<el-button type="primary" size="medium" @click="fillPDD">拼多多</el-button>
<el-button type="primary" size="medium" @click="fillPDDWen">拼多多-纹</el-button>
</el-form-item>
</div>
</el-form>
<el-divider>响应</el-divider>
@@ -533,6 +533,7 @@ export default {
display: flex;
flex-wrap: wrap;
gap: 10px;
width: 100%;
}
.button-group .el-button {
@@ -597,14 +598,10 @@ export default {
font-size: 12px;
}
/* 确保el-form-item不会影响布局 */
.button-group.el-form-item {
margin-bottom: 12px !important;
}
.button-group.el-form-item ::v-deep .el-form-item__content {
/* 确保按钮组独立于form-item */
.button-group {
margin-left: 0 !important;
width: 100% !important;
margin-right: 0 !important;
}
}