|
|
<template> <div class="mod-config"> <!-- 查询表单 - rqrq --> <el-form :inline="true" label-position="top" style="margin-top: 1px; margin-left: 0px;"> <el-form-item label="接口名称"> <el-input v-model="queryData.interfaceName" style="width: 120px" placeholder="接口名称" clearable></el-input> </el-form-item>
<el-form-item label="方法名称"> <el-input v-model="queryData.methodName" style="width: 120px" placeholder="方法名称" clearable></el-input> </el-form-item>
<el-form-item label="业务主键"> <el-input v-model="queryData.businessKey" style="width: 120px" placeholder="业务主键" clearable></el-input> </el-form-item>
<el-form-item label="调用状态"> <el-select v-model="queryData.status" placeholder="请选择" style="width: 120px" clearable> <el-option label="全部" value=""></el-option> <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item>
<el-form-item label="创建时间从"> <el-date-picker v-model="queryData.startDate" type="date" style="width: 120px" placeholder="开始日期" value-format="yyyy-MM-dd" clearable> </el-date-picker> </el-form-item>
<el-form-item label="创建时间至"> <el-date-picker v-model="queryData.endDate" type="date" style="width: 120px" placeholder="结束日期" value-format="yyyy-MM-dd" clearable> </el-date-picker> </el-form-item>
<el-form-item label=" "> <el-button type="primary" @click="getDataList()">{{ $t('warehouse.common.search') }}</el-button> <el-button @click="resetQuery()">{{ $t('warehouse.common.reset') }}</el-button> <!-- 导出按钮 - rqrq --> <download-excel :fields="fields()" :data="exportData" type="xls" :name="exportName" :header="exportHeader" :footer="exportFooter" :fetch="createExportData" :before-generate="startDownload" :before-finish="finishDownload" :worksheet="$t('warehouse.common.exportWorksheet')" class="el-button el-button--primary el-button--medium"> {{ $t('warehouse.common.download') }} </download-excel> </el-form-item> </el-form>
<!-- 数据表格 - rqrq --> <el-table :data="dataList" :height="height" border highlight-current-row v-loading="dataListLoading" style="width: 100%;"> <el-table-column v-for="(item,index) in columnList" :key="index" :sortable="item.columnSortable" :prop="item.columnProp" :header-align="item.headerAlign" :show-overflow-tooltip="item.showOverflowTooltip" :align="item.align" :fixed="item.fixed==''?false:item.fixed" :min-width="item.columnWidth" :label="item.columnLabel"> <template slot-scope="scope"> <span v-if="item.columnProp === 'status'"> <el-tag :type="getStatusType(scope.row.status)" size="small"> {{ getStatusLabel(scope.row.status) }} </el-tag> </span> <span v-else-if="item.columnProp === 'executionTime'"> <span :style="{color: scope.row.executionTime > 3000 ? '#F56C6C' : '#67C23A'}"> {{ scope.row.executionTime }} ms </span> </span> <span v-else>{{ scope.row[item.columnProp] }}</span> </template> </el-table-column>
<!-- 操作列 - rqrq --> <el-table-column header-align="center" align="center" fixed="right" width="150" label="操作"> <template slot-scope="scope"> <a type="text" @click="viewDetail(scope.row)">查看详情</a> </template> </el-table-column> </el-table>
<!-- 分页 - rqrq --> <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" :current-page="pageIndex" :page-sizes="[20, 50, 100, 1000]" :page-size="pageSize" :total="totalPage" layout="total, sizes, prev, pager, next, jumper"> </el-pagination>
<!-- 详情弹窗 - rqrq --> <el-dialog title="接口调用详情" :visible.sync="detailVisible" :close-on-click-modal="false" v-drag width="80%"> <el-row :gutter="20"> <el-col :span="12"> <el-card class="box-card fixed-height-card"> <div slot="header" class="clearfix"> <span>基本信息</span> </div> <el-form label-width="120px" class="detail-form"> <el-form-item label="接口名称:"> <span>{{ detailData.interfaceName }}</span> </el-form-item> <el-form-item label="方法名称:"> <span>{{ detailData.methodName }}</span> </el-form-item> <el-form-item label="工厂编码:"> <span>{{ detailData.site }}</span> </el-form-item> <el-form-item label="业务主键:"> <span>{{ detailData.businessKey }}</span> </el-form-item> <el-form-item label="调用状态:"> <el-tag :type="getStatusType(detailData.status)" size="small"> {{ getStatusLabel(detailData.status) }} </el-tag> </el-form-item> <el-form-item label="执行时间:"> <span :style="{color: detailData.executionTime > 3000 ? '#F56C6C' : '#67C23A'}"> {{ detailData.executionTime }} ms </span> </el-form-item> <el-form-item label="创建时间:"> <span>{{ detailData.createdTime }}</span> </el-form-item> <el-form-item label="创建人:"> <span>{{ detailData.createdBy }}</span> </el-form-item> </el-form> </el-card> </el-col>
<el-col :span="12"> <el-card class="box-card fixed-height-card"> <div slot="header" class="clearfix"> <span>返回信息</span> </div> <div class="detail-content-area"> <el-input type="textarea" :rows="13" :value="detailData.errorMessage || '无错误'" :readonly="true"> </el-input> </div> </el-card> </el-col> </el-row>
<el-row :gutter="20" style="margin-top: 20px;"> <el-col :span="12"> <el-card class="box-card fixed-height-card"> <div slot="header" class="clearfix"> <span>请求数据</span> <el-button style="float: right; padding: 3px 0" type="text" @click="copyToClipboard(detailData.requestData)">复制</el-button> </div> <div class="detail-content-area"> <pre class="json-pre">{{ formatJson(detailData.requestData) }}</pre> </div> </el-card> </el-col>
<el-col :span="12"> <el-card class="box-card fixed-height-card"> <div slot="header" class="clearfix"> <span>响应数据</span> <el-button style="float: right; padding: 3px 0" type="text" @click="copyToClipboard(detailData.responseData)">复制</el-button> </div> <div class="detail-content-area"> <pre class="json-pre">{{ formatJson(detailData.responseData) }}</pre> </div> </el-card> </el-col> </el-row>
<div slot="footer" class="dialog-footer"> <el-button @click="detailVisible = false">{{ $t('warehouse.common.close') }}</el-button> </div> </el-dialog> </div></template>
<script>import { haiAnGetInterfaceCallLogList, haiAnGetStatusOptions} from '@/api/haianWarehouse/interfaceCallLog.js'
export default { name: 'interfaceCallLog54', data() { // 默认携带登录工厂编码,保证日志查询上下文与海安工厂一致 - rqrq
const defaultSite = this.$store.state.user.site return { // 查询条件 - rqrq
queryData: { site: defaultSite, interfaceName: '', methodName: '', businessKey: '', status: '', startDate: '', endDate: '', page: 1, limit: 20 }, // 表格高度 - rqrq
height: 450, // 状态选项 - rqrq
statusOptions: [], // 表格列配置 - rqrq
columnList: [ { columnProp: 'interfaceName', headerAlign: 'center', align: 'center', columnLabel: '接口名称', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'methodName', headerAlign: 'center', align: 'center', columnLabel: '方法名称', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'businessKey', headerAlign: 'center', align: 'center', columnLabel: '业务主键', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'status', headerAlign: 'center', align: 'center', columnLabel: '调用状态', columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'executionTime', headerAlign: 'center', align: 'center', columnLabel: '执行时间', columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'site', headerAlign: 'center', align: 'center', columnLabel: '工厂编码', columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'createdTime', headerAlign: 'center', align: 'center', columnLabel: '创建时间', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'createdBy', headerAlign: 'center', align: 'center', columnLabel: '创建人', columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: '' }, { columnProp: 'remark', headerAlign: 'center', align: 'left', columnLabel: '备注', columnWidth: 200, columnSortable: false, showOverflowTooltip: true, fixed: '' } ], dataList: [], pageIndex: 1, pageSize: 20, totalPage: 0, dataListLoading: false, detailVisible: false, detailData: {}, // 导出相关 - rqrq
exportData: [], exportName: '海安接口调用日志' + this.dayjs().format('YYYYMMDDHHmmss'), exportHeader: ['海安接口调用日志'], exportFooter: [] } }, mounted() { this.$nextTick(() => { this.height = window.innerHeight - 220 }) }, activated() { this.getDataList() this.getStatusOptions() }, methods: { // 查询日志列表 - rqrq
getDataList() { this.dataListLoading = true this.queryData.page = this.pageIndex this.queryData.limit = this.pageSize
haiAnGetInterfaceCallLogList(this.queryData).then(({ data }) => { this.dataListLoading = false if (data && data.code === 0) { this.dataList = data.page.list || [] this.totalPage = data.page.totalCount || 0 } else { this.dataList = [] this.totalPage = 0 this.$alert(data.msg || this.$t('warehouse.message.queryFailed'), this.$t('warehouse.common.error'), { confirmButtonText: this.$t('warehouse.common.confirm') }) } }).catch(() => { this.dataListLoading = false this.$alert(this.$t('warehouse.message.queryFailed'), this.$t('warehouse.common.error'), { confirmButtonText: this.$t('warehouse.common.confirm') }) }) },
// 查询状态下拉选项 - rqrq
getStatusOptions() { haiAnGetStatusOptions().then(({ data }) => { if (data && data.code === 0) { this.statusOptions = data.options || [] } }) },
// 重置查询条件 - rqrq
resetQuery() { this.queryData = { // 重置时保留site,避免空site触发后端必填校验失败 - rqrq
site: this.$store.state.user.site, interfaceName: '', methodName: '', businessKey: '', status: '', startDate: '', endDate: '', page: 1, limit: 20 } this.pageIndex = 1 this.getDataList() },
sizeChangeHandle(val) { this.pageSize = val this.pageIndex = 1 this.getDataList() }, currentChangeHandle(val) { this.pageIndex = val this.getDataList() },
// 状态标签色 - rqrq
getStatusType(status) { const statusMap = { PROCESSING: 'warning', SUCCESS: 'success', ERROR: 'danger', TIMEOUT: 'info' } return statusMap[status] || 'info' }, // 状态文案 - rqrq
getStatusLabel(status) { const statusMap = { PROCESSING: '处理中', SUCCESS: '成功', ERROR: '失败', TIMEOUT: '超时' } return statusMap[status] || '未知' },
// 查看详情 - rqrq
viewDetail(row) { this.detailData = row this.detailVisible = true },
// 格式化JSON展示 - rqrq
formatJson(jsonStr) { if (!jsonStr) { return '无数据' } try { return JSON.stringify(JSON.parse(jsonStr), null, 2) } catch (e) { return jsonStr } },
// 复制文本 - rqrq
copyToClipboard(text) { if (!text) { this.$message.warning('无内容可复制') return } const textarea = document.createElement('textarea') textarea.value = text document.body.appendChild(textarea) textarea.select() try { document.execCommand('copy') this.$message.success('复制成功') } catch (e) { this.$alert('复制失败', this.$t('warehouse.common.error'), { confirmButtonText: this.$t('warehouse.common.confirm') }) } document.body.removeChild(textarea) },
// 导出相关方法 - rqrq
async createExportData() { const queryParams = { ...this.queryData, page: 1, limit: 999999 } const { data } = await haiAnGetInterfaceCallLogList(queryParams) if (data && data.code === 0) { return (data.page.list || []).map(item => ({ ...item, status: this.getStatusLabel(item.status) })) } return [] }, startDownload() {}, finishDownload() {}, fields() { let json = '{' this.columnList.forEach((item, index) => { if (index === this.columnList.length - 1) { json += '"' + item.columnLabel + '":"' + item.columnProp + '"' } else { json += '"' + item.columnLabel + '":"' + item.columnProp + '",' } }) json += '}' return eval('(' + json + ')') } }}</script>
<style scoped>.mod-config { padding: 10px;}
.box-card { margin-bottom: 20px;}
.fixed-height-card { height: 380px;}
.detail-form { height: 320px; overflow-y: auto;}
.detail-content-area { height: 320px; overflow-y: auto;}
.json-pre { margin: 0; white-space: pre-wrap; word-wrap: break-word; font-size: 12px; line-height: 1.5;}
.clearfix:before,.clearfix:after { display: table; content: '';}
.clearfix:after { clear: both;}</style>
|