|
|
@@ -1,19 +1,227 @@
|
|
|
<template>
|
|
|
<div class="app-container">
|
|
|
+ <!-- ===== 搜索栏 ===== -->
|
|
|
+ <el-card shadow="never" class="mb16 filter-card">
|
|
|
+ <el-form :model="queryParams" ref="queryForm" :inline="true" size="small">
|
|
|
+ <el-form-item label="操作人员" prop="operName">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.operName"
|
|
|
+ placeholder="请输入操作人员"
|
|
|
+ clearable
|
|
|
+ style="width:160px"
|
|
|
+ @keyup.enter.native="handleQuery"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="操作状态" prop="status">
|
|
|
+ <el-select v-model="queryParams.status" placeholder="全部" clearable style="width:120px">
|
|
|
+ <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="操作时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="dateRange"
|
|
|
+ type="daterange"
|
|
|
+ range-separator="-"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ style="width:220px"
|
|
|
+ @change="handleDateChange"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <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-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport">导出</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- ===== 日志列表 ===== -->
|
|
|
<el-card shadow="never">
|
|
|
- <div slot="header">
|
|
|
- <span>代理操作日志</span>
|
|
|
- </div>
|
|
|
- <el-empty description="功能开发中,敬请期待" />
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ v-loading="loading"
|
|
|
+ :data="logList"
|
|
|
+ size="small"
|
|
|
+ style="width:100%"
|
|
|
+ >
|
|
|
+ <el-table-column label="日志ID" prop="operId" width="80" align="center" />
|
|
|
+ <el-table-column label="模块标题" prop="title" min-width="120" show-overflow-tooltip />
|
|
|
+ <el-table-column label="业务类型" align="center" width="90">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag :type="businessTypeMap[scope.row.businessType] && businessTypeMap[scope.row.businessType].type" size="mini">
|
|
|
+ {{ businessTypeMap[scope.row.businessType] ? businessTypeMap[scope.row.businessType].label : '其它' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作人" prop="operName" width="100" align="center" />
|
|
|
+ <el-table-column label="请求方式" prop="requestMethod" width="90" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag :type="methodTypeMap[scope.row.requestMethod] || 'info'" size="mini" plain>
|
|
|
+ {{ scope.row.requestMethod || '-' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="主机地址" prop="operIp" width="130" align="center" />
|
|
|
+ <el-table-column label="请求URL" prop="operUrl" min-width="160" show-overflow-tooltip />
|
|
|
+ <el-table-column label="操作状态" align="center" width="90">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag v-if="scope.row.status === 0 || scope.row.status === '0'" type="success" size="mini">正常</el-tag>
|
|
|
+ <el-tag v-else type="danger" size="mini">异常</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作时间" prop="operTime" width="160" align="center" />
|
|
|
+ <el-table-column label="操作" align="center" width="70" fixed="right">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button size="mini" type="text" icon="el-icon-view" @click="handleDetail(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="640px" append-to-body>
|
|
|
+ <el-descriptions :column="2" border size="small">
|
|
|
+ <el-descriptions-item label="日志ID">{{ detail.operId }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="模块标题">{{ detail.title }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="业务类型">
|
|
|
+ <el-tag
|
|
|
+ :type="businessTypeMap[detail.businessType] && businessTypeMap[detail.businessType].type"
|
|
|
+ size="mini"
|
|
|
+ >
|
|
|
+ {{ businessTypeMap[detail.businessType] ? businessTypeMap[detail.businessType].label : '其它' }}
|
|
|
+ </el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="操作人员">{{ detail.operName || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="请求方式">{{ detail.requestMethod || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="主机地址">{{ detail.operIp || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="请求URL" :span="2">{{ detail.operUrl || '-' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="请求参数" :span="2">
|
|
|
+ <div class="param-box">{{ detail.operParam || '-' }}</div>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="操作状态">
|
|
|
+ <el-tag v-if="detail.status === 0 || detail.status === '0'" type="success" size="mini">正常</el-tag>
|
|
|
+ <el-tag v-else type="danger" size="mini">异常</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="操作时间">{{ detail.operTime }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="租户名称" v-if="detail.companyName">{{ detail.companyName }}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="detailOpen = false">关 闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+import { listProxyOperLog, exportProxyOperLog } from '@/api/admin/proxyOperLog'
|
|
|
+
|
|
|
export default {
|
|
|
name: 'AdminProxyOperLog',
|
|
|
data() {
|
|
|
- return {}
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ exportLoading: false,
|
|
|
+ total: 0,
|
|
|
+ logList: [],
|
|
|
+ dateRange: [],
|
|
|
+ queryParams: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ operName: null,
|
|
|
+ status: null,
|
|
|
+ beginTime: null,
|
|
|
+ endTime: null
|
|
|
+ },
|
|
|
+ statusOptions: [
|
|
|
+ { value: 0, label: '正常' },
|
|
|
+ { value: 1, label: '异常' }
|
|
|
+ ],
|
|
|
+ businessTypeMap: {
|
|
|
+ 0: { label: '其它', type: 'info' },
|
|
|
+ 1: { label: '新增', type: 'success' },
|
|
|
+ 2: { label: '修改', type: 'warning' },
|
|
|
+ 3: { label: '删除', type: 'danger' }
|
|
|
+ },
|
|
|
+ methodTypeMap: {
|
|
|
+ GET: '',
|
|
|
+ POST: 'success',
|
|
|
+ PUT: 'warning',
|
|
|
+ DELETE: 'danger'
|
|
|
+ },
|
|
|
+ detailOpen: false,
|
|
|
+ detail: {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getList() {
|
|
|
+ this.loading = true
|
|
|
+ listProxyOperLog(this.queryParams).then(response => {
|
|
|
+ this.logList = response.rows || []
|
|
|
+ this.total = response.total || 0
|
|
|
+ }).finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleQuery() {
|
|
|
+ this.queryParams.pageNum = 1
|
|
|
+ this.getList()
|
|
|
+ },
|
|
|
+ resetQuery() {
|
|
|
+ this.dateRange = []
|
|
|
+ this.resetForm('queryForm')
|
|
|
+ this.queryParams.beginTime = null
|
|
|
+ this.queryParams.endTime = null
|
|
|
+ this.handleQuery()
|
|
|
+ },
|
|
|
+ handleDateChange(val) {
|
|
|
+ if (val && val.length === 2) {
|
|
|
+ this.queryParams.beginTime = val[0]
|
|
|
+ this.queryParams.endTime = val[1]
|
|
|
+ } else {
|
|
|
+ this.queryParams.beginTime = null
|
|
|
+ this.queryParams.endTime = null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleDetail(row) {
|
|
|
+ this.detail = Object.assign({}, row)
|
|
|
+ this.detailOpen = true
|
|
|
+ },
|
|
|
+ handleExport() {
|
|
|
+ this.exportLoading = true
|
|
|
+ exportProxyOperLog(this.queryParams).then(response => {
|
|
|
+ this.download(response.msg)
|
|
|
+ this.exportLoading = false
|
|
|
+ }).catch(() => { this.exportLoading = false })
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.mb16 { margin-bottom: 16px; }
|
|
|
+.filter-card { padding-bottom: 0; }
|
|
|
+.param-box {
|
|
|
+ max-height: 120px;
|
|
|
+ overflow-y: auto;
|
|
|
+ word-break: break-all;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ font-size: 12px;
|
|
|
+ font-family: monospace;
|
|
|
+ background: #f5f7fa;
|
|
|
+ padding: 4px 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+</style>
|