mirror of https://github.com/veops/cmdb.git
Merge pull request #580 from veops/dev_ui_240716
feat: add history export
This commit is contained in:
commit
4e857c2775
|
@ -1,89 +1,92 @@
|
||||||
import { axios } from '@/utils/request'
|
import { axios } from '@/utils/request'
|
||||||
|
|
||||||
export function getCIHistory(ciId) {
|
export function getCIHistory(ciId) {
|
||||||
return axios({
|
return axios({
|
||||||
url: `/v0.1/history/ci/${ciId}`,
|
url: `/v0.1/history/ci/${ciId}`,
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCIHistoryTable(params) {
|
export function getCIHistoryTable(params) {
|
||||||
return axios({
|
return axios({
|
||||||
url: `/v0.1/history/records/attribute`,
|
url: `/v0.1/history/records/attribute`,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params: params
|
params: params,
|
||||||
})
|
timeout: 30 * 1000
|
||||||
}
|
})
|
||||||
|
}
|
||||||
export function getRelationTable(params) {
|
|
||||||
return axios({
|
export function getRelationTable(params) {
|
||||||
url: `/v0.1/history/records/relation`,
|
return axios({
|
||||||
method: 'GET',
|
url: `/v0.1/history/records/relation`,
|
||||||
params: params
|
method: 'GET',
|
||||||
})
|
params: params,
|
||||||
}
|
timeout: 30 * 1000
|
||||||
|
})
|
||||||
export function getCITypesTable(params) {
|
}
|
||||||
return axios({
|
|
||||||
url: `/v0.1/history/ci_types`,
|
export function getCITypesTable(params) {
|
||||||
method: 'GET',
|
return axios({
|
||||||
params: params
|
url: `/v0.1/history/ci_types`,
|
||||||
})
|
method: 'GET',
|
||||||
}
|
params: params,
|
||||||
|
timeout: 30 * 1000
|
||||||
export function getUsers(params) {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/v1/acl/users/employee`,
|
|
||||||
method: 'GET',
|
export function getUsers(params) {
|
||||||
params: params
|
return axios({
|
||||||
})
|
url: `/v1/acl/users/employee`,
|
||||||
}
|
method: 'GET',
|
||||||
|
params: params
|
||||||
export function getCiTriggers(params) {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/v0.1/history/ci_triggers`,
|
|
||||||
method: 'GET',
|
export function getCiTriggers(params) {
|
||||||
params: params
|
return axios({
|
||||||
})
|
url: `/v0.1/history/ci_triggers`,
|
||||||
}
|
method: 'GET',
|
||||||
|
params: params
|
||||||
export function getCiTriggersByCiId(ci_id, params) {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/v0.1/history/ci_triggers/${ci_id}`,
|
|
||||||
method: 'GET',
|
export function getCiTriggersByCiId(ci_id, params) {
|
||||||
params
|
return axios({
|
||||||
})
|
url: `/v0.1/history/ci_triggers/${ci_id}`,
|
||||||
}
|
method: 'GET',
|
||||||
|
params
|
||||||
export function getCiRelatedTickets(params) {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/itsm/v1/process_ticket/get_tickets_by`,
|
|
||||||
method: 'POST',
|
export function getCiRelatedTickets(params) {
|
||||||
data: params,
|
return axios({
|
||||||
isShowMessage: false
|
url: `/itsm/v1/process_ticket/get_tickets_by`,
|
||||||
})
|
method: 'POST',
|
||||||
}
|
data: params,
|
||||||
|
isShowMessage: false
|
||||||
export function judgeItsmInstalled() {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/itsm/v1/process_ticket/itsm_existed`,
|
|
||||||
method: 'GET',
|
export function judgeItsmInstalled() {
|
||||||
isShowMessage: false
|
return axios({
|
||||||
})
|
url: `/itsm/v1/process_ticket/itsm_existed`,
|
||||||
}
|
method: 'GET',
|
||||||
|
isShowMessage: false
|
||||||
export function getCIsBaseline(params) {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/v0.1/ci/baseline`,
|
|
||||||
method: 'GET',
|
export function getCIsBaseline(params) {
|
||||||
params
|
return axios({
|
||||||
})
|
url: `/v0.1/ci/baseline`,
|
||||||
}
|
method: 'GET',
|
||||||
|
params
|
||||||
export function CIBaselineRollback(ciId, params) {
|
})
|
||||||
return axios({
|
}
|
||||||
url: `/v0.1/ci/${ciId}/baseline/rollback`,
|
|
||||||
method: 'POST',
|
export function CIBaselineRollback(ciId, params) {
|
||||||
data: params
|
return axios({
|
||||||
})
|
url: `/v0.1/ci/${ciId}/baseline/rollback`,
|
||||||
}
|
method: 'POST',
|
||||||
|
data: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,449 +1,463 @@
|
||||||
<template>
|
<template>
|
||||||
<div :style="{ height: '100%' }">
|
<div :style="{ height: '100%' }">
|
||||||
<a-tabs v-if="hasPermission" class="ci-detail-tab" v-model="activeTabKey" @change="changeTab">
|
<a-tabs v-if="hasPermission" class="ci-detail-tab" v-model="activeTabKey" @change="changeTab">
|
||||||
<a @click="shareCi" slot="tabBarExtraContent" :style="{ marginRight: '24px' }">
|
<a @click="shareCi" slot="tabBarExtraContent" :style="{ marginRight: '24px' }">
|
||||||
<a-icon type="share-alt" />
|
<a-icon type="share-alt" />
|
||||||
{{ $t('cmdb.ci.share') }}
|
{{ $t('cmdb.ci.share') }}
|
||||||
</a>
|
</a>
|
||||||
<a-tab-pane key="tab_1">
|
<a-tab-pane key="tab_1">
|
||||||
<span slot="tab"><a-icon type="book" />{{ $t('cmdb.attribute') }}</span>
|
<span slot="tab"><a-icon type="book" />{{ $t('cmdb.attribute') }}</span>
|
||||||
<div class="ci-detail-attr">
|
<div class="ci-detail-attr">
|
||||||
<el-descriptions
|
<el-descriptions
|
||||||
:title="group.name || $t('other')"
|
:title="group.name || $t('other')"
|
||||||
:key="group.name"
|
:key="group.name"
|
||||||
v-for="group in attributeGroups"
|
v-for="group in attributeGroups"
|
||||||
border
|
border
|
||||||
:column="3"
|
:column="3"
|
||||||
>
|
>
|
||||||
<el-descriptions-item
|
<el-descriptions-item
|
||||||
:label="`${attr.alias || attr.name}`"
|
:label="`${attr.alias || attr.name}`"
|
||||||
:key="attr.name"
|
:key="attr.name"
|
||||||
v-for="attr in group.attributes"
|
v-for="attr in group.attributes"
|
||||||
>
|
>
|
||||||
<ci-detail-attr-content :ci="ci" :attr="attr" @refresh="refresh" @updateCIByself="updateCIByself" />
|
<ci-detail-attr-content :ci="ci" :attr="attr" @refresh="refresh" @updateCIByself="updateCIByself" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="tab_2">
|
<a-tab-pane key="tab_2">
|
||||||
<span slot="tab"><a-icon type="branches" />{{ $t('cmdb.relation') }}</span>
|
<span slot="tab"><a-icon type="branches" />{{ $t('cmdb.relation') }}</span>
|
||||||
<div :style="{ height: '100%', padding: '24px', overflow: 'auto' }">
|
<div :style="{ height: '100%', padding: '24px', overflow: 'auto' }">
|
||||||
<ci-detail-relation ref="ciDetailRelation" :ciId="ciId" :typeId="typeId" :ci="ci" />
|
<ci-detail-relation ref="ciDetailRelation" :ciId="ciId" :typeId="typeId" :ci="ci" />
|
||||||
</div>
|
</div>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="tab_3">
|
<a-tab-pane key="tab_3">
|
||||||
<span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span>
|
<span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span>
|
||||||
<div :style="{ padding: '24px', height: '100%' }">
|
<div :style="{ padding: '24px', height: '100%' }">
|
||||||
<a-space :style="{ 'margin-bottom': '10px', display: 'flex' }">
|
<a-space :style="{ 'margin-bottom': '10px', display: 'flex' }">
|
||||||
<a-button type="primary" class="ops-button-ghost" ghost @click="handleRollbackCI()">
|
<a-button type="primary" class="ops-button-ghost" ghost @click="handleRollbackCI()">
|
||||||
<ops-icon type="shishizhuangtai" />{{ $t('cmdb.ci.rollback') }}
|
<ops-icon type="shishizhuangtai" />{{ $t('cmdb.ci.rollback') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
<a-button type="primary" class="ops-button-ghost" ghost @click="handleExport">
|
||||||
<ci-rollback-form ref="ciRollbackForm" :ciIds="[ciId]" @getCIHistory="getCIHistory" />
|
<ops-icon type="veops-export" />{{ $t('export') }}
|
||||||
<vxe-table
|
</a-button>
|
||||||
ref="xTable"
|
</a-space>
|
||||||
show-overflow
|
<ci-rollback-form ref="ciRollbackForm" :ciIds="[ciId]" @getCIHistory="getCIHistory" />
|
||||||
show-header-overflow
|
<vxe-table
|
||||||
:data="ciHistory"
|
ref="xTable"
|
||||||
size="small"
|
show-overflow
|
||||||
:height="tableHeight"
|
show-header-overflow
|
||||||
highlight-hover-row
|
:data="ciHistory"
|
||||||
:span-method="mergeRowMethod"
|
size="small"
|
||||||
:scroll-y="{ enabled: false, gt: 20 }"
|
:height="tableHeight"
|
||||||
:scroll-x="{ enabled: false, gt: 0 }"
|
highlight-hover-row
|
||||||
border
|
:span-method="mergeRowMethod"
|
||||||
resizable
|
:scroll-y="{ enabled: false, gt: 20 }"
|
||||||
class="ops-unstripe-table"
|
:scroll-x="{ enabled: false, gt: 0 }"
|
||||||
>
|
border
|
||||||
<template #empty>
|
resizable
|
||||||
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
|
class="ops-unstripe-table"
|
||||||
<img slot="image" :src="require('@/assets/data_empty.png')" />
|
>
|
||||||
<span slot="description"> {{ $t('noData') }} </span>
|
<template #empty>
|
||||||
</a-empty>
|
<a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
|
||||||
</template>
|
<img slot="image" :src="require('@/assets/data_empty.png')" />
|
||||||
<vxe-table-column sortable field="created_at" :title="$t('created_at')"></vxe-table-column>
|
<span slot="description"> {{ $t('noData') }} </span>
|
||||||
<vxe-table-column
|
</a-empty>
|
||||||
field="username"
|
</template>
|
||||||
:title="$t('user')"
|
<vxe-table-column sortable field="created_at" :title="$t('created_at')"></vxe-table-column>
|
||||||
:filters="[]"
|
<vxe-table-column
|
||||||
:filter-method="filterUsernameMethod"
|
field="username"
|
||||||
></vxe-table-column>
|
:title="$t('user')"
|
||||||
<vxe-table-column
|
:filters="[]"
|
||||||
field="operate_type"
|
:filter-method="filterUsernameMethod"
|
||||||
:filters="[
|
></vxe-table-column>
|
||||||
{ value: 0, label: $t('new') },
|
<vxe-table-column
|
||||||
{ value: 1, label: $t('delete') },
|
field="operate_type"
|
||||||
{ value: 2, label: $t('update') },
|
:filters="[
|
||||||
]"
|
{ value: 0, label: $t('new') },
|
||||||
:filter-method="filterOperateMethod"
|
{ value: 1, label: $t('delete') },
|
||||||
:title="$t('operation')"
|
{ value: 2, label: $t('update') },
|
||||||
>
|
]"
|
||||||
<template #default="{ row }">
|
:filter-method="filterOperateMethod"
|
||||||
{{ operateTypeMap[row.operate_type] }}
|
:title="$t('operation')"
|
||||||
</template>
|
>
|
||||||
</vxe-table-column>
|
<template #default="{ row }">
|
||||||
<vxe-table-column
|
{{ operateTypeMap[row.operate_type] }}
|
||||||
field="attr_alias"
|
</template>
|
||||||
:title="$t('cmdb.attribute')"
|
</vxe-table-column>
|
||||||
:filters="[]"
|
<vxe-table-column
|
||||||
:filter-method="filterAttrMethod"
|
field="attr_alias"
|
||||||
></vxe-table-column>
|
:title="$t('cmdb.attribute')"
|
||||||
<vxe-table-column field="old" :title="$t('cmdb.history.old')">
|
:filters="[]"
|
||||||
<template #default="{ row }">
|
:filter-method="filterAttrMethod"
|
||||||
<span v-if="row.value_type === '6'">{{ JSON.parse(row.old) }}</span>
|
></vxe-table-column>
|
||||||
<span v-else>{{ row.old }}</span>
|
<vxe-table-column :cell-type="'string'" field="old" :title="$t('cmdb.history.old')">
|
||||||
</template>
|
<template #default="{ row }">
|
||||||
</vxe-table-column>
|
<span v-if="row.value_type === '6'">{{ JSON.parse(row.old) }}</span>
|
||||||
<vxe-table-column field="new" :title="$t('cmdb.history.new')">
|
<span v-else>{{ row.old }}</span>
|
||||||
<template #default="{ row }">
|
</template>
|
||||||
<span v-if="row.value_type === '6'">{{ JSON.parse(row.new) }}</span>
|
</vxe-table-column>
|
||||||
<span v-else>{{ row.new }}</span>
|
<vxe-table-column :cell-type="'string'" field="new" :title="$t('cmdb.history.new')">
|
||||||
</template>
|
<template #default="{ row }">
|
||||||
</vxe-table-column>
|
<span v-if="row.value_type === '6'">{{ JSON.parse(row.new) }}</span>
|
||||||
</vxe-table>
|
<span v-else>{{ row.new }}</span>
|
||||||
</div>
|
</template>
|
||||||
</a-tab-pane>
|
</vxe-table-column>
|
||||||
<a-tab-pane key="tab_4">
|
</vxe-table>
|
||||||
<span slot="tab"><ops-icon type="itsm_auto_trigger" />{{ $t('cmdb.history.triggerHistory') }}</span>
|
</div>
|
||||||
<div :style="{ padding: '24px', height: '100%' }">
|
</a-tab-pane>
|
||||||
<TriggerTable :ci_id="ci._id" />
|
<a-tab-pane key="tab_4">
|
||||||
</div>
|
<span slot="tab"><ops-icon type="itsm_auto_trigger" />{{ $t('cmdb.history.triggerHistory') }}</span>
|
||||||
</a-tab-pane>
|
<div :style="{ padding: '24px', height: '100%' }">
|
||||||
<a-tab-pane key="tab_5">
|
<TriggerTable :ci_id="ci._id" />
|
||||||
<span slot="tab"><ops-icon type="itsm-association" />{{ $t('cmdb.ci.relITSM') }}</span>
|
</div>
|
||||||
<div :style="{ padding: '24px', height: '100%' }">
|
</a-tab-pane>
|
||||||
<RelatedItsmTable ref="relatedITSMTable" :ci_id="ci._id" :ciHistory="ciHistory" :itsmInstalled="itsmInstalled" :attrList="attrList" />
|
<a-tab-pane key="tab_5">
|
||||||
</div>
|
<span slot="tab"><ops-icon type="itsm-association" />{{ $t('cmdb.ci.relITSM') }}</span>
|
||||||
</a-tab-pane>
|
<div :style="{ padding: '24px', height: '100%' }">
|
||||||
</a-tabs>
|
<RelatedItsmTable ref="relatedITSMTable" :ci_id="ci._id" :ciHistory="ciHistory" :itsmInstalled="itsmInstalled" :attrList="attrList" />
|
||||||
<a-empty
|
</div>
|
||||||
v-else
|
</a-tab-pane>
|
||||||
:image-style="{
|
</a-tabs>
|
||||||
height: '100px',
|
<a-empty
|
||||||
}"
|
v-else
|
||||||
:style="{ paddingTop: '20%' }"
|
:image-style="{
|
||||||
>
|
height: '100px',
|
||||||
<img slot="image" :src="require('@/assets/data_empty.png')" />
|
}"
|
||||||
<span slot="description"> {{ $t('cmdb.ci.noPermission') }} </span>
|
:style="{ paddingTop: '20%' }"
|
||||||
</a-empty>
|
>
|
||||||
</div>
|
<img slot="image" :src="require('@/assets/data_empty.png')" />
|
||||||
</template>
|
<span slot="description"> {{ $t('cmdb.ci.noPermission') }} </span>
|
||||||
|
</a-empty>
|
||||||
<script>
|
</div>
|
||||||
import _ from 'lodash'
|
</template>
|
||||||
import { Descriptions, DescriptionsItem } from 'element-ui'
|
|
||||||
import { getCITypeGroupById, getCITypes } from '@/modules/cmdb/api/CIType'
|
<script>
|
||||||
import { getCIHistory, judgeItsmInstalled } from '@/modules/cmdb/api/history'
|
import _ from 'lodash'
|
||||||
import { getCIById } from '@/modules/cmdb/api/ci'
|
import { Descriptions, DescriptionsItem } from 'element-ui'
|
||||||
import CiDetailAttrContent from './ciDetailAttrContent.vue'
|
import { getCITypeGroupById, getCITypes } from '@/modules/cmdb/api/CIType'
|
||||||
import CiDetailRelation from './ciDetailRelation.vue'
|
import { getCIHistory, judgeItsmInstalled } from '@/modules/cmdb/api/history'
|
||||||
import TriggerTable from '../../operation_history/modules/triggerTable.vue'
|
import { getCIById } from '@/modules/cmdb/api/ci'
|
||||||
import RelatedItsmTable from './ciDetailRelatedItsmTable.vue'
|
import CiDetailAttrContent from './ciDetailAttrContent.vue'
|
||||||
import CiRollbackForm from './ciRollbackForm.vue'
|
import CiDetailRelation from './ciDetailRelation.vue'
|
||||||
export default {
|
import TriggerTable from '../../operation_history/modules/triggerTable.vue'
|
||||||
name: 'CiDetailTab',
|
import RelatedItsmTable from './ciDetailRelatedItsmTable.vue'
|
||||||
components: {
|
import CiRollbackForm from './ciRollbackForm.vue'
|
||||||
ElDescriptions: Descriptions,
|
export default {
|
||||||
ElDescriptionsItem: DescriptionsItem,
|
name: 'CiDetailTab',
|
||||||
CiDetailAttrContent,
|
components: {
|
||||||
CiDetailRelation,
|
ElDescriptions: Descriptions,
|
||||||
TriggerTable,
|
ElDescriptionsItem: DescriptionsItem,
|
||||||
RelatedItsmTable,
|
CiDetailAttrContent,
|
||||||
CiRollbackForm,
|
CiDetailRelation,
|
||||||
},
|
TriggerTable,
|
||||||
props: {
|
RelatedItsmTable,
|
||||||
typeId: {
|
CiRollbackForm,
|
||||||
type: Number,
|
},
|
||||||
required: true,
|
props: {
|
||||||
},
|
typeId: {
|
||||||
treeViewsLevels: {
|
type: Number,
|
||||||
type: Array,
|
required: true,
|
||||||
default: () => [],
|
},
|
||||||
},
|
treeViewsLevels: {
|
||||||
attributeHistoryTableHeight: {
|
type: Array,
|
||||||
type: Number,
|
default: () => [],
|
||||||
default: null
|
},
|
||||||
}
|
attributeHistoryTableHeight: {
|
||||||
},
|
type: Number,
|
||||||
data() {
|
default: null
|
||||||
return {
|
}
|
||||||
ci: {},
|
},
|
||||||
item: [],
|
data() {
|
||||||
attributeGroups: [],
|
return {
|
||||||
activeTabKey: 'tab_1',
|
ci: {},
|
||||||
rowSpanMap: {},
|
item: [],
|
||||||
ciHistory: [],
|
attributeGroups: [],
|
||||||
ciId: null,
|
activeTabKey: 'tab_1',
|
||||||
ci_types: [],
|
rowSpanMap: {},
|
||||||
hasPermission: true,
|
ciHistory: [],
|
||||||
itsmInstalled: true,
|
ciId: null,
|
||||||
tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 120),
|
ci_types: [],
|
||||||
}
|
hasPermission: true,
|
||||||
},
|
itsmInstalled: true,
|
||||||
computed: {
|
tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 120),
|
||||||
windowHeight() {
|
}
|
||||||
return this.$store.state.windowHeight
|
},
|
||||||
},
|
computed: {
|
||||||
operateTypeMap() {
|
windowHeight() {
|
||||||
return {
|
return this.$store.state.windowHeight
|
||||||
0: this.$t('new'),
|
},
|
||||||
1: this.$t('delete'),
|
operateTypeMap() {
|
||||||
2: this.$t('update'),
|
return {
|
||||||
}
|
0: this.$t('new'),
|
||||||
},
|
1: this.$t('delete'),
|
||||||
},
|
2: this.$t('update'),
|
||||||
provide() {
|
}
|
||||||
return {
|
},
|
||||||
ci_types: () => {
|
},
|
||||||
return this.ci_types
|
provide() {
|
||||||
},
|
return {
|
||||||
}
|
ci_types: () => {
|
||||||
},
|
return this.ci_types
|
||||||
inject: {
|
},
|
||||||
reload: {
|
}
|
||||||
from: 'reload',
|
},
|
||||||
default: null,
|
inject: {
|
||||||
},
|
reload: {
|
||||||
handleSearch: {
|
from: 'reload',
|
||||||
from: 'handleSearch',
|
default: null,
|
||||||
default: null,
|
},
|
||||||
},
|
handleSearch: {
|
||||||
attrList: {
|
from: 'handleSearch',
|
||||||
from: 'attrList',
|
default: null,
|
||||||
default: () => [],
|
},
|
||||||
},
|
attrList: {
|
||||||
},
|
from: 'attrList',
|
||||||
methods: {
|
default: () => [],
|
||||||
async create(ciId, activeTabKey = 'tab_1', ciDetailRelationKey = '1') {
|
},
|
||||||
this.activeTabKey = activeTabKey
|
},
|
||||||
if (activeTabKey === 'tab_2') {
|
methods: {
|
||||||
this.$nextTick(() => {
|
async create(ciId, activeTabKey = 'tab_1', ciDetailRelationKey = '1') {
|
||||||
this.$refs.ciDetailRelation.activeKey = ciDetailRelationKey
|
this.activeTabKey = activeTabKey
|
||||||
})
|
if (activeTabKey === 'tab_2') {
|
||||||
}
|
this.$nextTick(() => {
|
||||||
this.ciId = ciId
|
this.$refs.ciDetailRelation.activeKey = ciDetailRelationKey
|
||||||
await this.getCI()
|
})
|
||||||
await this.judgeItsmInstalled()
|
}
|
||||||
if (this.hasPermission) {
|
this.ciId = ciId
|
||||||
this.getAttributes()
|
await this.getCI()
|
||||||
this.getCIHistory()
|
await this.judgeItsmInstalled()
|
||||||
getCITypes().then((res) => {
|
if (this.hasPermission) {
|
||||||
this.ci_types = res.ci_types
|
this.getAttributes()
|
||||||
})
|
this.getCIHistory()
|
||||||
}
|
getCITypes().then((res) => {
|
||||||
},
|
this.ci_types = res.ci_types
|
||||||
getAttributes() {
|
})
|
||||||
getCITypeGroupById(this.typeId, { need_other: 1 })
|
}
|
||||||
.then((res) => {
|
},
|
||||||
this.attributeGroups = res
|
getAttributes() {
|
||||||
})
|
getCITypeGroupById(this.typeId, { need_other: 1 })
|
||||||
.catch((e) => {})
|
.then((res) => {
|
||||||
},
|
this.attributeGroups = res
|
||||||
async getCI() {
|
})
|
||||||
await getCIById(this.ciId)
|
.catch((e) => {})
|
||||||
.then((res) => {
|
},
|
||||||
if (res.result.length) {
|
async getCI() {
|
||||||
this.ci = res.result[0]
|
await getCIById(this.ciId)
|
||||||
} else {
|
.then((res) => {
|
||||||
this.hasPermission = false
|
if (res.result.length) {
|
||||||
}
|
this.ci = res.result[0]
|
||||||
})
|
} else {
|
||||||
.catch((e) => {
|
this.hasPermission = false
|
||||||
if (e.response.status === 404) {
|
}
|
||||||
this.itsmInstalled = false
|
})
|
||||||
}
|
.catch((e) => {
|
||||||
})
|
if (e.response.status === 404) {
|
||||||
},
|
this.itsmInstalled = false
|
||||||
async judgeItsmInstalled() {
|
}
|
||||||
await judgeItsmInstalled().catch((e) => {
|
})
|
||||||
this.itsmInstalled = false
|
},
|
||||||
})
|
async judgeItsmInstalled() {
|
||||||
},
|
await judgeItsmInstalled().catch((e) => {
|
||||||
|
this.itsmInstalled = false
|
||||||
getCIHistory() {
|
})
|
||||||
getCIHistory(this.ciId)
|
},
|
||||||
.then((res) => {
|
|
||||||
this.ciHistory = res
|
getCIHistory() {
|
||||||
|
getCIHistory(this.ciId)
|
||||||
const rowSpanMap = {}
|
.then((res) => {
|
||||||
let startIndex = 0
|
this.ciHistory = res
|
||||||
let startCount = 1
|
|
||||||
res.forEach((item, index) => {
|
const rowSpanMap = {}
|
||||||
if (index === 0) {
|
let startIndex = 0
|
||||||
return
|
let startCount = 1
|
||||||
}
|
res.forEach((item, index) => {
|
||||||
if (res[index].record_id === res[startIndex].record_id) {
|
if (index === 0) {
|
||||||
startCount += 1
|
return
|
||||||
rowSpanMap[index] = 0
|
}
|
||||||
if (index === res.length - 1) {
|
if (res[index].record_id === res[startIndex].record_id) {
|
||||||
rowSpanMap[startIndex] = startCount
|
startCount += 1
|
||||||
}
|
rowSpanMap[index] = 0
|
||||||
} else {
|
if (index === res.length - 1) {
|
||||||
rowSpanMap[startIndex] = startCount
|
rowSpanMap[startIndex] = startCount
|
||||||
startIndex = index
|
}
|
||||||
startCount = 1
|
} else {
|
||||||
if (index === res.length - 1) {
|
rowSpanMap[startIndex] = startCount
|
||||||
rowSpanMap[index] = 1
|
startIndex = index
|
||||||
}
|
startCount = 1
|
||||||
}
|
if (index === res.length - 1) {
|
||||||
})
|
rowSpanMap[index] = 1
|
||||||
this.rowSpanMap = rowSpanMap
|
}
|
||||||
})
|
}
|
||||||
.catch((e) => {
|
})
|
||||||
console.log(e)
|
this.rowSpanMap = rowSpanMap
|
||||||
})
|
})
|
||||||
},
|
.catch((e) => {
|
||||||
changeTab(key) {
|
console.log(e)
|
||||||
this.activeTabKey = key
|
})
|
||||||
if (key === 'tab_3') {
|
},
|
||||||
this.$nextTick(() => {
|
changeTab(key) {
|
||||||
const $table = this.$refs.xTable
|
this.activeTabKey = key
|
||||||
if ($table) {
|
if (key === 'tab_3') {
|
||||||
const usernameColumn = $table.getColumnByField('username')
|
this.$nextTick(() => {
|
||||||
const attrColumn = $table.getColumnByField('attr_alias')
|
const $table = this.$refs.xTable
|
||||||
if (usernameColumn) {
|
if ($table) {
|
||||||
const usernameList = [...new Set(this.ciHistory.map((item) => item.username))]
|
const usernameColumn = $table.getColumnByField('username')
|
||||||
$table.setFilter(
|
const attrColumn = $table.getColumnByField('attr_alias')
|
||||||
usernameColumn,
|
if (usernameColumn) {
|
||||||
usernameList.map((item) => {
|
const usernameList = [...new Set(this.ciHistory.map((item) => item.username))]
|
||||||
return {
|
$table.setFilter(
|
||||||
value: item,
|
usernameColumn,
|
||||||
label: item,
|
usernameList.map((item) => {
|
||||||
}
|
return {
|
||||||
})
|
value: item,
|
||||||
)
|
label: item,
|
||||||
}
|
}
|
||||||
if (attrColumn) {
|
})
|
||||||
$table.setFilter(
|
)
|
||||||
attrColumn,
|
}
|
||||||
this.attrList().map((attr) => {
|
if (attrColumn) {
|
||||||
return { value: attr.alias || attr.name, label: attr.alias || attr.name }
|
$table.setFilter(
|
||||||
})
|
attrColumn,
|
||||||
)
|
this.attrList().map((attr) => {
|
||||||
}
|
return { value: attr.alias || attr.name, label: attr.alias || attr.name }
|
||||||
}
|
})
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
filterUsernameMethod({ value, row, column }) {
|
})
|
||||||
return row.username === value
|
}
|
||||||
},
|
},
|
||||||
filterOperateMethod({ value, row, column }) {
|
filterUsernameMethod({ value, row, column }) {
|
||||||
return Number(row.operate_type) === Number(value)
|
return row.username === value
|
||||||
},
|
},
|
||||||
filterAttrMethod({ value, row, column }) {
|
filterOperateMethod({ value, row, column }) {
|
||||||
return row.attr_alias === value
|
return Number(row.operate_type) === Number(value)
|
||||||
},
|
},
|
||||||
refresh(editAttrName) {
|
filterAttrMethod({ value, row, column }) {
|
||||||
this.getCI()
|
return row.attr_alias === value
|
||||||
const _find = this.treeViewsLevels.find((level) => level.name === editAttrName)
|
},
|
||||||
// 修改的字段为树形视图订阅的字段 则全部reload
|
refresh(editAttrName) {
|
||||||
setTimeout(() => {
|
this.getCI()
|
||||||
if (_find) {
|
const _find = this.treeViewsLevels.find((level) => level.name === editAttrName)
|
||||||
if (this.reload) {
|
// 修改的字段为树形视图订阅的字段 则全部reload
|
||||||
this.reload()
|
setTimeout(() => {
|
||||||
}
|
if (_find) {
|
||||||
} else {
|
if (this.reload) {
|
||||||
if (this.handleSearch) {
|
this.reload()
|
||||||
this.handleSearch()
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (this.handleSearch) {
|
||||||
}, 500)
|
this.handleSearch()
|
||||||
},
|
}
|
||||||
mergeRowMethod({ row, _rowIndex, column, visibleData }) {
|
}
|
||||||
const fields = ['created_at', 'username']
|
}, 500)
|
||||||
const cellValue1 = row['created_at']
|
},
|
||||||
const cellValue2 = row['username']
|
mergeRowMethod({ row, _rowIndex, column, visibleData }) {
|
||||||
if (cellValue1 && cellValue2 && fields.includes(column.property)) {
|
const fields = ['created_at', 'username']
|
||||||
const prevRow = visibleData[_rowIndex - 1]
|
const cellValue1 = row['created_at']
|
||||||
let nextRow = visibleData[_rowIndex + 1]
|
const cellValue2 = row['username']
|
||||||
if (prevRow && prevRow['created_at'] === cellValue1 && prevRow['username'] === cellValue2) {
|
if (cellValue1 && cellValue2 && fields.includes(column.property)) {
|
||||||
return { rowspan: 0, colspan: 0 }
|
const prevRow = visibleData[_rowIndex - 1]
|
||||||
} else {
|
let nextRow = visibleData[_rowIndex + 1]
|
||||||
let countRowspan = 1
|
if (prevRow && prevRow['created_at'] === cellValue1 && prevRow['username'] === cellValue2) {
|
||||||
while (nextRow && nextRow['created_at'] === cellValue1 && nextRow['username'] === cellValue2) {
|
return { rowspan: 0, colspan: 0 }
|
||||||
nextRow = visibleData[++countRowspan + _rowIndex]
|
} else {
|
||||||
}
|
let countRowspan = 1
|
||||||
if (countRowspan > 1) {
|
while (nextRow && nextRow['created_at'] === cellValue1 && nextRow['username'] === cellValue2) {
|
||||||
return { rowspan: countRowspan, colspan: 1 }
|
nextRow = visibleData[++countRowspan + _rowIndex]
|
||||||
}
|
}
|
||||||
}
|
if (countRowspan > 1) {
|
||||||
}
|
return { rowspan: countRowspan, colspan: 1 }
|
||||||
},
|
}
|
||||||
updateCIByself(params, editAttrName) {
|
}
|
||||||
const _ci = { ..._.cloneDeep(this.ci), ...params }
|
}
|
||||||
this.ci = _ci
|
},
|
||||||
const _find = this.treeViewsLevels.find((level) => level.name === editAttrName)
|
updateCIByself(params, editAttrName) {
|
||||||
// 修改的字段为树形视图订阅的字段 则全部reload
|
const _ci = { ..._.cloneDeep(this.ci), ...params }
|
||||||
setTimeout(() => {
|
this.ci = _ci
|
||||||
if (_find) {
|
const _find = this.treeViewsLevels.find((level) => level.name === editAttrName)
|
||||||
if (this.reload) {
|
// 修改的字段为树形视图订阅的字段 则全部reload
|
||||||
this.reload()
|
setTimeout(() => {
|
||||||
}
|
if (_find) {
|
||||||
} else {
|
if (this.reload) {
|
||||||
if (this.handleSearch) {
|
this.reload()
|
||||||
this.handleSearch()
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (this.handleSearch) {
|
||||||
}, 500)
|
this.handleSearch()
|
||||||
},
|
}
|
||||||
shareCi() {
|
}
|
||||||
const text = `${document.location.host}/cmdb/cidetail/${this.typeId}/${this.ciId}`
|
}, 500)
|
||||||
this.$copyText(text)
|
},
|
||||||
.then(() => {
|
shareCi() {
|
||||||
this.$message.success(this.$t('copySuccess'))
|
const text = `${document.location.host}/cmdb/cidetail/${this.typeId}/${this.ciId}`
|
||||||
})
|
this.$copyText(text)
|
||||||
.catch(() => {
|
.then(() => {
|
||||||
this.$message.error(this.$t('cmdb.ci.copyFailed'))
|
this.$message.success(this.$t('copySuccess'))
|
||||||
})
|
})
|
||||||
},
|
.catch(() => {
|
||||||
handleRollbackCI() {
|
this.$message.error(this.$t('cmdb.ci.copyFailed'))
|
||||||
this.$nextTick(() => {
|
})
|
||||||
this.$refs.ciRollbackForm.onOpen()
|
},
|
||||||
})
|
handleRollbackCI() {
|
||||||
},
|
this.$nextTick(() => {
|
||||||
},
|
this.$refs.ciRollbackForm.onOpen()
|
||||||
}
|
})
|
||||||
</script>
|
},
|
||||||
|
async handleExport() {
|
||||||
<style lang="less">
|
this.$refs.xTable.exportData({
|
||||||
.ci-detail-tab {
|
filename: this.$t('cmdb.ci.history'),
|
||||||
height: 100%;
|
sheetName: 'Sheet1',
|
||||||
.ant-tabs-content {
|
type: 'xlsx',
|
||||||
height: calc(100% - 45px);
|
types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
|
||||||
.ant-tabs-tabpane {
|
data: this.ciHistory,
|
||||||
height: 100%;
|
isMerge: true,
|
||||||
}
|
isColgroup: true,
|
||||||
}
|
})
|
||||||
.ant-tabs-bar {
|
}
|
||||||
margin: 0;
|
},
|
||||||
}
|
}
|
||||||
.ant-tabs-extra-content {
|
</script>
|
||||||
line-height: 44px;
|
|
||||||
}
|
<style lang="less">
|
||||||
.ci-detail-attr {
|
.ci-detail-tab {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
.ant-tabs-content {
|
||||||
padding: 24px;
|
height: calc(100% - 45px);
|
||||||
.el-descriptions-item__content {
|
.ant-tabs-tabpane {
|
||||||
cursor: default;
|
height: 100%;
|
||||||
&:hover a {
|
}
|
||||||
opacity: 1 !important;
|
}
|
||||||
}
|
.ant-tabs-bar {
|
||||||
}
|
margin: 0;
|
||||||
.el-descriptions:first-child > .el-descriptions__header {
|
}
|
||||||
margin-top: 0;
|
.ant-tabs-extra-content {
|
||||||
}
|
line-height: 44px;
|
||||||
.el-descriptions__header {
|
}
|
||||||
margin-bottom: 5px;
|
.ci-detail-attr {
|
||||||
margin-top: 20px;
|
height: 100%;
|
||||||
}
|
overflow: auto;
|
||||||
.ant-form-item {
|
padding: 24px;
|
||||||
margin-bottom: 0;
|
.el-descriptions-item__content {
|
||||||
}
|
cursor: default;
|
||||||
.ant-form-item-control {
|
&:hover a {
|
||||||
line-height: 19px;
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.el-descriptions:first-child > .el-descriptions__header {
|
||||||
</style>
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.el-descriptions__header {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.ant-form-item-control {
|
||||||
|
line-height: 19px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@searchFormReset="searchFormReset"
|
@searchFormReset="searchFormReset"
|
||||||
@searchFormChange="searchFormChange"
|
@searchFormChange="searchFormChange"
|
||||||
|
@export="handleExport"
|
||||||
></search-form>
|
></search-form>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
ref="xTable"
|
ref="xTable"
|
||||||
|
@ -86,13 +87,13 @@
|
||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column field="attr_alias" :title="$t('cmdb.history.attribute')"></vxe-column>
|
<vxe-column field="attr_alias" :title="$t('cmdb.history.attribute')"></vxe-column>
|
||||||
<vxe-column field="old" :title="$t('cmdb.history.old')"></vxe-column>
|
<vxe-column :cell-type="'string'" field="old" :title="$t('cmdb.history.old')"></vxe-column>
|
||||||
<vxe-column field="new" :title="$t('cmdb.history.new')"></vxe-column>
|
<vxe-column :cell-type="'string'" field="new" :title="$t('cmdb.history.new')"></vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
<pager
|
<pager
|
||||||
:current-page.sync="queryParams.page"
|
:current-page.sync="queryParams.page"
|
||||||
:page-size.sync="queryParams.page_size"
|
:page-size.sync="queryParams.page_size"
|
||||||
:page-sizes="[50, 100, 200]"
|
:page-sizes="[50, 100, 200, 500]"
|
||||||
:total="total"
|
:total="total"
|
||||||
:isLoading="loading"
|
:isLoading="loading"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
|
@ -391,6 +392,37 @@ export default {
|
||||||
filterOption(input, option) {
|
filterOption(input, option) {
|
||||||
return option.componentOptions.children[0].text.indexOf(input) >= 0
|
return option.componentOptions.children[0].text.indexOf(input) >= 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async handleExport(params) {
|
||||||
|
const hide = this.$message.loading(this.$t('loading'), 0)
|
||||||
|
const res = await getCIHistoryTable({
|
||||||
|
...params,
|
||||||
|
page: this.queryParams.page,
|
||||||
|
page_size: this.queryParams.page_size,
|
||||||
|
})
|
||||||
|
hide()
|
||||||
|
const data = []
|
||||||
|
res.records.forEach((item) => {
|
||||||
|
item[0].type_id = this.handleTypeId(item[0].type_id)
|
||||||
|
item[1].forEach((subItem) => {
|
||||||
|
subItem.operate_type = this.handleOperateType(subItem.operate_type)
|
||||||
|
subItem.new = subItem.new || ''
|
||||||
|
subItem.old = subItem.old || ''
|
||||||
|
const tempObj = Object.assign(subItem, item[0])
|
||||||
|
data.push(tempObj)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$refs.xTable.exportData({
|
||||||
|
filename: this.$t('cmdb.history.ciChange'),
|
||||||
|
sheetName: 'Sheet1',
|
||||||
|
type: 'xlsx',
|
||||||
|
types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
|
||||||
|
isMerge: true,
|
||||||
|
isColgroup: true,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
@expandChange="handleExpandChange"
|
@expandChange="handleExpandChange"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@searchFormReset="searchFormReset"
|
@searchFormReset="searchFormReset"
|
||||||
|
@export="handleExport"
|
||||||
></search-form>
|
></search-form>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
ref="xTable"
|
ref="xTable"
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
<pager
|
<pager
|
||||||
:current-page.sync="queryParams.page"
|
:current-page.sync="queryParams.page"
|
||||||
:page-size.sync="queryParams.page_size"
|
:page-size.sync="queryParams.page_size"
|
||||||
:page-sizes="[50, 100, 200]"
|
:page-sizes="[50, 100, 200, 500]"
|
||||||
:total="total"
|
:total="total"
|
||||||
:isLoading="loading"
|
:isLoading="loading"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
|
@ -379,6 +380,58 @@ export default {
|
||||||
filterOption(input, option) {
|
filterOption(input, option) {
|
||||||
return option.componentOptions.children[0].text.indexOf(input) >= 0
|
return option.componentOptions.children[0].text.indexOf(input) >= 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async handleExport(params) {
|
||||||
|
const hide = this.$message.loading(this.$t('loading'), 0)
|
||||||
|
const res = await getRelationTable({
|
||||||
|
...params,
|
||||||
|
page: this.queryParams.page,
|
||||||
|
page_size: this.queryParams.page_size,
|
||||||
|
})
|
||||||
|
hide()
|
||||||
|
const data = []
|
||||||
|
res.records.forEach((item) => {
|
||||||
|
item[1].forEach((subItem) => {
|
||||||
|
subItem.operate_type = this.handleOperateType(subItem.operate_type)
|
||||||
|
subItem.relation_type_id = this.handleRelationType(subItem.relation_type_id)
|
||||||
|
subItem.first = res.cis[String(subItem.first_ci_id)]
|
||||||
|
subItem.second = res.cis[String(subItem.second_ci_id)]
|
||||||
|
|
||||||
|
const tempObj = Object.assign(subItem, item[0])
|
||||||
|
|
||||||
|
tempObj.changeDescription = this.getExportChangeDescription(tempObj)
|
||||||
|
|
||||||
|
data.push(tempObj)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$refs.xTable.exportData({
|
||||||
|
filename: this.$t('cmdb.history.relationChange'),
|
||||||
|
sheetName: 'Sheet1',
|
||||||
|
type: 'xlsx',
|
||||||
|
types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
|
||||||
|
isMerge: true,
|
||||||
|
isColgroup: true,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getExportChangeDescription(item) {
|
||||||
|
const first = item.first ? `${item.first.ci_type_alias}${item.first.unique_alias && item.first[item.first.unique] ? `(${item.first.unique_alias}:${item.first[item.first.unique]})` : ''}` : ''
|
||||||
|
const second = item.second ? `${item.second.ci_type_alias}${item.second.unique_alias && item.second[item.second.unique] ? `(${item.second.unique_alias}:${item.second[item.second.unique]})` : ''}` : ''
|
||||||
|
let center = ''
|
||||||
|
if (item.changeDescription === this.$t('cmdb.history.noUpdate')) {
|
||||||
|
center = item.relation_type_id
|
||||||
|
} else if (item.operate_type.includes(this.$t('update'))) {
|
||||||
|
center = item.changeArr.join(';')
|
||||||
|
} else if (item.operate_type.includes(this.$t('new'))) {
|
||||||
|
center = item.relation_type_id
|
||||||
|
} else if (item.operate_type.includes(this.$t('delete'))) {
|
||||||
|
center = item.relation_type_id
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${first || ''} => ${center || ''} => ${second || ''}`
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<a-select-option
|
<a-select-option
|
||||||
:value="Object.values(choice)[0]"
|
:value="Object.values(choice)[0]"
|
||||||
v-for="(choice, index) in attr.choice_value"
|
v-for="(choice, index) in attr.choice_value"
|
||||||
:key="'Search_' + attr.name + index"
|
:key="'Search_' + attr.name + Object.values(choice)[0] + index"
|
||||||
>
|
>
|
||||||
{{ Object.keys(choice)[0] }}
|
{{ Object.keys(choice)[0] }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
hideDisabledOptions: true,
|
hideDisabledOptions: true,
|
||||||
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
|
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
|
||||||
}"
|
}"
|
||||||
v-else-if="valueTypeMap[attr.value_type] == 'date' || valueTypeMap[attr.value_type] == 'datetime'"
|
v-else-if="attr.value_type === '3'"
|
||||||
/>
|
/>
|
||||||
<a-input v-model="queryParams[attr.name]" style="width: 100%" allowClear v-else />
|
<a-input v-model="queryParams[attr.name]" style="width: 100%" allowClear v-else />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
format="YYYY-MM-DD HH:mm"
|
format="YYYY-MM-DD HH:mm"
|
||||||
:placeholder="[$t('cmdb.history.startTime'), $t('cmdb.history.endTime')]"
|
:placeholder="[$t('cmdb.history.startTime'), $t('cmdb.history.endTime')]"
|
||||||
v-else-if="valueTypeMap[item.value_type] == 'date' || valueTypeMap[item.value_type] == 'datetime'"
|
v-else-if="attr.value_type === '3'"
|
||||||
:show-time="{
|
:show-time="{
|
||||||
hideDisabledOptions: true,
|
hideDisabledOptions: true,
|
||||||
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
|
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
|
||||||
|
@ -101,6 +101,9 @@
|
||||||
<a-button type="primary" html-type="submit" @click="handleSearch">
|
<a-button type="primary" html-type="submit" @click="handleSearch">
|
||||||
{{ $t('query') }}
|
{{ $t('query') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<a-button :style="{ marginLeft: '8px' }" @click="handleExport">
|
||||||
|
{{ $t('export') }}
|
||||||
|
</a-button>
|
||||||
<a-button :style="{ marginLeft: '8px' }" @click="handleReset">
|
<a-button :style="{ marginLeft: '8px' }" @click="handleReset">
|
||||||
{{ $t('reset') }}
|
{{ $t('reset') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
|
@ -155,6 +158,13 @@ export default {
|
||||||
this.$emit('search', this.queryParams)
|
this.$emit('search', this.queryParams)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleExport() {
|
||||||
|
const queryParams = {
|
||||||
|
...this.queryParams
|
||||||
|
}
|
||||||
|
this.$emit('export', queryParams)
|
||||||
|
},
|
||||||
|
|
||||||
handleReset() {
|
handleReset() {
|
||||||
this.queryParams = {
|
this.queryParams = {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
@expandChange="handleExpandChange"
|
@expandChange="handleExpandChange"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@searchFormReset="searchFormReset"
|
@searchFormReset="searchFormReset"
|
||||||
|
@export="handleExport"
|
||||||
></search-form>
|
></search-form>
|
||||||
<vxe-table
|
<vxe-table
|
||||||
ref="xTable"
|
ref="xTable"
|
||||||
|
@ -121,7 +122,7 @@ export default {
|
||||||
relationTypeList: null,
|
relationTypeList: null,
|
||||||
typeList: null,
|
typeList: null,
|
||||||
userList: [],
|
userList: [],
|
||||||
pageSizeOptions: ['50', '100', '200'],
|
pageSizeOptions: ['50', '100', '200', '500'],
|
||||||
isExpand: false,
|
isExpand: false,
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
|
@ -508,6 +509,36 @@ export default {
|
||||||
filterOption(input, option) {
|
filterOption(input, option) {
|
||||||
return option.componentOptions.children[0].text.indexOf(input) >= 0
|
return option.componentOptions.children[0].text.indexOf(input) >= 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async handleExport(params) {
|
||||||
|
const hide = this.$message.loading(this.$t('loading'), 0)
|
||||||
|
const res = await getCITypesTable({
|
||||||
|
...params,
|
||||||
|
page: this.queryParams.page,
|
||||||
|
page_size: this.queryParams.page_size,
|
||||||
|
})
|
||||||
|
hide()
|
||||||
|
|
||||||
|
res.result.forEach((item) => {
|
||||||
|
this.handleChangeDescription(item, item.operate_type)
|
||||||
|
item.operate_type = this.handleOperateType(item.operate_type)
|
||||||
|
item.type_id = this.handleTypeId(item.type_id)
|
||||||
|
item.uid = this.handleUID(item.uid)
|
||||||
|
if (item.operate_type.includes(this.$t('update'))) {
|
||||||
|
item.changeDescription = item.changeArr.join(';')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$refs.xTable.exportData({
|
||||||
|
filename: this.$t('cmdb.history.ciTypeChange'),
|
||||||
|
sheetName: 'Sheet1',
|
||||||
|
type: 'xlsx',
|
||||||
|
types: ['xlsx', 'csv', 'html', 'xml', 'txt'],
|
||||||
|
isMerge: true,
|
||||||
|
isColgroup: true,
|
||||||
|
data: res.result,
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue