Files
pickling-mes/frontend/src/views/Message.vue
wangyu 8583f605bd style(frontend): 全局样式改为 klp-ui 浅色红主题
- variables.scss 整盘重配色:浅灰背景/白卡片、#C03639 红主色、element 标准状态色与字体栈
- global.scss element-ui 覆写由深色改为浅色+红主色,卡片加轻投影
- Material/Message 视图内硬编码深色数据面板改为浅色

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 10:41:10 +08:00

168 lines
7.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div class="card">
<div class="card-body" style="padding:10px 14px;">
<div class="flex-row" style="flex-wrap:wrap;gap:12px;">
<div class="flex-row">
<span class="kv-label">报文类型</span>
<input v-model="query.msg_type" class="kv-input" style="width:90px;" />
</div>
<div class="flex-row">
<span class="kv-label">方向</span>
<select v-model="query.direction" class="kv-input" style="width:90px;">
<option value="">全部</option>
<option value="recv">接收</option>
<option value="send">发送</option>
</select>
</div>
<div class="flex-row">
<span class="kv-label">状态</span>
<select v-model="query.status" class="kv-input" style="width:90px;">
<option value="">全部</option>
<option value="success">成功</option>
<option value="error">失败</option>
</select>
</div>
<div class="flex-row">
<button class="btn btn-primary" @click="fetchData">查询</button>
<button class="btn btn-outline" @click="fetchData"> 刷新</button>
</div>
<div style="margin-left:auto;" class="flex-row">
<span class="kv-label">
成功 <span class="kv-value" style="color:var(--accent-green)">{{ successCount }}</span>
&nbsp; 失败 <span class="kv-value" style="color:var(--accent-red)">{{ errorCount }}</span>
</span>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
报文监控日志
<span class="ch-badge" :style="{ color: connected ? 'var(--accent-green)' : 'var(--accent-red)' }">
{{ connected ? '● UDP在线' : '○ 未连接' }}
</span>
</div>
<div class="table-scroll" v-loading="loading">
<table class="data-table">
<thead>
<tr>
<th>报文ID</th><th>类型</th><th>方向</th><th>来源</th>
<th>状态</th><th>耗时(ms)</th><th>错误信息</th><th>接收时间</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tableData" :key="row.id">
<td class="td-num">{{ row.msg_id }}</td>
<td><span class="badge badge-blue">{{ row.msg_type }}</span></td>
<td>
<span :class="['badge', row.direction==='recv' ? 'badge-green' : 'badge-blue']">
{{ row.direction === 'recv' ? '↓ 接收' : '↑ 发送' }}
</span>
</td>
<td class="td-muted">{{ row.source }}</td>
<td>
<span :class="['badge', row.status==='success' ? 'badge-green' : 'badge-red']">
{{ row.status === 'success' ? '成功' : '失败' }}
</span>
</td>
<td :class="row.process_time > 100 ? 'td-warn' : 'td-num'">{{ row.process_time || '—' }}</td>
<td class="td-err">{{ row.error_msg || '—' }}</td>
<td class="td-muted">{{ fmtTime(row.received_at) }}</td>
<td><span class="action-link" @click="viewDetail(row)">详情</span></td>
</tr>
<tr v-if="!tableData.length && !loading">
<td colspan="9" class="td-muted" style="text-align:center;padding:24px;">暂无报文记录</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 详情 Modal -->
<div v-if="detailVisible" class="modal-mask" @click.self="detailVisible=false">
<div class="modal-box" style="width:760px;">
<div class="modal-header">
报文详情 <span style="color:var(--sms-highlight)">{{ currentLog && currentLog.msg_type }}</span>
<span class="modal-close" @click="detailVisible=false"></span>
</div>
<div class="modal-body" v-if="currentLog">
<div class="kv-grid" style="margin-bottom:14px;">
<span class="kv-label">报文类型</span><span class="kv-value">{{ currentLog.msg_type }}</span>
<span class="kv-label">接收时间</span><span class="kv-value">{{ fmtTime(currentLog.received_at) }}</span>
<span class="kv-label">状态</span>
<span><span :class="['badge', currentLog.status==='success' ? 'badge-green' : 'badge-red']">{{ currentLog.status }}</span></span>
</div>
<div class="sec-title">原始报文HEX</div>
<pre class="raw-box">{{ currentLog.raw_data || '—' }}</pre>
<div class="sec-title" style="margin-top:12px;">解析结果JSON</div>
<pre class="raw-box">{{ formatJson(currentLog.parsed_data) }}</pre>
</div>
<div class="modal-footer">
<button class="btn btn-outline" @click="detailVisible=false">关闭</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { getMessageLogs, getMessageLog } from '@/api'
export default {
name: 'Message',
data() {
return {
loading: false,
tableData: [], total: 0,
query: { page: 1, page_size: 50, msg_type: '', direction: '', status: '' },
connected: true,
detailVisible: false, currentLog: null,
}
},
computed: {
successCount() { return this.tableData.filter(r => r.status === 'success').length },
errorCount() { return this.tableData.filter(r => r.status === 'error').length },
},
created() { this.fetchData() },
methods: {
async fetchData() {
this.loading = true
try {
const res = await getMessageLogs(this.query)
this.tableData = res.data.items
this.total = res.data.total
} finally { this.loading = false }
},
fmtTime(t) { return t ? t.replace('T',' ').slice(0,19) : '—' },
async viewDetail(row) {
const res = await getMessageLog(row.id)
this.currentLog = res.data
this.detailVisible = true
},
formatJson(s) {
if (!s) return '—'
try { return JSON.stringify(JSON.parse(s), null, 2) } catch { return s }
}
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/styles/variables';
.action-link { color: $sms-highlight; cursor: pointer; font-size: 12px; &:hover { text-decoration: underline; } }
.raw-box {
background: $bg-panel; color: $text-primary;
padding: 12px; border-radius: 4px; border: 1px solid $border;
font-size: 11px; font-family: $font-mono;
max-height: 180px; overflow-y: auto;
white-space: pre-wrap; word-break: break-all;
}
.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: flex; align-items: center; justify-content: center; z-index: 9999; }
.modal-box { background: $bg-card; border: 1px solid $border; border-radius: 6px; max-width: 95vw; max-height: 90vh; display: flex; flex-direction: column; }
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; background: $bg-panel; border-bottom: 1px solid $border; font-size: 13px; font-weight: 600; color: $sms-highlight; .modal-close { cursor: pointer; color: $text-muted; &:hover { color: $text-primary; } } }
.modal-body { padding: 16px; overflow-y: auto; }
.modal-footer { padding: 10px 16px; background: $bg-panel; border-top: 1px solid $border; display: flex; justify-content: flex-end; gap: 10px; }
</style>