Files
pickling-mes/frontend/src/views/Message.vue
wangyu fb28599365 style: 顶部横向导航 + 登录页工业重设计 + 清除 placeholder 文本
- Layout: 恢复顶部横向导航,图标换为 SVG 几何图形
- Login: 西门子风格重设计,去掉渐变/圆角/placeholder
- 全局清除所有输入框 placeholder 说明文字
- 修复 Equipment.vue 重复 style 属性
2026-05-27 17:04:48 +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: #0a0f18; color: #d4d4d4;
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>