diff --git a/cmdb-ui/src/modules/cmdb/api/history.js b/cmdb-ui/src/modules/cmdb/api/history.js
index ae8a099..dcadc65 100644
--- a/cmdb-ui/src/modules/cmdb/api/history.js
+++ b/cmdb-ui/src/modules/cmdb/api/history.js
@@ -54,3 +54,20 @@ export function getCiTriggersByCiId(ci_id, params) {
     params
   })
 }
+
+export function getCiRelatedTickets(params) {
+  return axios({
+    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',
+    isShowMessage: false
+  })
+}
diff --git a/cmdb-ui/src/modules/cmdb/assets/itsm_uninstalled.png b/cmdb-ui/src/modules/cmdb/assets/itsm_uninstalled.png
new file mode 100644
index 0000000..273716e
Binary files /dev/null and b/cmdb-ui/src/modules/cmdb/assets/itsm_uninstalled.png differ
diff --git a/cmdb-ui/src/modules/cmdb/lang/en.js b/cmdb-ui/src/modules/cmdb/lang/en.js
index 3d8e102..02d9aa2 100644
--- a/cmdb-ui/src/modules/cmdb/lang/en.js
+++ b/cmdb-ui/src/modules/cmdb/lang/en.js
@@ -402,7 +402,15 @@ const cmdb_en = {
         noModifications: 'No Modifications',
         attr: 'attribute',
         attrId: 'attribute id',
-        changeDescription: 'attribute id: {attr_id}, {before_days} day(s) in advance, Subject: {subject}\nContent: {body}\nNotify At: {notify_at}'
+        changeDescription: 'attribute id: {attr_id}, {before_days} day(s) in advance, Subject: {subject}\nContent: {body}\nNotify At: {notify_at}',
+        ticketStartTime: 'Start Time',
+        ticketCreator: 'Creator',
+        ticketTitle: 'Title',
+        ticketFinishTime: 'Finish Time',
+        ticketNodeName: 'Node Name',
+        itsmUninstalled: 'Please use it in combination with VE ITSM',
+        applyItsm: 'Free Apply ITSM',
+        ticketId: 'Ticket ID',
     },
     relation_type: {
         addRelationType: 'New',
diff --git a/cmdb-ui/src/modules/cmdb/lang/zh.js b/cmdb-ui/src/modules/cmdb/lang/zh.js
index 762bcbb..1c1d524 100644
--- a/cmdb-ui/src/modules/cmdb/lang/zh.js
+++ b/cmdb-ui/src/modules/cmdb/lang/zh.js
@@ -402,7 +402,15 @@ const cmdb_zh = {
         noModifications: '没有修改',
         attr: '属性名',
         attrId: '属性ID',
-        changeDescription: '属性ID:{attr_id},提前:{before_days}天,主题:{subject}\n内容:{body}\n通知时间:{notify_at}'
+        changeDescription: '属性ID:{attr_id},提前:{before_days}天,主题:{subject}\n内容:{body}\n通知时间:{notify_at}',
+        ticketStartTime: '工单发起时间',
+        ticketCreator: '发起人',
+        ticketTitle: '工单名称',
+        ticketFinishTime: '节点完成时间',
+        ticketNodeName: '节点名称',
+        itsmUninstalled: '请结合维易ITSM使用',
+        applyItsm: '免费申请',
+        ticketId: '工单ID',
     },
     relation_type: {
         addRelationType: '新增关系类型',
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelatedItsmTable.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelatedItsmTable.vue
new file mode 100644
index 0000000..4bb10f9
--- /dev/null
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailRelatedItsmTable.vue
@@ -0,0 +1,221 @@
+<template>
+  <div :style="{ height: '100%' }" v-if="itsmInstalled">
+    <vxe-table
+      ref="xTable"
+      show-overflow
+      show-header-overflow
+      resizable
+      border
+      size="small"
+      class="ops-stripe-table"
+      :span-method="mergeRowMethod"
+      :data="tableData"
+      v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
+    >
+      <template #empty>
+        <a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
+          <img slot="image" :src="require('@/assets/data_empty.png')" />
+          <span slot="description"> {{ $t('noData') }} </span>
+        </a-empty>
+      </template>
+      <vxe-column field="ticket.ticket_id" min-width="80" :title="$t('cmdb.history.ticketId')"> </vxe-column>
+      <vxe-column field="ticket.created_at" width="160" :title="$t('cmdb.history.ticketStartTime')"> </vxe-column>
+      <vxe-column field="ticket.creator_name" min-width="80" :title="$t('cmdb.history.ticketCreator')"> </vxe-column>
+      <vxe-column field="ticket.title" min-width="150" :title="$t('cmdb.history.ticketTitle')">
+        <template slot-scope="{ row }">
+          <a target="_blank" :href="row.ticket.url">{{ row.ticket.title }}</a>
+        </template>
+      </vxe-column>
+      <vxe-column field="ticket.node_finish_time" width="160" :title="$t('cmdb.history.ticketFinishTime')">
+      </vxe-column>
+      <vxe-column field="ticket.node_name" min-width="100" :title="$t('cmdb.history.ticketNodeName')"> </vxe-column>
+      <vxe-table-column
+        field="operate_type"
+        min-width="100"
+        :filters="[
+          { value: 0, label: $t('new') },
+          { value: 1, label: $t('delete') },
+          { value: 3, label: $t('update') },
+        ]"
+        :filter-method="filterOperateMethod"
+        :title="$t('operation')"
+      >
+        <template #default="{ row }">
+          {{ operateTypeMap[row.operate_type] }}
+        </template>
+      </vxe-table-column>
+      <vxe-table-column
+        field="attr_alias"
+        min-width="100"
+        :title="$t('cmdb.attribute')"
+        :filters="[]"
+        :filter-method="filterAttrMethod"
+      >
+      </vxe-table-column>
+      <vxe-table-column field="old" min-width="100" :title="$t('cmdb.history.old')"></vxe-table-column>
+      <vxe-table-column field="new" min-width="100" :title="$t('cmdb.history.new')"></vxe-table-column>
+    </vxe-table>
+    <div :style="{ textAlign: 'right' }" v-if="!ci_id">
+      <a-pagination
+        size="small"
+        show-size-changer
+        show-quick-jumper
+        :page-size-options="pageSizeOptions"
+        :current="tablePage.currentPage"
+        :total="tablePage.totalResult"
+        :show-total="(total, range) => $t('cmdb.history.totalItems', { total: total })"
+        :page-size="tablePage.pageSize"
+        :default-current="1"
+        @change="pageOrSizeChange"
+        @showSizeChange="pageOrSizeChange"
+      >
+      </a-pagination>
+    </div>
+  </div>
+  <a-empty
+    v-else
+    :image-style="{
+      height: '200px',
+    }"
+    :style="{ paddingTop: '10%' }"
+  >
+    <img slot="image" :src="require('@/modules/cmdb/assets/itsm_uninstalled.png')" />
+    <span slot="description"> {{ $t('cmdb.history.itsmUninstalled') }} </span>
+    <a-button href="https://veops.cn/apply" target="_blank" type="primary">
+      {{ $t('cmdb.history.applyItsm') }}
+    </a-button>
+  </a-empty>
+</template>
+
+<script>
+import { getCiRelatedTickets } from '../../../api/history'
+export default {
+  name: 'RelatedItsmTable',
+  props: {
+    ci_id: {
+      type: Number,
+      default: null,
+    },
+    ciHistory: {
+      type: Array,
+      default: () => [],
+    },
+    itsmInstalled: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  data() {
+    return {
+      tableData: [],
+      tablePage: {
+        currentPage: 1,
+        pageSize: 50,
+        totalResult: 0,
+      },
+      pageSizeOptions: ['50', '100', '200'],
+    }
+  },
+  computed: {
+    windowHeight() {
+      return this.$store.state.windowHeight
+    },
+    operateTypeMap() {
+      return {
+        0: this.$t('new'),
+        1: this.$t('delete'),
+        2: this.$t('update'),
+      }
+    },
+  },
+  mounted() {
+    this.updateTableData()
+  },
+  methods: {
+    updateTableData(currentPage = 1, pageSize = this.tablePage.pageSize) {
+      const params = { page: currentPage, page_size: pageSize, next_todo_ids: [] }
+      if (this.ci_id) {
+        const tableData = []
+        this.ciHistory.forEach((item) => {
+          if (item.ticket_id) {
+            params.next_todo_ids.push(item.ticket_id)
+            tableData.push(item)
+          }
+        })
+        if (params.next_todo_ids.length) {
+          getCiRelatedTickets(params)
+            .then((res) => {
+              const ticketId2Detail = {}
+              res.forEach((item) => {
+                ticketId2Detail[item.next_todo_id] = item
+              })
+              this.tableData = tableData.map((item) => {
+                return {
+                  ...item,
+                  ticket: ticketId2Detail[item.ticket_id],
+                }
+              })
+              this.updateAttrFilter()
+            })
+            .catch((e) => {})
+        }
+      } else {
+      }
+    },
+    updateAttrFilter() {
+      this.$nextTick(() => {
+        const $table = this.$refs.xTable
+        if ($table) {
+          const attrColumn = $table.getColumnByField('attr_alias')
+          if (attrColumn) {
+            $table.setFilter(
+              attrColumn,
+              this.tableData.map((item) => {
+                return { value: item.attr_alias, label: item.attr_alias }
+              })
+            )
+          }
+        }
+      })
+    },
+    mergeRowMethod({ row, _rowIndex, column, visibleData }) {
+      const fields = [
+        'ticket.ticket_id',
+        'ticket.created_at',
+        'ticket.creator_name',
+        'ticket.title',
+        'ticket.node_finish_time',
+        'ticket.node_name',
+      ]
+      const cellValue1 = row.ticket.ticket_id
+      const cellValue2 = row.ticket.node_name
+      if (cellValue1 && cellValue2 && fields.includes(column.property)) {
+        const prevRow = visibleData[_rowIndex - 1]
+        let nextRow = visibleData[_rowIndex + 1]
+        if (prevRow && prevRow.ticket.ticket_id === cellValue1 && prevRow.ticket.node_name === cellValue2) {
+          return { rowspan: 0, colspan: 0 }
+        } else {
+          let countRowspan = 1
+          while (nextRow && nextRow.ticket.ticket_id === cellValue1 && nextRow.ticket.node_name === cellValue2) {
+            nextRow = visibleData[++countRowspan + _rowIndex]
+          }
+          if (countRowspan > 1) {
+            return { rowspan: countRowspan, colspan: 1 }
+          }
+        }
+      }
+    },
+    pageOrSizeChange(currentPage, pageSize) {
+      this.updateTableData(currentPage, pageSize)
+    },
+    filterOperateMethod({ value, row, column }) {
+      return Number(row.operate_type) === Number(value)
+    },
+    filterAttrMethod({ value, row, column }) {
+      return row.attr_alias === value
+    },
+  },
+}
+</script>
+
+<style></style>
diff --git a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
index 11491e1..a2ff1b2 100644
--- a/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
+++ b/cmdb-ui/src/modules/cmdb/views/ci/modules/ciDetailTab.vue
@@ -41,9 +41,16 @@
             height="auto"
             :span-method="mergeRowMethod"
             border
+            resizable
             :scroll-y="{ enabled: false }"
             class="ops-stripe-table"
           >
+            <template #empty>
+              <a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
+                <img slot="image" :src="require('@/assets/data_empty.png')" />
+                <span slot="description"> {{ $t('noData') }} </span>
+              </a-empty>
+            </template>
             <vxe-table-column sortable field="created_at" :title="$t('created_at')"></vxe-table-column>
             <vxe-table-column
               field="username"
@@ -82,6 +89,12 @@
           <TriggerTable :ci_id="ci._id" />
         </div>
       </a-tab-pane>
+      <a-tab-pane key="tab_5">
+        <span slot="tab"><ops-icon type="itsm-association" />{{ $t('cmdb.ci.relITSM') }}</span>
+        <div :style="{ padding: '24px', height: '100%' }">
+          <RelatedItsmTable :ci_id="ci._id" :ciHistory="ciHistory" :itsmInstalled="itsmInstalled" />
+        </div>
+      </a-tab-pane>
     </a-tabs>
     <a-empty
       v-else
@@ -100,11 +113,12 @@
 import _ from 'lodash'
 import { Descriptions, DescriptionsItem } from 'element-ui'
 import { getCITypeGroupById, getCITypes } from '@/modules/cmdb/api/CIType'
-import { getCIHistory } from '@/modules/cmdb/api/history'
+import { getCIHistory, judgeItsmInstalled } from '@/modules/cmdb/api/history'
 import { getCIById } from '@/modules/cmdb/api/ci'
 import CiDetailAttrContent from './ciDetailAttrContent.vue'
 import CiDetailRelation from './ciDetailRelation.vue'
 import TriggerTable from '../../operation_history/modules/triggerTable.vue'
+import RelatedItsmTable from './ciDetailRelatedItsmTable.vue'
 export default {
   name: 'CiDetailTab',
   components: {
@@ -113,6 +127,7 @@ export default {
     CiDetailAttrContent,
     CiDetailRelation,
     TriggerTable,
+    RelatedItsmTable,
   },
   props: {
     typeId: {
@@ -134,6 +149,7 @@ export default {
       ciId: null,
       ci_types: [],
       hasPermission: true,
+      itsmInstalled: true,
     }
   },
   computed: {
@@ -179,6 +195,7 @@ export default {
       }
       this.ciId = ciId
       await this.getCI()
+      await this.judgeItsmInstalled()
       if (this.hasPermission) {
         this.getAttributes()
         this.getCIHistory()
@@ -203,7 +220,15 @@ export default {
             this.hasPermission = false
           }
         })
-        .catch((e) => {})
+        .catch((e) => {
+          if (e.response.status === 404) {
+            this.itsmInstalled = false
+          }
+        })
+    },
+    async judgeItsmInstalled() {
+      await judgeItsmInstalled()
+        .catch((e) => { this.itsmInstalled = false })
     },
 
     getCIHistory() {
diff --git a/cmdb-ui/src/modules/cmdb/views/operation_history/modules/triggerTable.vue b/cmdb-ui/src/modules/cmdb/views/operation_history/modules/triggerTable.vue
index 2d95c29..b084d4e 100644
--- a/cmdb-ui/src/modules/cmdb/views/operation_history/modules/triggerTable.vue
+++ b/cmdb-ui/src/modules/cmdb/views/operation_history/modules/triggerTable.vue
@@ -9,6 +9,12 @@
       :data="tableData"
       v-bind="ci_id ? { height: 'auto' } : { height: `${windowHeight - 225}px` }"
     >
+      <template #empty>
+        <a-empty :image-style="{ height: '100px' }" :style="{ paddingTop: '10%' }">
+          <img slot="image" :src="require('@/assets/data_empty.png')" />
+          <span slot="description"> {{ $t('noData') }} </span>
+        </a-empty>
+      </template>
       <vxe-column field="trigger_name" :title="$t('cmdb.history.triggerName')"> </vxe-column>
       <vxe-column field="type" :title="$t('type')">
         <template #default="{ row }">