Merge pull request #2271 from dataease/pr@dev@feat_log

feat: 操作日志
This commit is contained in:
fit2cloud-chenyw
2022-05-18 18:17:31 +08:00
committed by GitHub
29 changed files with 1181 additions and 76 deletions

View File

@@ -47,11 +47,12 @@ export function editDs(data) {
})
}
export function delDs(id) {
export function delDs(data) {
return request({
url: 'datasource/delete/' + id,
url: 'datasource/delete',
loading: true,
method: 'post'
method: 'post',
data
})
}
@@ -81,7 +82,7 @@ export function getSchema(data) {
})
}
export function checkApiDatasource(data){
export function checkApiDatasource(data) {
return request({
url: 'datasource/checkApiDatasource',
method: 'post',

View File

@@ -0,0 +1,26 @@
import request from '@/utils/request'
export function logGrid(page, size, data) {
return request({
url: '/api/log/logGrid/' + page + '/' + size,
method: 'post',
data,
loading: true
})
}
export function opTypes() {
return request({
url: '/api/log/opTypes',
method: 'post',
loading: true
})
}
export function exportExcel() {
return request({
url: '/api/log/export',
method: 'post',
loading: true
})
}

View File

@@ -2041,5 +2041,14 @@ export default {
port: '端口',
user: '用户名',
passwd: '密码'
},
log: {
title: '操作日志',
optype: '操作类型',
detail: '操作详情',
user: '操作用户',
time: '操作时间',
export: '导出',
search_by_key: '搜索详情'
}
}

View File

@@ -827,3 +827,6 @@ div:focus {
// position: relative !important;
right: 0px;
}
.fu-operator-component__operator {
display: none !important;
}

View File

@@ -5,11 +5,16 @@
<span class="title-text">
{{ $t('commons.datasource') }}
</span>
<el-button icon="el-icon-plus" type="text" size="mini" style="float: right;"
@click="addFolder"/>
<el-button
icon="el-icon-plus"
type="text"
size="mini"
style="float: right;"
@click="addFolder"
/>
</el-row>
<el-divider/>
<el-divider />
<el-row>
<el-form>
<el-form-item class="form-item">
@@ -39,35 +44,41 @@
<span slot-scope="{ node, data }" class="custom-tree-node-list father">
<span style="display: flex;flex: 1;width: 0;">
<span v-if="data.type !== 'folder' && data.status !== 'Error' && data.status !== 'Warning'">
<svg-icon icon-class="datasource" class="ds-icon-scene"/>
<svg-icon icon-class="datasource" class="ds-icon-scene" />
</span>
<span v-if="data.status === 'Error'">
<svg-icon icon-class="exclamationmark" class="ds-icon-scene"/>
<svg-icon icon-class="exclamationmark" class="ds-icon-scene" />
</span>
<span v-if="data.status === 'Warning'">
<svg-icon icon-class="exclamationmark2" class="ds-icon-scene"/>
<svg-icon icon-class="exclamationmark2" class="ds-icon-scene" />
</span>
<span v-if="data.type === 'folder'">
<i class="el-icon-folder"/>
<i class="el-icon-folder" />
</span>
<span v-if=" data.status === 'Error'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
<span
v-if=" data.status === 'Error'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"
>
<el-tooltip effect="dark" :content="$t('datasource.in_valid')" placement="right">
<span>
{{ data.name }}
</span>
</el-tooltip>
</span>
<span v-if=" data.status === 'Warning'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
<span
v-if=" data.status === 'Warning'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"
>
<el-tooltip effect="dark" :content="$t('datasource.warning')" placement="right">
<span>
{{ data.name }}
</span>
</el-tooltip>
</span>
<span v-if="data.status !== 'Error' && data.status !== 'Warning'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
<span
v-if="data.status !== 'Error' && data.status !== 'Warning'"
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"
>
{{ data.name }}
</span>
@@ -103,7 +114,7 @@
</el-col>
</template>
<script>
import {listDatasource, listDatasourceByType, delDs, listDatasourceType} from '@/api/system/datasource'
import { listDatasource, listDatasourceByType, delDs, listDatasourceType } from '@/api/system/datasource'
export default {
name: 'DsTree',
@@ -162,14 +173,14 @@ export default {
listDatasourceByType(datasource.type).then(res => {
typeData = this.buildTree(res.data)
if (typeData.length === 0) {
let index = this.tData.findIndex(item => {
const index = this.tData.findIndex(item => {
if (item.id === datasource.type) {
return true;
return true
}
})
this.tData.splice(index, 1)
} else {
let find = false;
let find = false
for (let index = 0; index < this.tData.length; index++) {
if (typeData[0].id === this.tData[index].id) {
this.tData[index].children = typeData[0].children
@@ -212,7 +223,7 @@ export default {
this.switchMain('DsForm', {}, this.tData, this.dsTypes)
},
addFolderWithType(data) {
this.switchMain('DsForm', {type: data.id}, this.tData, this.dsTypes)
this.switchMain('DsForm', { type: data.id }, this.tData, this.dsTypes)
},
nodeClick(node, data) {
if (node.type === 'folder') return
@@ -220,7 +231,7 @@ export default {
},
clickFileMore(param) {
const {optType, data} = param
const { optType, data } = param
switch (optType) {
case 'edit':
this.edit(data)
@@ -233,13 +244,13 @@ export default {
}
},
beforeClickFile(optType, data, node) {
return {optType, data, node}
return { optType, data, node }
},
edit(row) {
this.switchMain('DsForm', row, this.tData, this.dsTypes)
},
showInfo(row) {
const param = {...row.data, ...{showModel: 'show'}}
const param = { ...row.data, ...{ showModel: 'show' }}
this.switchMain('DsForm', param, this.tData, this.dsTypes)
},
_handleDelete(datasource) {
@@ -248,12 +259,13 @@ export default {
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
delDs(datasource.id).then(res => {
if(res.success){
const parma = { type: datasource.type, id: datasource.id }
delDs(parma).then(res => {
if (res.success) {
this.$success(this.$t('commons.delete_success'))
this.switchMain('DataHome', {}, this.tData, this.dsTypes)
this.refreshType(datasource)
}else {
} else {
this.$message({
type: 'error',
message: res.message

View File

@@ -0,0 +1,137 @@
<template>
<layout-content :header="$t('log.title')">
<complex-table
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
:data="data"
:columns="columns"
local-key="logGrid"
:search-config="searchConfig"
:pagination-config="paginationConfig"
@select="select"
@search="search"
@sort-change="sortChange"
>
<template #toolbar>
<el-button v-permission="['log:export']" icon="el-icon-download" size="mini" @click="exportData">{{ $t('log.export') }}</el-button>
</template>
<el-table-column prop="opType" :label="$t('log.optype')" width="120">
<template v-slot:default="{row}">
<span>{{ row.opType + row.sourceType }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" prop="detail" :label="$t('log.detail')" />
<el-table-column prop="user" :label="$t('log.user')" width="80" />
<el-table-column :show-overflow-tooltip="true" prop="time" sortable="custom" :label="$t('log.time')" width="180">
<template v-slot:default="scope">
<span>{{ scope.row.time | timestampFormatDate }}</span>
</template>
</el-table-column>
</complex-table>
</layout-content>
</template>
<script>
import LayoutContent from '@/components/business/LayoutContent'
import ComplexTable from '@/components/business/complex-table'
import { formatCondition, formatQuickCondition, addOrder, formatOrders } from '@/utils/index'
import { logGrid, opTypes, exportExcel } from '@/api/system/log'
export default {
components: { ComplexTable, LayoutContent },
data() {
return {
columns: [],
searchConfig: {
useQuickSearch: true,
useComplexSearch: true,
quickPlaceholder: this.$t('log.search_by_key'),
components: [
{
field: 'optype',
label: this.$t('log.optype'),
component: 'FuComplexMixSelect',
options: [],
multiple: true,
class: 'de-log-filter',
defaultOperator: 'in'
},
{ field: 'nick_name', label: this.$t('log.user'), component: 'DeComplexInput', class: 'de-log-filter' },
{ field: 'time', label: this.$t('log.time'), component: 'FuComplexDateTime', defaultOperator: 'between', class: 'de-log-filter' }
]
},
paginationConfig: {
currentPage: 1,
pageSize: 10,
total: 0
},
data: [],
types: [],
orderConditions: [],
last_condition: null
}
},
created() {
this.types = []
opTypes().then(res => {
const datas = res.data
datas.forEach(item => {
this.types.push({ 'label': item.name, 'value': item.id })
})
this.searchConfig.components[0].options = this.types
})
},
mounted() {
this.search()
},
methods: {
exportData() {
console.log('exportting...')
exportExcel().then(res => {
})
},
sortChange({ column, prop, order }) {
this.orderConditions = []
if (!order) {
this.search(this.last_condition)
return
}
this.orderConditions = []
addOrder({ field: prop, value: order }, this.orderConditions)
this.search(this.last_condition)
},
select(selection) {
},
search(condition) {
this.last_condition = condition
condition = formatQuickCondition(condition, 'key')
const temp = formatCondition(condition)
const param = temp || {}
param['orders'] = formatOrders(this.orderConditions)
const { currentPage, pageSize } = this.paginationConfig
logGrid(currentPage, pageSize, param).then(response => {
this.data = response.data.listObject
this.paginationConfig.total = response.data.itemCount
})
}
}
}
</script>
<style scoped>
</style>