fastbee/yack-web/src/views/platform/push-log/index.vue

189 lines
8.4 KiB
Vue

<template>
<div class="platform-push-log">
<!-- 搜索 -->
<el-card v-show="showSearch" style="margin-bottom:10px">
<el-form :model="queryParams" ref="queryForm" size="mini" :inline="true" style="margin-bottom:-18px">
<el-form-item label="平台" prop="platformId">
<el-select v-model="queryParams.platformId" placeholder="全部平台" clearable style="width:140px">
<el-option v-for="p in platformList" :key="p.id" :label="p.name" :value="p.id" />
</el-select>
</el-form-item>
<el-form-item label="设备序列号" prop="serialNumber">
<el-input v-model="queryParams.serialNumber" placeholder="序列号" clearable style="width:140px" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="全部" clearable style="width:100px">
<el-option label="进行中" :value="0" />
<el-option label="成功" :value="1" />
<el-option label="失败" :value="2" />
</el-select>
</el-form-item>
<el-form-item style="float:right">
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card>
<el-row :gutter="10" style="margin-bottom:12px">
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="selectedIds.length === 0" @click="handleBatchDelete" v-hasPermi="['platform:pushLog:remove']">删除</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
</el-row>
<el-tabs v-model="activeTab" @tab-click="onTabChange">
<el-tab-pane label="数据推送" name="1" />
<el-tab-pane label="操作日志" name="2" />
</el-tabs>
<el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="45" align="center" />
<el-table-column label="时间" prop="createTime" width="160" />
<el-table-column label="平台" width="120">
<template slot-scope="scope">{{ platformName(scope.row.platformId) }}</template>
</el-table-column>
<el-table-column label="设备序列号" prop="serialNumber" width="140" />
<el-table-column label="接口" prop="interfaceCode" width="180" show-overflow-tooltip />
<el-table-column label="状态" width="80" align="center">
<template slot-scope="scope">
<el-tag size="small" type="info" v-if="scope.row.status===0">进行中</el-tag>
<el-tag size="small" type="success" v-if="scope.row.status===1">成功</el-tag>
<el-tag size="small" type="danger" v-if="scope.row.status===2">失败</el-tag>
</template>
</el-table-column>
<el-table-column label="耗时(ms)" prop="costMs" width="90" align="right" />
<el-table-column label="错误信息" prop="errorMsg" min-width="160" show-overflow-tooltip />
<el-table-column label="操作" fixed="right" width="140" align="center">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click="handleDetail(scope.row)">详情</el-button>
<el-button
v-if="scope.row.status===2 && activeTab==='1'"
size="mini" type="text" icon="el-icon-refresh"
:loading="retryingId===scope.row.id"
@click="handleRetry(scope.row)">重推</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 详情弹窗 -->
<el-dialog title="日志详情" :visible.sync="detailOpen" width="800px" append-to-body>
<el-descriptions :column="2" border size="small" style="margin-bottom:16px">
<el-descriptions-item label="平台">{{ platformName(detail.platformId) }}</el-descriptions-item>
<el-descriptions-item label="接口">{{ detail.interfaceCode }}</el-descriptions-item>
<el-descriptions-item label="设备序列号">{{ detail.serialNumber }}</el-descriptions-item>
<el-descriptions-item label="状态">
<el-tag size="small" type="info" v-if="detail.status===0">进行中</el-tag>
<el-tag size="small" type="success" v-if="detail.status===1">成功</el-tag>
<el-tag size="small" type="danger" v-if="detail.status===2">失败</el-tag>
</el-descriptions-item>
<el-descriptions-item label="耗时">{{ detail.costMs }} ms</el-descriptions-item>
<el-descriptions-item label="响应码">{{ detail.responseCode }}</el-descriptions-item>
<el-descriptions-item label="时间" :span="2">{{ detail.createTime }}</el-descriptions-item>
<el-descriptions-item label="错误信息" :span="2" v-if="detail.errorMsg">
<span style="color:#f56c6c">{{ detail.errorMsg }}</span>
</el-descriptions-item>
</el-descriptions>
<el-tabs v-model="detailTab">
<el-tab-pane label="请求URL" name="url">
<pre style="background:#f5f7fa;padding:12px;border-radius:4px;font-size:12px;word-break:break-all;white-space:pre-wrap">{{ detail.requestUrl }}</pre>
</el-tab-pane>
<el-tab-pane label="请求体" name="req">
<pre style="background:#f5f7fa;padding:12px;border-radius:4px;font-size:12px;max-height:300px;overflow:auto">{{ formatJson(detail.requestBody) }}</pre>
</el-tab-pane>
<el-tab-pane label="响应体" name="resp">
<pre style="background:#f5f7fa;padding:12px;border-radius:4px;font-size:12px;max-height:300px;overflow:auto">{{ formatJson(detail.responseBody) }}</pre>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template>
<script>
import { listPlatformPushLog, getPlatformPushLog, retryPlatformPushLog, delPlatformPushLog } from '@/api/platform/pushLog'
import { listPlatformInstance } from '@/api/platform/instance'
export default {
name: 'PlatformPushLog',
data() {
return {
loading: false,
showSearch: true,
total: 0,
list: [],
platformList: [],
selectedIds: [],
activeTab: '1',
retryingId: null,
detailOpen: false,
detailTab: 'req',
detail: {},
queryParams: { pageNum: 1, pageSize: 20, platformId: null, serialNumber: '', status: null, logType: 1 }
}
},
created() {
listPlatformInstance({ pageNum: 1, pageSize: 100 }).then(res => { this.platformList = res.rows })
this.getList()
},
methods: {
getList() {
this.loading = true
listPlatformPushLog(this.queryParams).then(res => {
this.list = res.rows; this.total = res.total; this.loading = false
})
},
handleSelectionChange(selection) {
this.selectedIds = (selection || []).map(item => item.id).filter(Boolean)
},
platformName(id) {
const p = this.platformList.find(x => x.id === id)
return p ? p.name : id
},
onTabChange(tab) {
this.queryParams.logType = parseInt(tab.name)
this.queryParams.pageNum = 1
this.getList()
},
handleQuery() { this.queryParams.pageNum = 1; this.getList() },
resetQuery() { this.resetForm('queryForm'); this.handleQuery() },
handleDetail(row) {
getPlatformPushLog(row.id).then(res => {
this.detail = res.data
this.detailTab = 'req'
this.detailOpen = true
})
},
handleRetry(row) {
this.retryingId = row.id
retryPlatformPushLog(row.id).then(() => {
this.$message.success('重推成功')
this.getList()
}).catch(err => {
this.$message.error(err.message || '重推失败')
}).finally(() => {
this.retryingId = null
})
},
handleBatchDelete() {
if (this.selectedIds.length === 0) return
this.$confirm(`确认删除选中的 ${this.selectedIds.length} 条日志?`).then(() => {
delPlatformPushLog(this.selectedIds.join(',')).then(() => {
this.$message.success('删除成功')
this.selectedIds = []
this.getList()
})
})
},
formatJson(str) {
if (!str) return ''
try { return JSON.stringify(JSON.parse(str), null, 2) } catch { return str }
}
}
}
</script>