summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchenjinsong <[email protected]>2021-04-08 20:28:54 +0800
committerchenjinsong <[email protected]>2021-04-08 20:28:54 +0800
commit527c189ced8f569a96045689e12c79ac6f53b143 (patch)
treee3b523726a833287b2bf7f9b227548e2ea0269dc
parentf259ed27507d30ebb0d345cac732f3c64ec2bc8a (diff)
perf: settings列表改版(细节未调整)codeCheck
-rw-r--r--.idea/inspectionProfiles/Project_Default.xml6
-rw-r--r--.idea/misc.xml3
-rw-r--r--nezha-fronted/package.json4
-rw-r--r--nezha-fronted/src/assets/css/common/tableCommon.scss24
-rw-r--r--nezha-fronted/src/assets/css/theme.scss2
-rw-r--r--nezha-fronted/src/assets/stylus/main.scss86
-rw-r--r--nezha-fronted/src/components/common/bottomBox/bottomBox.vue46
-rw-r--r--nezha-fronted/src/components/common/bottomBox/tabs/operationLogTab.vue206
-rw-r--r--nezha-fronted/src/components/common/bottomBox/tabs/terminalLogTab.vue291
-rw-r--r--nezha-fronted/src/components/common/exportXLSX.vue93
-rw-r--r--nezha-fronted/src/components/common/header.vue2
-rw-r--r--nezha-fronted/src/components/common/js/constants.js10
-rw-r--r--nezha-fronted/src/components/common/js/tools.js8
-rw-r--r--nezha-fronted/src/components/common/language/cn.js7
-rw-r--r--nezha-fronted/src/components/common/language/en.js17
-rw-r--r--nezha-fronted/src/components/common/mixin/table.js47
-rw-r--r--nezha-fronted/src/components/common/popBox/selectAssetMetaGroup.vue152
-rw-r--r--nezha-fronted/src/components/common/rightBox/accountBox.vue22
-rw-r--r--nezha-fronted/src/components/common/table/nzDataList.vue16
-rw-r--r--nezha-fronted/src/components/layout/header.vue2
-rw-r--r--nezha-fronted/src/components/page/config/account2.vue152
-rw-r--r--nezha-fronted/src/components/page/config/assetMeta.vue384
-rw-r--r--nezha-fronted/src/components/page/config/assetState.vue415
-rw-r--r--nezha-fronted/src/components/page/config/assetType.vue432
-rw-r--r--nezha-fronted/src/components/page/config/dc.vue378
-rw-r--r--nezha-fronted/src/components/page/config/exprTemp.vue367
-rw-r--r--nezha-fronted/src/components/page/config/mib.vue387
-rw-r--r--nezha-fronted/src/components/page/config/model.vue348
-rw-r--r--nezha-fronted/src/components/page/config/operationLog.vue208
-rw-r--r--nezha-fronted/src/components/page/config/operationlog.vue255
-rw-r--r--nezha-fronted/src/components/page/config/promServer.vue356
-rw-r--r--nezha-fronted/src/components/page/config/roles.vue276
-rw-r--r--nezha-fronted/src/components/page/config/terminalLog.vue292
-rw-r--r--nezha-fronted/src/components/page/config/terminallog.vue387
-rw-r--r--nezha-fronted/src/main.js34
-rw-r--r--nezha-fronted/src/router/index.js4
36 files changed, 2562 insertions, 3157 deletions
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 000000000..03d9549ea
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+ <profile version="1.0">
+ <option name="myName" value="Project Default" />
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
+ </profile>
+</component> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 28a804d89..1c24890b2 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,4 +3,7 @@
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
+ <component name="WebPackConfiguration">
+ <option name="mode" value="DISABLED" />
+ </component>
</project> \ No newline at end of file
diff --git a/nezha-fronted/package.json b/nezha-fronted/package.json
index e97e234c7..56912b3d8 100644
--- a/nezha-fronted/package.json
+++ b/nezha-fronted/package.json
@@ -5,7 +5,7 @@
"author": "",
"private": true,
"scripts": {
- "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+ "dev": "node --max-old-space-size=6000 ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js",
"lint": "eslint --fix --ext .js,.vue src"
@@ -27,7 +27,7 @@
"element-ui": "^2.13.0",
"file-saver": "^2.0.2",
"leaflet": "^1.7.1",
- "node-sass": "^4.13.1",
+ "node-sass": "^4.14.1",
"pl-table": "^2.5.8",
"quill": "^1.3.7",
"vis": "^4.21.0-EOL",
diff --git a/nezha-fronted/src/assets/css/common/tableCommon.scss b/nezha-fronted/src/assets/css/common/tableCommon.scss
index ffb150403..0016d7fe4 100644
--- a/nezha-fronted/src/assets/css/common/tableCommon.scss
+++ b/nezha-fronted/src/assets/css/common/tableCommon.scss
@@ -24,18 +24,32 @@
display: flex;
align-items : center;
position: relative;
- flex-direction: row-reverse;
- padding: 14px 20px 14px 0;
+ justify-content: space-between;
+ padding: 14px 20px;
.top-tool-main-right {
display: flex;
}
+ .top-tool-main-left {
+ display: flex;
+ }
+ .top-tool-btn-group {
+ display: flex;
+
+ .top-tool-btn:first-of-type {
+ border-radius: $--button-border-radius 0 0 $--button-border-radius;
+ }
+ .top-tool-btn:last-of-type {
+ border-radius: 0 $--button-border-radius $--button-border-radius 0;
+ border-left: none;
+ }
+ }
.top-tool-btn {
height: 32px;
width: 36px;
border: 1px solid #DEDEDE;
outline: none;
- border-radius: 2px;
+ border-radius: $--button-border-radius;
background-color: $--button-gray-background-color;
transition: background-color linear .1s;
@@ -117,7 +131,7 @@
.table-operation-item {
display: flex;
height: 22px;
- border-radius: 2px;
+ border-radius: $--button-border-radius;
outline: none;
}
>.table-operation-item {
@@ -126,7 +140,7 @@
width: 40px;
margin-right: 10px;
border: none;
- border-radius: 2px;
+ border-radius: $--button-border-radius;
background-color: $--button-primary-background-color;
opacity: .8;
cursor: pointer;
diff --git a/nezha-fronted/src/assets/css/theme.scss b/nezha-fronted/src/assets/css/theme.scss
index 0676b6082..02902d698 100644
--- a/nezha-fronted/src/assets/css/theme.scss
+++ b/nezha-fronted/src/assets/css/theme.scss
@@ -4,6 +4,8 @@
$--theme-color: var(--theme-color); // 主题色
/* 按钮 */
+$--button-border-radius: 2px; // 按钮圆角
+
$--button-primary-color: #FFF; // 普通按钮字色
$--button-primary-background-color: var(--theme-color); // 普通按钮背景色
$--button-hover-tint-percent: 20%; // 非灰色按钮在鼠标hover时背景色变浅的幅度
diff --git a/nezha-fronted/src/assets/stylus/main.scss b/nezha-fronted/src/assets/stylus/main.scss
index e90d99288..00f21e164 100644
--- a/nezha-fronted/src/assets/stylus/main.scss
+++ b/nezha-fronted/src/assets/stylus/main.scss
@@ -747,6 +747,7 @@ li{
border-top: 1px solid #DCDFE6;
border-bottom: 1px solid #E4E7ED;
margin: 0 -6px;
+ padding-right: 80px;
background-color: $content-right-background-color;
margin-bottom: 10px;
}
@@ -756,6 +757,9 @@ li{
.sub-top-tools .top-tool-search {
width: 260px;
margin: -1px 0 0 0;
+ .select_input input {
+ background-color: white;
+ }
}
.sub-top-tools .top-tool-btn-txt .nz-icon{
display: inline-block;
@@ -2098,88 +2102,6 @@ li{
}
-/*export相关*/
-.export-dropdown-btn {
- position: relative;
-}
-.endpoint-query-dropdown {
- position: absolute;
- right: 0;
- top: 31px;
-}
-.export-dropdown {
- width: 90px;
- right: 0;
- left: unset !important;
- top: 27px;
-}
-.endpoint-query-dropdown::after, .export-dropdown::after {
- content: '';
- display: block;
- width:0;
- height:0;
- overflow: hidden;
- font-size: 0;
- line-height: 0;
- border: 5px;
- border-style: dashed dashed solid dashed;
- border-color: transparent transparent #fff transparent;
- position: absolute;
- right: 3px;
- bottom: 0;
-
-}
-.export-dropdown::after {
- transform: translate(-50%, -54px);
-}
-.endpoint-query-dropdown::after {
- transform: translate(-50%, -45px);
-}
-/*.dropdownBtn .el-dropdown__caret-button{
- top:0px !important;
- left: -1px;
-}*/
-.export-xlsx .el-dialog__body{
- padding: 10px 20px 20px 20px;
-}
-.export-xlsx .el-button:focus, .export-xlsx .el-button:hover {
- color: unset;
- border-color: unset;
- background-color:unset;
-}
-.dropdownBtn .el-button--primary{
- top:2px;
- padding: 0 8px;
- background-image: linear-gradient(180deg, #fff 0%, #E0E0E0 100%);
- border: 0px;
- color: #666;
- -webkit-box-shadow: 0 0 1px 1px rgba(162,162,162,0.5);
- box-shadow: 0 0 1px 1px rgba(162,162,162,0.5);
- letter-spacing: 0;
- background-color: unset;
-}
-.dropdownBtn .el-button--primary:hover{
- background-image: linear-gradient(180deg, #F0F0F0 0%, #D8D8D8 99%) !important;
-}
-.dropdownBtn .el-button--mini{
- font-size: 12px;
- height: 24px;
-}
-.dropdownBtn .el-button--mini:first-of-type {
- right: 3px;
-}
-.el-dropdown .el-button-group{
- display: block;
- position: relative;
- top:-2px;
-}
-.export-xlsx .el-dropdown .el-dropdown__caret-button {
- padding-left: 5px;
- padding-right: 5px;
- border-left: none;
- top:0px;
- left: -1px;
-}
.footer:before{
/*content: '';*/
/*clear:both;*/
diff --git a/nezha-fronted/src/components/common/bottomBox/bottomBox.vue b/nezha-fronted/src/components/common/bottomBox/bottomBox.vue
index f73d74ad8..b9dd894b0 100644
--- a/nezha-fronted/src/components/common/bottomBox/bottomBox.vue
+++ b/nezha-fronted/src/components/common/bottomBox/bottomBox.vue
@@ -18,24 +18,27 @@
<!------TAB区------>
<!--机柜-->
- <cabinet-tab v-if="from === $CONSTANTS.fromRoute.dc && targetTab === 'cabinet'" v-show="subResizeShow" :obj="obj" @changeTab="changeTab"></cabinet-tab>
+ <cabinet-tab v-if="from === fromRoute.dc && targetTab === 'cabinet'" v-show="subResizeShow" :obj="obj" @changeTab="changeTab"></cabinet-tab>
<!--告警信息-->
- <alert-message-tab v-if="((from === $CONSTANTS.fromRoute.rule || from === $CONSTANTS.fromRoute.asset || from === $CONSTANTS.fromRoute.endpoint) && targetTab === 'alertMessage')" v-show="subResizeShow" :from="from" :obj="obj" @changeTab="changeTab"></alert-message-tab>
+ <alert-message-tab v-if="((from === fromRoute.rule || from === fromRoute.asset || from === fromRoute.endpoint) && targetTab === 'alertMessage')" v-show="subResizeShow" :from="from" :obj="obj" @changeTab="changeTab"></alert-message-tab>
<!--asset页的endpoint列表-->
- <endpoint-tab v-if="from === $CONSTANTS.fromRoute.asset && targetTab === $CONSTANTS.fromRoute.endpoint" v-show="subResizeShow" :from="from" :obj="obj" @changeTab="changeTab"></endpoint-tab>
+ <endpoint-tab v-if="from === fromRoute.asset && targetTab === fromRoute.endpoint" v-show="subResizeShow" :from="from" :obj="obj" @changeTab="changeTab"></endpoint-tab>
<!--endpoint-query-->
- <endpoint-query-tab v-if="(from === $CONSTANTS.fromRoute.endpoint && targetTab === 'endpointQuery')" v-show="subResizeShow" ref="endpointQuery" :from="from" :obj="obj" @changeTab="changeTab"></endpoint-query-tab>
+ <endpoint-query-tab v-if="(from === fromRoute.endpoint && targetTab === 'endpointQuery')" v-show="subResizeShow" ref="endpointQuery" :from="from" :obj="obj" @changeTab="changeTab"></endpoint-query-tab>
<!-- model-panel/asset-detail/project-overview的panel-->
- <panel-tab v-if="(from === $CONSTANTS.fromRoute.model || from === $CONSTANTS.fromRoute.asset || from === $CONSTANTS.fromRoute.project || from === $CONSTANTS.fromRoute.rule || from === $CONSTANTS.fromRoute.endpoint) && targetTab === 'panel'" v-show="subResizeShow" ref="panelTab" :from="from" :obj="obj"
+ <panel-tab v-if="(from === fromRoute.model || from === fromRoute.asset || from === fromRoute.project || from === fromRoute.rule || from === fromRoute.endpoint) && targetTab === 'panel'" v-show="subResizeShow" ref="panelTab" :from="from" :obj="obj"
@changeTab="changeTab" :targetTab.sync="targetTab" :detail="detail"></panel-tab>
<!--terminal-log的记录和回放-->
- <terminal-log-cmd-tab v-if="from === $CONSTANTS.fromRoute.terminalLog && targetTab === 'cmd'" ref="reminalLogCMDTab" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-cmd-tab>
- <terminal-log-record-tab v-if="from === $CONSTANTS.fromRoute.terminalLog && targetTab === 'record'" ref="reminalLogRecordTab" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-record-tab>
+ <terminal-log-cmd-tab v-if="from === fromRoute.terminalLog && targetTab === 'cmd'" ref="reminalLogCMDTab" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-cmd-tab>
+ <terminal-log-record-tab v-if="from === fromRoute.terminalLog && targetTab === 'record'" ref="reminalLogRecordTab" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-record-tab>
- <terminal-log-monitor-tab v-if="from === $CONSTANTS.fromRoute.terminalLog && targetTab === 'monitor'" ref="reminalLogRecordTab" :from="from" :obj="obj" @changeTab="changeTab" @exit="closeSubList"></terminal-log-monitor-tab>
+ <terminal-log-monitor-tab v-if="from === fromRoute.terminalLog && targetTab === 'monitor'" ref="reminalLogRecordTab" :from="from" :obj="obj" @changeTab="changeTab" @exit="closeSubList"></terminal-log-monitor-tab>
+ <!--user列表的两个日志-->
+ <operation-log-tab v-if="from === fromRoute.account && targetTab === 'operationLogTab'" :from="from" :obj="obj" @changeTab="changeTab"></operation-log-tab>
+ <terminal-log-tab v-if="from === fromRoute.account && targetTab === 'terminalLogTab'" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-tab>
</div>
</div>
</template>
@@ -49,18 +52,23 @@ import panelTab from './tabs/panelTab'
import terminalLogRecordTab from './tabs/terminalLogRecordTab'
import terminalLogMonitorTab from './tabs/terminalLogMonitorTab'
import terminalLogCMDTab from './tabs/terminalLogCMDTab'
+import operationLogTab from './tabs/operationLogTab'
+import terminalLogTab from './tabs/terminalLogTab'
+import { fromRoute } from '@/components/common/js/constants'
export default {
name: 'bottomBox',
components: {
- 'cabinet-tab': cabinetTab,
- 'alert-message-tab': alertMessageTab,
- 'endpoint-query-tab': endpointQueryTab,
- 'endpoint-tab': endpointTab,
- 'panel-tab': panelTab,
+ cabinetTab,
+ alertMessageTab,
+ endpointQueryTab,
+ endpointTab,
+ panelTab,
terminalLogRecordTab,
- 'terminal-log-cmd-tab': terminalLogCMDTab,
- terminalLogMonitorTab
+ terminalLogMonitorTab,
+ operationLogTab,
+ terminalLogTab,
+ 'terminal-log-cmd-tab': terminalLogCMDTab
},
props: {
isFullScreen: Boolean, // 是否全屏
@@ -75,7 +83,9 @@ export default {
assetDetail: Object // endpoint页的asset详情
},
data () {
- return {}
+ return {
+ fromRoute: fromRoute
+ }
},
methods: {
exitFullScreen () {
@@ -97,9 +107,9 @@ export default {
this.$emit('update:targetTab', tab)
},
afterResize () {
- if (this.from === this.$CONSTANTS.fromRoute.endpoint && this.targetTab === 'endpointQuery') {
+ if (this.from === this.fromRoute.endpoint && this.targetTab === 'endpointQuery') {
this.$refs.endpointQuery.tableReload()
- } else if (this.from === this.$CONSTANTS.fromRoute.terminalLog && this.targetTab === 'record') {
+ } else if (this.from === this.fromRoute.terminalLog && this.targetTab === 'record') {
setTimeout(() => {
this.$refs.reminalLogRecordTab.consoleResize()
}, 600)
diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/operationLogTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/operationLogTab.vue
new file mode 100644
index 000000000..ea10ddf5b
--- /dev/null
+++ b/nezha-fronted/src/components/common/bottomBox/tabs/operationLogTab.vue
@@ -0,0 +1,206 @@
+<template>
+ <div style="height: 100%">
+ <div class="sub-top-tools">
+ <div class="sub-list-tabs">
+ <div class="sub-list-tab-title">{{obj.id}}</div><div
+ id="endpoint-tab-change-panel" class="sub-list-tab sub-list-tab-active">{{$t("config.operationlog.operationlog")}}</div><div
+ id="endpoint-tab-change-alertmsg" class="sub-list-tab" @click="changeTab('terminalLogTab')">{{$t("config.terminallog.terminallog")}}</div>
+ </div>
+ <div class="top-tool-right">
+ <div class="top-tool-search">
+ <search-input :searchMsg="searchMsg" position="endpoint-bottom" @search="search"></search-input>
+ </div>
+ </div>
+ </div>
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <span v-if="item.prop === 'time'">
+ {{scope.row[item.prop]}} ms
+ </span>
+ <span v-else-if="item.prop === 'username'">{{formatUsername(scope.row)}}</span>
+ <span v-else-if="item.prop === 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+</template>
+
+<script>
+import tableMixin from '@/components/common/mixin/table'
+export default {
+ name: 'operationLogTab',
+ mixins: [tableMixin],
+ data () {
+ return {
+ tableId: 'operationLogTable', // 需要分页的table的id,用于记录每页数量
+ tableTitle: [
+ {
+ label: this.$t('config.operationlog.id'),
+ prop: 'id',
+ show: true,
+ width: 80
+ }, {
+ label: this.$t('config.operationlog.username'),
+ prop: 'username',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.ip'),
+ prop: 'ip',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.operation'),
+ prop: 'operation',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.type'),
+ prop: 'type',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.state'),
+ prop: 'state',
+ show: true
+ },
+ // {
+ // label: this.$t('config.operationlog.userId'),
+ // prop: 'userId',
+ // show: false,
+ // },
+ {
+ label: this.$t('config.operationlog.operaId'),
+ prop: 'operaId',
+ show: false
+ },
+ {
+ label: this.$t('config.operationlog.createDate'),
+ prop: 'createDate',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.time'),
+ prop: 'time',
+ show: false
+ },
+ {
+ label: this.$t('config.operationlog.params'),
+ prop: 'params',
+ show: false
+ },
+ {
+ label: this.$t('config.operationlog.response'),
+ prop: 'response',
+ show: false
+ }
+ ],
+ searchMsg: { // 给搜索框子组件传递的信息
+ zheze_none: true,
+ searchLabelList: [
+ {
+ id: 11,
+ name: this.$t('config.operationlog.type'),
+ type: 'input',
+ label: 'type',
+ disabled: false
+ }, {
+ id: 12,
+ name: this.$t('config.operationlog.username'),
+ type: 'input',
+ label: 'username',
+ disabled: false
+ }, {
+ id: 13,
+ name: this.$t('config.operationlog.operation'),
+ type: 'selectString',
+ label: 'operation',
+ disabled: false
+ }
+ ]
+ }
+ }
+ },
+ props: {
+ obj: Object // 关联的实体对象
+ },
+ methods: {
+ // 切换tab
+ changeTab (tab) {
+ this.$emit('changeTab', tab)
+ },
+ messageStyle (e) {
+ if (e.column.label === this.$t('config.operationlog.state')) {
+ if (e.row.state === 'success') {
+ return 'success'
+ } else {
+ return 'danger'
+ }
+ }
+ return ''
+ },
+ getTableData () {
+ this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
+ this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
+ this.tools.loading = true
+ this.$get('sys/log/list', this.searchLabel).then(response => {
+ this.tools.loading = false
+ if (response.code === 200) {
+ this.tableData = response.data.list
+ this.pageObj.total = response.data.total
+ if (!this.scrollbarWrap) {
+ this.$nextTick(() => {
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
+ this.toTopBtnHandler(this.scrollbarWrap)
+ })
+ }
+ }
+ })
+ },
+ formatUsername (row) {
+ if (row.username) {
+ return row.username
+ } else if (row.operation === 'login' && !row.username) { // 如果是登录 且登录失败
+ return JSON.parse(row.params).username
+ } else {
+ return '-'
+ }
+ }
+ }
+}
+</script>
diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogTab.vue
new file mode 100644
index 000000000..065848041
--- /dev/null
+++ b/nezha-fronted/src/components/common/bottomBox/tabs/terminalLogTab.vue
@@ -0,0 +1,291 @@
+<template>
+ <div style="height: 100%">
+ <div class="sub-top-tools">
+ <div class="sub-list-tabs">
+ <div class="sub-list-tab-title">{{obj.id}}</div><div
+ id="endpoint-tab-change-panel" class="sub-list-tab" @click="changeTab('operationLogTab')">{{$t("config.operationlog.operationlog")}}</div><div
+ id="endpoint-tab-change-alertmsg" class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.terminallog")}}</div>
+ </div>
+ <div class="top-tool-right">
+ <div class="top-tool-search">
+ <search-input :searchMsg="searchMsg" position="endpoint-bottom" @search="search"></search-input>
+ </div>
+ </div>
+ </div>
+ <el-table
+ id="terminal-log-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <span v-if="item.prop === 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <template v-else-if="item.prop === 'status'">
+ <span>{{getStatusText(scope.row.status)}}</span>
+ </template>
+ <template v-else-if="item.prop === 'uuid'">
+ <span>{{scope.row.uuid.substring(0, 8).toUpperCase()}}</span>
+ </template>
+ <template v-else-if="item.prop === 'remote'">
+ <span>{{getRemoteText(scope.row)}}</span>
+ </template>
+ <template v-else-if="item.prop === 'duration'">
+ <el-tooltip :disabled="!scope.row.status" effect="light" placement="right">
+ <div slot="content">
+ {{$t('config.terminallog.endTime')}}<br/>
+ {{scope.row.endTime}}
+ </div>
+ <span>{{getDuration(scope.row)}}</span>
+ </el-tooltip>
+ </template>
+ <template v-else-if="item.prop === 'authType'">
+ <span v-if="scope.row.authType == 1">{{$t('config.terminallog.password')}}</span>
+ <span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
+ </template>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <template v-if="scope.row.status == 0">
+ <button :title="$t('config.terminallog.monitor.monitor')" class="table-operation-item" @click="$refs.dataList.showBottomBox('monitor', scope.row)"><i class="nz-icon nz-icon-JC"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['shutdown', scope.row]"><i class="nz-icon nz-icon-ZD"></i><span class="operation-dropdown-text">Kill</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </template>
+ <template v-else>
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('cmd', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['record', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('config.terminallog.record.record')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </template>
+ </div>
+ </el-table-column>
+ </el-table>
+ </div>
+</template>
+
+<script>
+import tableMixin from '@/components/common/mixin/table'
+import { terminalLog } from '@/components/common/js/constants'
+import { calcDurationByStringTimeB } from '@/components/common/js/tools'
+
+export default {
+ name: 'terminalLogTab',
+ mixins: [tableMixin],
+ data () {
+ return {
+ tableId: 'terminalLogTable', // 需要分页的table的id,用于记录每页数量
+
+ tableTitle: [
+ {
+ label: this.$t('config.terminallog.id'),
+ prop: 'id',
+ show: true,
+ width: 80
+ }, {
+ label: 'Session ID',
+ prop: 'uuid',
+ show: true
+ }, {
+ label: 'Username',
+ prop: 'username',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.source'),
+ prop: 'remoteAddr',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.remote'),
+ prop: 'remote',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.protocol'),
+ prop: 'protocol',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.startTime'),
+ prop: 'startTime',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.duration'),
+ prop: 'duration',
+ show: true
+ },
+ {
+ label: 'AuthType',
+ prop: 'authType',
+ show: false
+ },
+ {
+ label: this.$t('config.terminallog.status'), // killusername鼠标悬停形式
+ prop: 'status',
+ show: true,
+ width: 100
+ }
+ ],
+ searchMsg: { // 给搜索框子组件传递的信息
+ zheze_none: true,
+ searchLabelList: [
+ {
+ id: 11,
+ name: this.$t('config.terminallog.host'),
+ type: 'input',
+ label: 'host',
+ disabled: false
+ }, {
+ id: 12,
+ name: this.$t('config.terminallog.user'),
+ type: 'input',
+ label: 'username',
+ disabled: false
+ }
+ ]
+ },
+ nowTime: ''
+ }
+ },
+ computed: {
+ getStatusText () {
+ return function (status) {
+ return terminalLog.status[status]
+ }
+ },
+ getRemoteText () {
+ return function (record) {
+ return `${record.loginUser}@${record.host}:${record.port}`
+ }
+ },
+ getDuration () {
+ return function (record) {
+ if (record.endTime) {
+ return calcDurationByStringTimeB(record.startTime, record.endTime)
+ }
+ return calcDurationByStringTimeB(record.startTime, this.nowTime)
+ }
+ }
+ },
+ props: {
+ obj: Object // 关联的实体对象
+ },
+ methods: {
+ // 切换tab
+ changeTab (tab) {
+ this.$emit('changeTab', tab)
+ },
+ tableOperation ([command, row]) {
+ switch (command) {
+ case 'shutdown': {
+ this.shutdown(row)
+ break
+ }
+ default:
+ this.$refs.dataList.showBottomBox(command, row)
+ break
+ }
+ },
+ getTableData () {
+ const params = {
+ ...this.searchLabel,
+ pageNo: this.pageObj.pageNo,
+ pageSize: this.pageObj.pageSize
+ }
+ this.$get('terminal/session', params).then(response => {
+ this.tools.loading = false
+ if (response.code === 200) {
+ this.tableData = response.data.list
+ this.nowTime = this.utcTimeToTimezoneStr(response.time)
+ this.pageObj.total = response.data.total
+ if (!this.scrollbarWrap) {
+ this.$nextTick(() => {
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
+ this.toTopBtnHandler(this.scrollbarWrap)
+ })
+ }
+ }
+ })
+ },
+ shutdown (record) {
+ this.$confirm(this.$t('tip.killTerm'), {
+ confirmButtonText: this.$t('tip.yes'),
+ cancelButtonText: this.$t('tip.no'),
+ type: 'warning'
+ }).then(() => {
+ this.$put('/terminal/kill', { uuid: record.uuid }).then(res => {
+ if (res.code === 200) {
+ this.$message.success(this.$t('config.terminallog.success'))
+ this.bottomBox.showSubList = false
+ this.getTableData()
+ } else {
+ this.$message.error(this.$t('config.terminallog.killErrorTip'))
+ }
+ })
+ })
+ },
+ messageStyle (e) {
+ if (e.column.label == this.$t('config.terminallog.status')) {
+ if (e.row.status == '0') {
+ return 'success'
+ } else if (e.row.status == '1') {
+ return 'warning'
+ } else if (e.row.status == '2') {
+ return 'suspended'
+ } else if (e.row.status == '3') {
+ return 'danger'
+ } else if (e.row.status == '4') {
+ return 'danger'
+ }
+ }
+ return ''
+ }
+ }
+}
+</script>
diff --git a/nezha-fronted/src/components/common/exportXLSX.vue b/nezha-fronted/src/components/common/exportXLSX.vue
index 2a54387a7..48ff11154 100644
--- a/nezha-fronted/src/components/common/exportXLSX.vue
+++ b/nezha-fronted/src/components/common/exportXLSX.vue
@@ -1,10 +1,11 @@
<template>
<div class="export-xlsx">
- <div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light">
- <slot name="optionZone"></slot><button @mouseenter="exportMenuHandler(true)" @mouseleave="exportMenuHandler(false)" class="nz-btn nz-btn-size-normal nz-btn-style-light export-dropdown-btn" id="browser-go" style="padding: 0" v-has="[permissions.import, permissions.export]">
- <i class="nz-icon nz-icon-arrow-down"></i>
+ <div class="top-tool-btn-group">
+ <slot name="optionZone"></slot>
+ <button id="browser-go" v-has="[permissions.import, permissions.export]" class="top-tool-btn" style="position: relative" @mouseenter="exportMenuHandler(true)" @mouseleave="exportMenuHandler(false)">
+ <i class="nz-icon nz-icon-arrow-down" style="font-size: 12px;"></i>
<transition name="el-zoom-in-top">
- <ul class="el-dropdown-menu el-popper el-dropdown-menu--mini export-dropdown" style="z-index: 101" v-show="exportShow">
+ <ul v-show="exportShow" class="el-dropdown-menu el-popper el-dropdown-menu--mini export-dropdown">
<li @click="showImportBox(1)" class="el-dropdown-menu__item dropdown-content" v-has="permissions.import" :id="id+'-xlsx-import'"><i class="nz-icon nz-icon-upload"></i>{{$t('overall.importExcel')}}</li>
<li @click="showImportBox(2)" class="el-dropdown-menu__item dropdown-content" v-has="permissions.export" :id="id+'-xlsx-export'"><i class="nz-icon nz-icon-download1"></i>{{$t('overall.exportExcel')}}</li>
</ul>
@@ -26,13 +27,13 @@
</div>
<div slot="footer" class="footer">
<div class="el-message-box__btns" style="text-align: right;">
- <button @click="downloadTemplate" class="el-button el-button--default el-button--small" :id="id+'-xlsx-import-template'">
+ <button :id="id+'-xlsx-import-template'" class="el-button el-button--default el-button--small" @click="downloadTemplate">
<span>{{$t('overall.template')}}</span>
</button>
- <button @click="importExcel" class="nz-btn el-button el-button--default el-button--small" :disabled="prevent_opt.import" :class="{'nz-btn-disabled':prevent_opt.import}" :id="id+'-xlsx-import-add'">
+ <button :id="id+'-xlsx-import-add'" :class="{'nz-btn-disabled':prevent_opt.import}" :disabled="prevent_opt.import" class="nz-btn el-button el-button--default el-button--small" @click="importExcel">
<span>{{$t('overall.importExcel')}}</span>
</button>
- <button @click="closeDialog" class="el-button el-button--default el-button--small" :id="id+'-xlsx-import-esc'">
+ <button :id="id+'-xlsx-import-esc'" class="el-button el-button--default el-button--small" @click="closeDialog">
<span>{{$t('overall.cancel')}}</span>
</button>
</div>
@@ -366,4 +367,82 @@ export default {
.import-result-item .line-num{
width: 55px;
}
+
+ .export-dropdown-btn {
+ position: relative;
+ }
+ .endpoint-query-dropdown {
+ position: absolute;
+ right: 0;
+ top: 31px;
+ }
+ .export-dropdown {
+ width: 90px;
+ right: 0;
+ left: unset !important;
+ top: 35px;
+ }
+ .endpoint-query-dropdown::after, .export-dropdown::after {
+ content: '';
+ display: block;
+ width:0;
+ height:0;
+ overflow: hidden;
+ font-size: 0;
+ line-height: 0;
+ border: 5px;
+ border-style: dashed dashed solid dashed;
+ border-color: transparent transparent #fff transparent;
+ position: absolute;
+ right: 3px;
+ bottom: 0;
+
+ }
+ .export-dropdown::after {
+ transform: translate(-50%, -54px);
+ }
+ .endpoint-query-dropdown::after {
+ transform: translate(-50%, -45px);
+ }
+ .export-xlsx .el-dialog__body{
+ padding: 10px 20px 20px 20px;
+ }
+ .export-xlsx .el-button:focus, .export-xlsx .el-button:hover {
+ color: unset;
+ border-color: unset;
+ background-color:unset;
+ }
+ .dropdownBtn .el-button--primary{
+ top:2px;
+ padding: 0 8px;
+ background-image: linear-gradient(180deg, #fff 0%, #E0E0E0 100%);
+ border: 0px;
+ color: #666;
+ -webkit-box-shadow: 0 0 1px 1px rgba(162,162,162,0.5);
+ box-shadow: 0 0 1px 1px rgba(162,162,162,0.5);
+ letter-spacing: 0;
+ background-color: unset;
+ }
+ .dropdownBtn .el-button--primary:hover{
+ background-image: linear-gradient(180deg, #F0F0F0 0%, #D8D8D8 99%) !important;
+ }
+ .dropdownBtn .el-button--mini{
+ font-size: 12px;
+ height: 24px;
+ }
+ .dropdownBtn .el-button--mini:first-of-type {
+ right: 3px;
+ }
+ .el-dropdown .el-button-group{
+ display: block;
+ position: relative;
+ top:-2px;
+ }
+ .export-xlsx .el-dropdown .el-dropdown__caret-button {
+ padding-left: 5px;
+ padding-right: 5px;
+ border-left: none;
+ top: 0;
+ left: -1px;
+ }
</style>
diff --git a/nezha-fronted/src/components/common/header.vue b/nezha-fronted/src/components/common/header.vue
index 5df9db7b0..459ae481b 100644
--- a/nezha-fronted/src/components/common/header.vue
+++ b/nezha-fronted/src/components/common/header.vue
@@ -418,7 +418,7 @@ export default {
},
getUserData () {
return new Promise(resolve => {
- this.$get('sys/user/list', { pageSize: -1, pageNo: 1 }).then(response => {
+ this.$get('sys/user', { pageSize: -1, pageNo: 1 }).then(response => {
if (response.code === 200) {
this.userData = response.data.list
}
diff --git a/nezha-fronted/src/components/common/js/constants.js b/nezha-fronted/src/components/common/js/constants.js
index eda5853b0..e9cc3ecf0 100644
--- a/nezha-fronted/src/components/common/js/constants.js
+++ b/nezha-fronted/src/components/common/js/constants.js
@@ -182,10 +182,18 @@ export const fromRoute = {
message: 'message',
rule: 'rule',
model: 'model',
+ mib: 'mib',
asset: 'asset',
+ assetType: 'assetType',
+ assetState: 'assetState',
+ expressionTemplate: 'expressionTemplate',
+ account: 'account',
+ promServer: 'promServer',
dc: 'dc',
+ role: 'role',
endpoint: 'endpoint',
project: 'project',
endpointQuery: 'endpointQuery',
- terminalLog: 'terminal'
+ terminalLog: 'terminalLog',
+ operationLog: 'operationLog'
}
diff --git a/nezha-fronted/src/components/common/js/tools.js b/nezha-fronted/src/components/common/js/tools.js
index 5d2050944..aebb5da49 100644
--- a/nezha-fronted/src/components/common/js/tools.js
+++ b/nezha-fronted/src/components/common/js/tools.js
@@ -242,7 +242,7 @@ export const bottomBoxWindow = {
vm.tools.toTopBtnTop = vm.$tableHeight.toTopBtnTop
vm.bottomBox.isFullScreen = false
// 移动分页组件的位置
- const paginationTop = document.querySelector('.pagination-top')
+ /* const paginationTop = document.querySelector('.pagination-top')
const paginationBottom = document.querySelector('.pagination-bottom')
paginationTop.classList.remove('display-none')
if (paginationTop.classList.contains('pagination-top-show')) {
@@ -254,7 +254,7 @@ export const bottomBoxWindow = {
setTimeout(() => {
paginationTop.classList.add('display-none')
paginationBottom.appendChild(paginationTop.removeChild(document.querySelector('.pagination')))
- }, 210)
+ }, 210) */
// 主列表恢复全屏
vm.bottomBox.mainResizeShow = vm.bottomBox.subResizeShow = true
@@ -265,7 +265,7 @@ export const bottomBoxWindow = {
vm.mainTableHeight = vm.$tableHeight.openSubList.mainList // 重置table高度
vm.tools.toTopBtnTop = vm.$tableHeight.openSubList.toTopBtnTop
// 移动分页组件的位置
- const paginationTop = document.querySelector('.pagination-top')
+ /* const paginationTop = document.querySelector('.pagination-top')
paginationTop.appendChild(document.querySelector('.pagination-bottom').removeChild(document.querySelector('.pagination')))
paginationTop.classList.remove('display-none')
setTimeout(() => {
@@ -275,7 +275,7 @@ export const bottomBoxWindow = {
if (!paginationTop.classList.contains('pagination-top-show')) {
paginationTop.classList.add('pagination-top-show')
}
- }, 210)
+ }, 210) */
}
}
}
diff --git a/nezha-fronted/src/components/common/language/cn.js b/nezha-fronted/src/components/common/language/cn.js
index 8d0293300..84917d151 100644
--- a/nezha-fronted/src/components/common/language/cn.js
+++ b/nezha-fronted/src/components/common/language/cn.js
@@ -48,6 +48,7 @@ const cn = {
createAlertRule: '新增告警规则',
createAccount: '新增用户名',
createRole: '新增角色',
+ createTemplate: '新增模板',
createPrometheusServer: '新增prometheus服务',
createDatacenter: '新增数据中心',
active: '活跃',
@@ -641,12 +642,17 @@ const cn = {
account: {
accountList: '用户列表',
account: '用户',
+ name: '姓名', // "用户"
+ username: '登录名', // 登录名
roles: '角色',
language: '语言',
receiver: '接收人',
createTime: '创建时间',
enable: '可用',
option: '操作',
+ lastLoginTime: '最后登录时间', // 最后登录时间
+ lastLoginIp: '最后登录IP', // 最后登录IP
+ source: '来源',
accountId: '用户ID',
createAccount: '新增用户',
editAccount: '编辑用户',
@@ -1000,6 +1006,7 @@ const cn = {
exprTempImport: 'expression模板导入',
exprTempExport: 'expression模板导出',
exprTempImportCancel: 'expression模板导入撤销',
+ copy: '复制',
name: '名称',
gname: '组名',
expression: '表达式',
diff --git a/nezha-fronted/src/components/common/language/en.js b/nezha-fronted/src/components/common/language/en.js
index 7a10f11ee..0700845bb 100644
--- a/nezha-fronted/src/components/common/language/en.js
+++ b/nezha-fronted/src/components/common/language/en.js
@@ -63,6 +63,7 @@ const en = {
createMib: 'Create MIB',
createAssetType: 'Create asset type',
createAssetState: 'Create asset state',
+ createTemplate: 'Create template',
exportExcel: 'Export',
importExcel: 'Import',
importExcelLower: 'import',
@@ -640,19 +641,24 @@ const en = {
config: {
config: 'Settings', // "设置"
account: {
- accountList: 'Account list', // "用户列表"
+ accountList: 'User list', // "用户列表"
+ account: 'User',
// 列表表头
- account: 'Account', // "用户"
+ name: 'Name', // "用户"
+ username: 'Username', // 登录名
roles: 'Role',
language: 'Language', // "语言"
receiver: 'Receiver', // "用户组"
createTime: 'Create time', // "创建时间"
enable: 'Enable', // "可用"
option: 'Operation', // "操作"
+ lastLoginTime: 'Last login time', // 最后登录时间
+ lastLoginIp: 'Last login IP', // 最后登录IP
+ source: 'Source',
// 侧滑框//
- accountId: 'Account ID', // "用户ID"
- createAccount: 'New account', // "新增用户"
- editAccount: 'Edit account', // "编辑用户"
+ accountId: 'User ID', // "用户ID"
+ createAccount: 'New user', // "新增用户"
+ editAccount: 'Edit user', // "编辑用户"
notCurrentlySupport: 'Not available', // '暂不支持'
password: 'Password', // '密码'
oldPwd: 'Old password',
@@ -1010,6 +1016,7 @@ const en = {
exprTempImport: 'expression template import',
exprTempExport: 'expression template export',
exprTempImportCancel: 'expression template import rollback',
+ copy: 'Copy',
name: 'Name',
gname: 'Group',
expression: 'Expression',
diff --git a/nezha-fronted/src/components/common/mixin/table.js b/nezha-fronted/src/components/common/mixin/table.js
index 00bf3ecb7..eaacb6287 100644
--- a/nezha-fronted/src/components/common/mixin/table.js
+++ b/nezha-fronted/src/components/common/mixin/table.js
@@ -1,12 +1,19 @@
import bus from '@/libs/bus'
+import { tableSet } from '@/components/common/js/tools'
+import { fromRoute } from '@/components/common/js/constants'
export default {
data () {
return {
+ fromRoute: fromRoute,
// 侧滑
rightBox: {
show: false
},
-
+ pageObj: { // 分页对象
+ pageNo: 1,
+ pageSize: this.$CONSTANTS.defaultPageSize,
+ total: 0
+ },
/* 工具参数 */
tools: {
loading: false, // 是否显示table加载动画
@@ -19,24 +26,51 @@ export default {
tableData: [],
searchLabel: {}, // 搜索参数
scrollbarWrap: null,
- delFlag: false
+ delFlag: false,
+
+ operationWidth: "165" // 操作列宽
}
},
methods: {
- tableOperation ([command, row]) {
+ sortableShow: tableSet.sortableShow,
+ propTitle: tableSet.propTitle,
+ asce: tableSet.asce,
+ desc: tableSet.desc,
+ strTodate: tableSet.strTodate,
+ tableOperation ([command, row, url]) {
switch (command) {
case 'edit': {
this.edit(row)
break
}
case 'delete': {
- this.del(row)
+ this.del(row, url)
break
}
default:
break
}
},
+ isBuildIn (row) {
+ return (row.buildIn && row.buildIn == 1) || (row.builtIn && row.builtIn == 1)
+ },
+ del (row, url) {
+ this.$confirm(this.$t('tip.confirmDelete'), {
+ confirmButtonText: this.$t('tip.yes'),
+ cancelButtonText: this.$t('tip.no'),
+ type: 'warning'
+ }).then(() => {
+ this.$delete(url).then(response => {
+ if (response.code === 200) {
+ this.delFlag = true
+ this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
+ this.getTableData()
+ } else {
+ this.$message.error(response.msg)
+ }
+ })
+ })
+ },
newObject () {
return JSON.parse(JSON.stringify(this.blankObject))
},
@@ -156,5 +190,10 @@ export default {
: this.tableTitle
this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
this.getTableData()
+ },
+ beforeDestroy () {
+ if (this.scrollbarWrap) {
+ this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
+ }
}
}
diff --git a/nezha-fronted/src/components/common/popBox/selectAssetMetaGroup.vue b/nezha-fronted/src/components/common/popBox/selectAssetMetaGroup.vue
new file mode 100644
index 000000000..43460c3ac
--- /dev/null
+++ b/nezha-fronted/src/components/common/popBox/selectAssetMetaGroup.vue
@@ -0,0 +1,152 @@
+<template>
+ <el-popover ref="selectAssetMetaGroupPopBox" v-model="popBox.show" :placement="placement" popper-class="nz-pop nz-pop-select-panel" transition="slide" width="300">
+ <div>
+ <div class="pop-item-wider">
+
+ <slot name="header"></slot>
+
+ <div class="select-panel-tree">
+ <el-tree
+ ref="tree"
+ :data="objectData"
+ :expand-on-click-node="false"
+ :filter-node-method="filterNode"
+ :props="{label: 'name', children: 'children'}"
+ check-on-click-node
+ check-strictly
+ default-expand-all
+ highlight-current
+ node-key="id"
+ @node-click="selectObject">
+ <div slot-scope="{ node, data }" class="tree--node">
+ <span>{{ node.label }}</span>
+ <span class="tree--operation">
+ <span class="panel-dropdown-btn panel-dropdown-btn-delete" @click.stop="del(data)"><i class="nz-icon nz-icon-delete"></i></span>
+ <span class="panel-dropdown-btn" @click.stop="edit(data)"><i class="nz-icon nz-icon-edit"></i></span>
+ </span>
+ </div>
+ </el-tree>
+ </div>
+ </div>
+ </div>
+ <div slot="reference">
+ <slot name="trigger"></slot>
+ </div>
+ </el-popover>
+</template>
+
+<script>
+export default {
+ name: 'selectAssetMetaGroup',
+ props: {
+ placement: { type: String },
+ isEdit: { type: Boolean, default: true },
+ objectData: { type: Array },
+ showObject: { type: Object },
+ filterObject: { type: String }
+ },
+ mounted () {
+ this.$refs.tree.setCurrentKey(this.object)
+ },
+ watch: {
+ filterObject: {
+ immediate: true,
+ handler (n) {
+ this.$refs.tree && this.$refs.tree.filter(n)
+ }
+ },
+ showObject: {
+ immediate: true,
+ handler (n) {
+ if (n) {
+ this.object = JSON.parse(JSON.stringify(n))
+ }
+ }
+ }
+ },
+ data () {
+ return {
+ popBox: { show: false },
+ object: { id: 0, name: '' }
+ }
+ },
+ methods: {
+ filterNode (value, data) {
+ if (!value) return true
+ return data.name.indexOf(value) !== -1
+ },
+ del (data) {
+ this.$emit('del', data)
+ },
+ edit (data) {
+ this.$emit('edit', data)
+ },
+ esc () {
+ this.popBox.show = false
+ },
+ // 确认选择某个节点,与父组件交互
+ selectObject (data, checked, child) {
+ this.$emit('selectObject', data)
+ this.$refs.tree.setCurrentKey(data)
+ this.esc()
+ }
+ }
+}
+</script>
+
+<style lang="scss">
+.movable {
+ .el-tree-node__content {
+ cursor: move;
+ .tree--node>span:first-of-type {
+ cursor: pointer;
+ }
+ .tree--node>span:last-of-type>span {
+ cursor: pointer;
+ }
+ }
+}
+.tree--node>span:last-of-type>span>i {
+ font-weight: normal !important;
+}
+.select-panel-tree {
+ height: 350px;
+ overflow: auto;
+}
+.select-panel-tree .el-tree-node__content {
+ height: 34px;
+ line-height: 34px;
+}
+.select-panel-tree .el-tree-node__content:hover {
+ color: $global-text-color-active;
+}
+.select-panel-tree .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
+ background-color: #F5F7FA;
+ font-weight: bold;
+ color: $global-text-color-active;
+}
+.tree--node {
+ display: flex;
+ justify-content: space-between;
+ width: calc(100% - 28px);
+}
+.tree--operation {
+ opacity: 0;
+}
+.tree--node:hover .tree--operation {
+ opacity: 1;
+}
+.panel-dropdown-btn {
+ color: #60BEFF;
+}
+.panel-dropdown-btn:hover {
+ color: #409EFF;
+}
+.panel-dropdown-btn-delete {
+ color: #F98D9A;
+}
+
+.panel-dropdown-btn-delete:hover {
+ color: #D96D7A;
+}
+</style>
diff --git a/nezha-fronted/src/components/common/rightBox/accountBox.vue b/nezha-fronted/src/components/common/rightBox/accountBox.vue
index 620676836..debfb5b72 100644
--- a/nezha-fronted/src/components/common/rightBox/accountBox.vue
+++ b/nezha-fronted/src/components/common/rightBox/accountBox.vue
@@ -5,7 +5,7 @@ $--input-focus-border: red;
<div class="right-box right-box-account" v-clickoutside="{obj:editUser,func:clickOutside}">
<!-- begin--顶部按钮-->
<div class="right-box-top-btns right-box-form-delete">
- <button @click="del" type="button" v-has="'account_delete'" v-if="editUser.userId&&editUser.userId!==1"
+ <button v-if="editUser.id&&editUser.id!==1" v-has="'account_delete'" type="button" @click="del"
class="nz-btn nz-btn-size-normal nz-btn-size-alien"
id="account-edit-del">
<span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span>
@@ -15,16 +15,16 @@ $--input-focus-border: red;
<!-- end--顶部按钮-->
<!-- begin--标题-->
- <div class="right-box-title">{{editUser.userId ? ($t("config.account.editAccount") + " ID:" + editUser.userId) : $t("config.account.createAccount")}}</div>
+ <div class="right-box-title">{{editUser.id ? ($t("config.account.editAccount") + " ID:" + editUser.id) : $t("config.account.createAccount")}}</div>
<!-- end--标题-->
<!-- begin--表单-->
<div class="right-box-form-box">
- <el-form :model="editUser" :rules="editUser.userId ? rules2 : rules" class="right-box-form right-box-form-left" label-position = "top" label-width="120px" ref="accountForm">
+ <el-form ref="accountForm" :model="editUser" :rules="editUser.id ? rules2 : rules" class="right-box-form right-box-form-left" label-position = "top" label-width="120px">
<!--username-->
<el-form-item :label="$t('config.account.account')" prop="username">
<el-input autocomplete="new-password" type="text" placeholder="" id="account-input-username"
- v-model="editUser.username" maxlength="64" show-word-limit size="small" :disabled="editUser.username==='admin' && editUser.userId==1"></el-input>
+ v-model="editUser.username" :disabled="editUser.username==='admin' && editUser.id==1" maxlength="64" show-word-limit size="small"></el-input>
</el-form-item>
<!--password-->
<el-form-item :label="$t('config.account.password')" prop="pin">
@@ -42,19 +42,19 @@ $--input-focus-border: red;
</el-form-item>
<!--enable-->
<el-form-item :label="$t('config.account.enable')">
- <el-switch v-model="editUser.status" active-color="#ee9d3f" :disabled="isCurrentUser(editUser.username) || (editUser.username==='admin' && editUser.userId==1) " active-value="1" id="account-input-status"
+ <el-switch id="account-input-status" v-model="editUser.status" :disabled="isCurrentUser(editUser.username) || (editUser.username==='admin' && editUser.id==1) " active-color="#ee9d3f" active-value="1"
inactive-value="0">
</el-switch>
</el-form-item>
<!--roles-->
<el-form-item :label="$t('config.account.roles')" prop="roleIds">
- <el-select @change="()=>{this.$forceUpdate()}" clearable collapse-tags placeholder="" popper-class="config-dropdown" size="small" v-model="editUser.roleIds" :disabled="(editUser.username==='admin') && editUser.userId==1" id="account-input-roleIds">
+ <el-select id="account-input-roleIds" v-model="editUser.roleIds" :disabled="(editUser.username==='admin') && editUser.id==1" clearable collapse-tags placeholder="" popper-class="config-dropdown" size="small" @change="()=>{this.$forceUpdate()}">
<template v-for="role in roles">
<el-option :key="role.id" :label="role.i18n?$t(role.i18n):role.name" :value="role.id"></el-option>
</template>
</el-select>
</el-form-item>
- <el-form-item :label="$t('config.account.createTime')" v-if="editUser.userId">
+ <el-form-item v-if="editUser.id" :label="$t('config.account.createTime')">
<div class="right-box-form-content-txt">{{editUser.createTime}}</div>
</el-form-item>
@@ -180,8 +180,8 @@ export default {
if (valid) {
const editUser = JSON.parse(JSON.stringify(this.editUser))
editUser.roleIds = [editUser.roleIds]
- if (this.editUser.userId) {
- this.$put('sys/user/update', editUser).then(response => {
+ if (this.editUser.id) {
+ this.$put('sys/user', editUser).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
@@ -192,7 +192,7 @@ export default {
})
} else {
editUser.roleIds = this.roles.find(t => t.name == 'common').id
- this.$post('sys/user/save', editUser).then(response => {
+ this.$post('sys/user', editUser).then(response => {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
@@ -217,7 +217,7 @@ export default {
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
- this.$delete('sys/user/delete?userIds=' + this.editUser.userId).then(response => {
+ this.$delete('sys/user?ids=' + this.editUser.id).then(response => {
if (response.code === 200) {
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.esc(true)
diff --git a/nezha-fronted/src/components/common/table/nzDataList.vue b/nezha-fronted/src/components/common/table/nzDataList.vue
index 36bd68362..0b45fef0b 100644
--- a/nezha-fronted/src/components/common/table/nzDataList.vue
+++ b/nezha-fronted/src/components/common/table/nzDataList.vue
@@ -5,11 +5,14 @@
<!-- 顶部工具栏 -->
<div class="main-modal"></div>
<div v-show="bottomBox.mainResizeShow" class="top-tools">
+ <div class="top-tool-main-left" style="width: 300px">
+ <slot name="top-tool-left"></slot>
+ </div>
<div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
<div v-if="components.indexOf('searchInput') > -1" class="top-tool-search">
<search-input ref="searchInput" :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search"></search-input>
</div>
- <slot name="top-tool"></slot>
+ <slot name="top-tool-right"></slot>
<button v-if="components.indexOf('elementSet') > -1" id="account-column-setting" class="top-tool-btn margin-l-10"
type="button" @click="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)">
<i class="nz-icon-gear nz-icon"></i>
@@ -33,7 +36,7 @@
<div v-show="bottomBox.mainResizeShow" class="nz-table2">
<slot v-bind:mainResizeShow="bottomBox.mainResizeShow"></slot>
</div>
- <div v-show="!bottomBox.showSubList" class="pagination-bottom">
+ <div class="pagination-bottom">
<slot name="pagination"></slot>
</div>
</div>
@@ -45,16 +48,23 @@
:obj="bottomBox.object"
:sub-resize-show="bottomBox.subResizeShow"
:target-tab.sync="bottomBox.targetTab"
- @closeSubList="bottomBox.showSubList = false" @exitFullScreen="exitFullScreen" @fullScreen="fullScreen" @listResize="listResize" ></bottom-box>
+ @closeSubList="bottomBox.showSubList = false"
+ @exitFullScreen="exitFullScreen"
+ @fullScreen="fullScreen"
+ @listResize="listResize" ></bottom-box>
</transition>
</div>
</template>
<script>
+import bottomBox from '@/components/common/bottomBox/bottomBox'
import { bottomBoxWindow } from '@/components/common/js/tools'
export default {
name: 'nzDataList',
+ components: {
+ bottomBox
+ },
props: {
from: {
type: String,
diff --git a/nezha-fronted/src/components/layout/header.vue b/nezha-fronted/src/components/layout/header.vue
index 04decdadb..879ffa3d7 100644
--- a/nezha-fronted/src/components/layout/header.vue
+++ b/nezha-fronted/src/components/layout/header.vue
@@ -343,7 +343,7 @@ export default {
},
getUserData () {
return new Promise(resolve => {
- this.$get('sys/user/list', { pageSize: -1, pageNo: 1 }).then(response => {
+ this.$get('sys/user', { pageSize: -1, pageNo: 1 }).then(response => {
if (response.code === 200) {
this.userData = response.data.list
}
diff --git a/nezha-fronted/src/components/page/config/account2.vue b/nezha-fronted/src/components/page/config/account2.vue
index aaa8121dc..d593777e7 100644
--- a/nezha-fronted/src/components/page/config/account2.vue
+++ b/nezha-fronted/src/components/page/config/account2.vue
@@ -7,13 +7,13 @@
:search-msg="searchMsg"
:table-id="tableId"
:table-title="tableTitle"
- from="account">
- <template v-slot:top-tool>
+ :from="fromRoute.account">
+ <template v-slot:top-tool-right>
<button id="account-add" v-has="'account_toAdd'" :title="$t('overall.createAccount')" class="top-tool-btn margin-l-20"
type="button" @click="add">
<i class="nz-icon-create-square nz-icon"></i>
</button>
- <delete-button id="account-list-batch-delete" v-has="'account_delete'" :delete-objs="batchDeleteObjs" :filter-function="(arr)=>{return '?userIds='+arr.map(t=>t.userId).join(',')}" api="sys/user/delete" @after="getTableData" @before="delFlag=true"></delete-button>
+ <delete-button id="account-list-batch-delete" v-has="'account_delete'" :delete-objs="batchDeleteObjs" api="sys/user" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot:default="slotProps">
<el-table
@@ -43,14 +43,12 @@
:resizable="true"
:sort-orders="['ascending', 'descending']"
:width="`${item.width}`"
+ :min-width="`${item.minWidth}`"
class="data-column"
>
<template slot="header">
- <span v-if="item.type == 'tag'" :title="item.label" class="tag-header"><span class="tag-value">{{item.label}}</span><span class="tag-mark">&nbsp;[Tag]</span></span>
- <span v-else>
- <span>{{item.label}}</span>
- <div class="col-resize-area"></div>
- </span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'roles'">
@@ -63,35 +61,34 @@
<span>-</span>
</template>
</template>
- <template v-else-if="item.prop == 'status'">
+ <template v-else-if="item.prop === 'status'">
<el-switch
v-model="scope.row.status"
- :disabled="isCurrentUser(scope.row.username) || !hasButton('account_toEdit') || !hasButton('account_toAdd') || (scope.row.username==='admin' && scope.row.userId==1)"
+ :disabled="isCurrentUser(scope.row.username) || !hasButton('account_toEdit') || !hasButton('account_toAdd') || (scope.row.username==='admin' && scope.row.id==1)"
active-color="#ee9d3f"
active-value="1"
inactive-value="0"
@change="(val)=>{statusChange(scope.row)}">
</el-switch>
</template>
- <span v-else-if="item.prop == 'tags'">{{filterTags(item, scope)}}</span>
- <span v-else-if="item.prop == 'createTime'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <span v-else-if="item.prop === 'createTime'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<el-table-column
:resizable="false"
fixed="right"
- width="165">
+ :width="operationWidth">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
- <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLogTab', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
- <el-dropdown-item :command="['edit', scope.row]" ><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
- <el-dropdown-item :command="['delete', scope.row]" ><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['edit', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `sys/user?ids=${scope.row.id}`]" :disabled="scope.row.id === 1"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
@@ -111,10 +108,9 @@
</div>
</template>
<script>
-import deleteButton from '../../common/deleteButton'
-import accountBox from '../../common/rightBox/accountBox'
+import deleteButton from '@/components/common/deleteButton'
+import accountBox from '@/components/common/rightBox/accountBox'
import nzDataList from '@/components/common/table/nzDataList'
-import bus from '../../../libs/bus'
import tableMixin from '@/components/common/mixin/table'
export default {
name: 'account',
@@ -128,7 +124,8 @@ export default {
return {
tableId: 'accountTable', // 需要分页的table的id,用于记录每页数量
blankObject: { // 空白对象
- userId: '',
+ id: '',
+ name: '',
username: '',
email: '',
status: '1',
@@ -139,37 +136,48 @@ export default {
lang: '',
notifications: []
},
- pageObj: { // 分页对象
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [ // 原table列
{
label: 'ID',
- prop: 'userId',
+ prop: 'id',
show: true,
width: 80
}, {
- label: this.$t('config.account.account'),
+ label: this.$t('config.account.name'),
+ prop: 'name',
+ show: true,
+ width: 150
+ }, {
+ label: this.$t('config.account.username'),
prop: 'username',
show: true,
- width: 200
+ width: 150
}, {
label: this.$t('config.account.roles'),
prop: 'roles',
show: true,
- width: 200
+ width: 150
}, {
label: 'E-mail',
prop: 'email',
- show: true
+ show: true,
+ minWidth: 150
}, {
- label: this.$t('config.account.createTime'),
- prop: 'createTime',
+ label: this.$t('config.account.lastLoginTime'),
+ prop: 'lastLoginTime',
show: true,
width: 200
}, {
+ label: this.$t('config.account.lastLoginIp'),
+ prop: 'lastLoginIp',
+ show: true,
+ width: 150
+ }, {
+ label: this.$t('config.account.source'),
+ prop: 'source',
+ show: true,
+ width: 150
+ }, {
label: this.$t('config.account.enable'),
prop: 'status',
show: true,
@@ -190,24 +198,6 @@ export default {
}
},
methods: {
- del (u) {
- if (u.userId == 1 && u.username === 'admin') { return }
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('sys/user/delete?userIds=' + u.userId).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
getTableData () {
if (!this.hasButton('account_view')) {
this.$message.error(this.$t('tip.noAccess'))
@@ -216,7 +206,7 @@ export default {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
- this.$get('sys/user/list', this.searchLabel).then(response => {
+ this.$get('sys/user', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
for (let i = 0; i < response.data.list.length; i++) {
@@ -233,25 +223,11 @@ export default {
}
})
},
- /* add () {
- this.object = this.newObject()
- if (!this.user.userId) {
- this.user.roleIds = this.roles.find(t => t.name == 'common').id
- }
- this.rightBox.show = true
- },
- edit (u) {
- this.object = JSON.parse(JSON.stringify(u))
- if (!this.object.userId) {
- this.object.roleIds = this.roles.find(t => t.name == 'common').id
- }
- this.rightBox.show = true
- }, */
statusChange (user) {
if (user.roles) {
user.roleIds = user.roles.map(t => t.id)
}
- this.$put('sys/user/update', user).then(response => {
+ this.$put('sys/user', user).then(response => {
if (response.code === 200) {
this.rightBox.show = false
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
@@ -291,7 +267,7 @@ export default {
result = result.concat(keepTags).concat(newTags)
this.tools.customTableTitle = JSON.parse(JSON.stringify(result))
})
- },
+ }/* ,
filterTags (head, scope) {
if (scope.row.notifications) {
const notification = scope.row.notifications.find(item => {
@@ -301,12 +277,7 @@ export default {
return notification.account
}
}
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- }
+ } */
},
computed: {
isCurrentUser () {
@@ -315,44 +286,9 @@ export default {
}
}
},
- /*watch: {
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- },
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
-
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.dataTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
- },*/
- created () {
- // 是否存在分页缓存
- /*const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }*/
- },
mounted () {
this.getRoles()
this.resetTableTitle()
- // 初始化表头
- /*this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
-
- this.resetTableTitle()
- this.getTableData()*/
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/assetMeta.vue b/nezha-fronted/src/components/page/config/assetMeta.vue
index cbce0524e..82f8f423b 100644
--- a/nezha-fronted/src/components/page/config/assetMeta.vue
+++ b/nezha-fronted/src/components/page/config/assetMeta.vue
@@ -1,129 +1,74 @@
<template>
- <div class="main-list main-and-sub-transition" :class="{'main-list-with-sub': bottomBox.showSubList}">
- <!--工具组-->
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}">
- <div class="top-tool-search margin-r-20">
- <search-input :searchMsg="searchMsg" @search="search"
- :inTransform="bottomBox.inTransform" :single="true"></search-input>
- </div>
- <button :title="$t('overall.exportExcelLower')" @click="addMeta" type="button" v-has="'expr_temp_save'"
- class="nz-btn nz-btn-size-normal nz-btn-style-light" id="meta-add-meta">
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.role"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-left>
+ <select-group ref="selectGroup" :filter-object="filterGroup" :object-data="groupData" :placement="'bottom-start'"
+ :show-object="showGroup" style="width: 300px;" @del="delGroup" @edit="editGroup" @selectObject="groupChange">
+ <template v-slot:header>
+ <div class="panel-select-header">
+ <el-input id="panel-list-search" v-model="filterGroup" :placeholder="$t('overall.search')" clearable size="mini" style="width: 240px; margin-right: 5px;"></el-input>
+ <span id="panel-list-toadd" v-has="'panel_toAdd'" :title='$t("dashboard.panel.createPanelTitleSec")' class="panel-select-add" @click="addGroup"><i class="nz-icon nz-icon-plus"></i></span>
+ </div>
+ </template>
+ <template v-slot:trigger>
+ <el-input v-model="showGroup.name" class="panel-name" placeholder="" readonly="readonly" size="small"></el-input>
+ </template>
+ </select-group>
+ </template>
+ <template v-slot:top-tool-right>
+ <button id="meta-add-meta" v-has="'expr_temp_save'" :title="$t('overall.exportExcelLower')" class="top-tool-btn margin-l-20"
+ type="button" @click="add">
<i class="nz-icon nz-icon-create-square"></i>
</button>
-
- <delete-button :delete-objs="batchDeleteObjs" @after="getAssetMeta"
+ <delete-button :delete-objs="batchDeleteObjs" @after="getTableData"
:api="'asset/field/meta'" v-has="'expr_temp_delete'" id="meta-msg-batch-delete"></delete-button>
- </div>
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- content -->
- <div class="content">
- <div class="asset-meta-group">
- <div class="group-title">
- <span>
- <button @click="addGroup" type="button" v-has="'asset:fieldgroup:add'" :disabled="metaGroupLock"
- :class="{'nz-btn-disabled' : metaGroupLock}"
- class="nz-btn nz-btn-size-normal nz-btn-style-light" id="meta-list-export">
- <i class="nz-icon nz-icon-create-square"></i>
- </button>
- <button @click="metaGroupLock=!metaGroupLock" class="nz-btn nz-btn-size-normal nz-btn-style-light" type="button" id="panel-lock"><i :class="{'nz-icon nz-icon-lock':metaGroupLock,'nz-icon nz-icon-unlock':!metaGroupLock}"></i></button>
- </span>
- </div>
- <el-tree
- :data="groupData"
- :props="defaultProps"
- :node-key="'id'"
- @node-click="changeGroup"
- ref="groupTree"
- check-on-click-node
- check-strictly
- >
- <div class="meta-group" slot-scope="{ node, data }">
- <div>
- <i class="nz-icon nz-icon-reading" v-if="!data.children"></i>
- <i class="el-icon-folder-opened" v-if="data.children"></i>
- {{ node.label }}
- </div>
- <div v-if="!data.children&&!metaGroupLock" class="icon-box">
- <span :id="'asset-group-edit-'+node.id" :title="$t('overall.edit')" @click.stop="editGroup(data)"
- class="content-right-option" v-has="'asset:fieldgroup:update'">
- <i class="nz-icon nz-icon-edit"></i>
- </span>
- <span
- :id="'asset-group-del-'+node.id"
- :title="$t('overall.delete')"
- @click.stop="delGroup(data)"
- class="content-right-option"
- v-has="'asset:fieldgroup:delete'">
- <i class="nz-icon nz-icon-delete"></i>
- </span>
- </div>
- </div>
- </el-tree>
- </div>
- <div class="asset-meta-table">
- <!--表格开始-->
- <transition name="el-zoom-in-top">
- <element-set
- id="meta-rule-element-set"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
+ </template>
+ <template v-slot:default="slotProps">
<el-table
- id="meta-rule-table"
- class="nz-table"
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
:data="tableData"
- border
- v-show="bottomBox.mainResizeShow"
- ref="assetMetaTable"
- tooltip-effect="light"
:height="mainTableHeight"
- v-loading="tools.loading"
- style="width: 100%;"
+ border
+ @header-dragend="dragend"
@sort-change="tableDataSort"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
+ align="center"
type="selection"
- width="40"
- align="center">
+ width="55">
</el-table-column>
-
<el-table-column
- :resizable="true"
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
+ :fixed="item.fixed"
:label="item.label"
- :show-overflow-tooltip="item.prop!=='matchers'"
+ :prop="item.prop"
+ :resizable="true"
:sort-orders="['ascending', 'descending']"
- :sortable="$tableSet.sortableShow(item.prop,'assetMeta')"
- :prop="$tableSet.propTitle(item.prop,'assetMeta')"
- :width="item.width"
+ :width="`${item.width}`"
+ class="data-column"
>
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
<template slot-scope="scope" :column="item">
- <div v-if="item.prop === 'option'" class="content-right-options">
- <span :id="'meta-edit-'+scope.row.id" :title="$t('overall.edit')" @click.stop="edit(scope.row)"
- class="content-right-option" v-has="'expr_temp_update'">
- <i class="nz-icon nz-icon-edit"></i>
- </span>
- <span
- :id="'meta-del-'+scope.row.id"
- :title="$t('overall.delete')"
- @click="del(scope.row)"
- class="content-right-option"
- v-has="'expr_temp_delete'">
- <i class="nz-icon nz-icon-delete"></i>
- </span>
- </div>
- <div v-else-if=" item.prop === 'group' ">
- {{scope.row[item.prop]?scope.row[item.prop].name:'-'}}
+ <div v-if="item.prop === 'group'">
+ {{scope.row[item.prop] ? scope.row[item.prop].name : '-'}}
</div>
<div v-else-if=" item.prop === 'display' ">
<el-switch
@@ -147,51 +92,63 @@
<template v-else>-</template>
</template>
</el-table-column>
-
- <el-table-column width="28" :resizable="false">
- <template slot="header">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)"
- class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `asset/field/meta?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </div>
</el-table-column>
</el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}"
- @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow"
- id="meta-rule-toTop"><i class="nz-icon nz-icon-top"></i></button>
- <!--表格结束-->
- <!--分页部分-->
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize'
- ref="Pagination"></Pagination>
- </div>
- </div>
- </div>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<!--侧滑-->
<transition name="right-box">
- <assetMetaBox v-if="rightBox.metaShow" :assetMeta="assetMeta" @close="closeRightBox"
- ref="assetMetaBox"></assetMetaBox>
+ <assetMetaBox v-if="rightBox.metaShow" ref="assetMetaBox" :asset-meta="object"
+ @close="closeRightBox"></assetMetaBox>
</transition>
<transition name="right-box">
<assetMetaGroup v-if="rightBox.groupShow" :metaGroup="metaGroup" @close="closeRightBox"
- ref="assetMetaBox"></assetMetaGroup>
+ ref="assetMetaBox"></assetMetaGroup>
</transition>
</div>
</template>
<script>
-import deleteButton from '../../common/deleteButton'
-import assetMetaGroup from '../../common/rightBox/assetMetaGroup'
-import assetMetaBox from '../../common/rightBox/assetMetaBox'
+import deleteButton from '@/components/common/deleteButton'
+import assetMetaGroup from '@/components/common/rightBox/assetMetaGroup'
+import assetMetaBox from '@/components/common/rightBox/assetMetaBox'
+import selectGroup from '@/components/common/popBox/selectAssetMetaGroup'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
name: 'assetMeta',
components: {
- 'delete-button': deleteButton,
+ deleteButton,
assetMetaGroup,
- assetMetaBox
+ assetMetaBox,
+ selectGroup,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
tableId: 'assetMeta',
@@ -200,7 +157,6 @@ export default {
metaShow: false,
groupShow: false
},
- metaGroupLock: true,
tableTitle: [
{
label: 'ID',
@@ -251,31 +207,6 @@ export default {
children: 'children',
label: 'name'
},
- tableData: [],
- /* 二级列表相关 */
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- /* 二级页面相关 */
- bottomBox: {
- tabList: [], // 二级列表的标签
- tabDetailList: [], // 多个详情
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- /* 批量删除相关 */
- batchDeleteObjs: [],
/* 搜素相关 */
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
@@ -295,14 +226,8 @@ export default {
}
]
},
- searchLabel: {}, // 搜索参数
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
// 创建修改相关
- blackAssetMeta: {
+ blankObject: {
id: '',
name: '',
metaKey: '',
@@ -313,44 +238,33 @@ export default {
param: {},
remark: ''
},
- assetMeta: {
-
- },
- blackMetaGroup: {
+ object: {},
+ blankMetaGroup: {
id: '',
name: '',
remark: ''
},
- activeGroupId: -1,
- metaGroup: {
-
- }
+ filterGroup: '',
+ showGroup: { name: '' },
+ metaGroup: {}
}
},
mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
- this.initEvent()
+ this.getGroup()
+ this.showGroup = this.groupData[0]
},
methods: {
- initEvent () {
- this.$refs.groupTree.setCurrentKey(this.activeGroupId)
- this.getGroup()
- this.getAssetMeta()
- },
getGroup () {
this.$get('asset/field/group', { pageSize: -1 }).then(response => {
this.tools.loading = false
if (response.code == 200) {
- this.groupData[0].children = response.data.list
+ this.groupData = [this.groupData[0]]
+ this.groupData = this.groupData.concat(response.data.list)
this.$forceUpdate()
}
})
},
- getAssetMeta () {
+ getTableData () {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
@@ -363,60 +277,21 @@ export default {
this.tableData = response.data.list
this.pageObj.total = response.data.total
this.nowTime = this.utcTimeToTimezoneStr(response.time)
- // console.info(this.$refs.assetMetaTable)
+ // console.info(this.$refs.dataTable)
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.assetMetaTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getAssetMeta()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getAssetMeta()
- },
- search (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- this.$refs.assetMetaTable.bodyWrapper.scrollTop = 0
- this.getAssetMeta()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getAssetMeta()
- },
afterTableListChange () {
- this.getAssetMeta()
+ this.getTableData()
},
addGroup () {
- this.metaGroup = JSON.parse(JSON.stringify(this.blackMetaGroup))
+ this.metaGroup = JSON.parse(JSON.stringify(this.blankMetaGroup))
this.rightBox.groupShow = true
},
editGroup (group) {
@@ -424,11 +299,10 @@ export default {
this.rightBox.groupShow = true
},
delGroup (group) {
- const selectKey = this.$refs.groupTree.getCurrentKey()
+ const selectKey = this.$refs.selectGroup.$refs.tree.getCurrentKey()
if (this.prevent_opt.save) {
return
}
- ;
this.prevent_opt.save = true
this.$confirm(this.$t('tip.confirmDelete'), {
confirmButtonText: this.$t('tip.yes'),
@@ -442,10 +316,10 @@ export default {
this.getGroup()
if (selectKey === group.id) {
- this.activeGroupId = -1
+ this.showGroup = -1
this.searchLabel.groupId = ''
- this.getAssetMeta()
- this.$refs.groupTree.setCurrentKey(this.activeGroupId)
+ this.getTableData()
+ this.$refs.selectGroup.$refs.tree.setCurrentKey(this.showGroup)
}
} else {
this.$message.error(response.msg)
@@ -455,13 +329,13 @@ export default {
this.prevent_opt.save = false
})
},
- changeGroup (item) {
- this.activeGroupId = item.id
+ groupChange (item) {
+ this.showGroup = item
this.searchLabel.groupId = item.id !== -1 ? item.id : ''
- this.getAssetMeta()
+ this.getTableData()
},
- addMeta () {
- this.assetMeta = JSON.parse(JSON.stringify(this.blackAssetMeta))
+ add () {
+ this.assetMeta = JSON.parse(JSON.stringify(this.blankObject))
this.rightBox.metaShow = true
},
edit (row) {
@@ -479,31 +353,7 @@ export default {
} else {
this.$message.error(response.msg)
}
- this.getAssetMeta()
- })
- },
- del (row) {
- if (this.prevent_opt.save) {
- return
- }
- ;
- this.prevent_opt.save = true
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('asset/field/meta?ids=' + row.id).then(response => {
- this.prevent_opt.save = false
- if (response.code === 200) {
- this.$message({ type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getAssetMeta()
- } else {
- this.$message.error(response.msg)
- }
- })
- }).catch(() => {
- this.prevent_opt.save = false
+ this.getTableData()
})
},
closeRightBox (refresh) {
@@ -511,7 +361,7 @@ export default {
this.rightBox.groupShow = false
if (refresh) {
this.delFlag = true
- this.getAssetMeta()
+ this.getTableData()
this.getGroup()
}
}
@@ -571,4 +421,8 @@ export default {
.meta-group:hover .icon-box{
display: inline-block;
}
+
+ .panel-select-header {
+ padding: 0 0 10px 16px;
+ }
</style>
diff --git a/nezha-fronted/src/components/page/config/assetState.vue b/nezha-fronted/src/components/page/config/assetState.vue
index d23903796..d1a135a14 100644
--- a/nezha-fronted/src/components/page/config/assetState.vue
+++ b/nezha-fronted/src/components/page/config/assetState.vue
@@ -1,175 +1,141 @@
-<style scoped>
- .asset-state {
- height: 100%;
- }
-</style>
<template>
- <div class="asset-state">
- <!-- 主页面 -->
- <div :class="{'main-list-with-sub': bottomBox.showSubList}" class="main-list">
- <!-- 顶部工具栏 -->
- <div class="main-modal"></div>
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
- <div class="top-tool-search">
- <search-input :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search" ref="searchInput"></search-input>
- </div>
- <button :title="$t('overall.createassetState')" @click="add" class="nz-btn nz-btn-size-normal nz-btn-style-light margin-l-20" id="assetState-add"
- type="button" v-has="'assetState_toAdd'">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" :filter-function="(arr)=>{return '?ids='+arr.map(t=>t.id).join(',')}" @after="getTableData" @before="delFlag=true" api="/asset/stateConf" id="asset-state-list-batch-delete" v-has="'assetState_delete'"></delete-button>
- </div>
- <!-- 顶部分页组件,当打开底部上滑框时出现 -->
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- @close="tools.showCustomTableTitle = false"
- id="assetStateList"
- ref="customTableTitle"
- v-if="tools.showCustomTableTitle"
- ></element-set>
- </transition>
- <el-table
- :data="tableData"
- :height="mainTableHeight"
- :id="tableId"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
- @sort-change="tableDataSort"
- border
- class="nz-table"
- ref="assetStateTable"
- style="width: 100%;"
- v-loading="tools.loading"
- v-show="bottomBox.mainResizeShow"
- >
- <el-table-column
- :resizable="false"
- align="center"
- type="selection"
- width="40">
- </el-table-column>
- <el-table-column
- :fixed="item.fixed"
- :key="`col-${index}`"
- :label="item.label"
- :prop="item.prop"
- :resizable="true"
- :sort-orders="['ascending', 'descending']"
- v-for="(item, index) in tools.customTableTitle"
- v-if="item.show"
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.assetState"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
+ <button id="assetState-add" v-has="'assetState_toAdd'" :title="$t('overall.createAssetState')" class="top-tool-btn margin-l-20"
+ type="button" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="asset-state-list-batch-delete" v-has="'assetState_delete'" :delete-objs="batchDeleteObjs" api="/asset/stateConf" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
- <template :column="item" slot-scope="scope">
- <el-switch
- :active-value="1"
- :disabled="!hasButton('assetState_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-if="item.prop == 'ping'"
- v-model="scope.row.ping">
- </el-switch>
- <el-switch
- :active-value="1"
- :disabled="!hasButton('assetState_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-else-if="item.prop == 'monitor'"
- v-model="scope.row.monitor">
- </el-switch>
- <el-switch
- :active-value="1"
- :disabled="!hasButton('assetState_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-else-if="item.prop == 'alert'"
- v-model="scope.row.alert">
- </el-switch>
- <div class="content-right-options" v-if="item.prop == 'option'">
- <span :id="'assetState-edit-'+scope.row.id" :title="$t('overall.edit')" @click="edit(scope.row)" class="content-right-option" v-has="'assetState_toEdit'"><i class="nz-icon nz-icon-edit"></i></span>
- &nbsp;
- <span :id="'assetState-del-'+scope.row.id" :title="$t('overall.delete')" @click="del(scope.row)" class="content-right-option" v-has="'assetState_delete'"><i class="nz-icon nz-icon-delete"></i></span>
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <el-switch
+ v-if="item.prop === 'ping'"
+ v-model="scope.row.ping"
+ :active-value="1"
+ :disabled="!hasButton('assetState_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <el-switch
+ v-else-if="item.prop === 'monitor'"
+ v-model="scope.row.monitor"
+ :active-value="1"
+ :disabled="!hasButton('assetState_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <el-switch
+ v-else-if="item.prop === 'alert'"
+ v-model="scope.row.alert"
+ :active-value="1"
+ :disabled="!hasButton('assetState_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `/asset/stateConf?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
</div>
- <span v-else>{{scope.row[item.prop]}}</span>
- </template>
- </el-table-column>
- <el-table-column fixed="right" width="28">
- <template slot="header" :resizable="false">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
- </el-table-column>
- </el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" id="assetState-list-totop" v-show="tools.showTopBtn && bottomBox.mainResizeShow"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
-
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<transition name="right-box">
- <asset-state-box :asset-state="assetState" :asset-state-data="assetStateData" @close="closeRightBox" v-if="rightBox.show"></asset-state-box>
+ <asset-state-box v-if="rightBox.show" :asset-state="object" :asset-state-data="assetStateData" @close="closeRightBox"></asset-state-box>
</transition>
</div>
</template>
<script>
-import deleteButton from '../../common/deleteButton'
-import assetStateBox from '../../common/rightBox/assetStateBox'
-import bus from '../../../libs/bus'
+import assetStateBox from '@/components/common/rightBox/assetStateBox'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
name: 'asset-state-list',
components: {
- 'delete-button': deleteButton,
- 'asset-state-box': assetStateBox
+ deleteButton,
+ assetStateBox,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
- // 侧滑
- rightBox: {
- show: false
- },
- /* 二级页面相关 */
- bottomBox: {
- assetStateDetail: {},
- assetState: {},
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
-
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- batchDeleteObjs: [],
- assetState: {},
assetStateData: [],
tableId: 'assetStateTable', // 需要分页的table的id,用于记录每页数量
- blankAssetState: { // 空白对象
+ blankObject: { // 空白对象
id: '', name: '', ping: 0, monitor: 0, alert: 0, remark: ''
},
- pageObj: { // 分页对象
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [ // 原table列
{
label: 'ID',
@@ -200,15 +166,8 @@ export default {
label: this.$t('overall.remark'),
prop: 'remark',
show: true
- }, {
- label: this.$t('overall.option'),
- prop: 'option',
- show: true,
- width: 120,
- fixed: 'right'
}
],
- tableData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
@@ -218,61 +177,10 @@ export default {
label: 'name',
disabled: false
}]
- },
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null,
- delFlag: false
+ }
}
},
methods: {
- // 全屏
- /* fullScreen() {
- let vm = this;
- this.$bottomBoxWindow.fullScreen(vm);
- }, */
- // 退出全屏
- /* exitFullScreen() {
- let vm = this;
- this.$bottomBoxWindow.exitFullScreen(vm);
- }, */
- // 鼠标拖动二级列表
- /* listResize(e) {
- let vm = this;
- this.$bottomBoxWindow.listResize(vm, e);
- }, */
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getTableData()
- }
- },
- edit (u) {
- this.assetState = JSON.parse(JSON.stringify(u))
- this.rightBox.show = true
- },
- /* detail(u) {
- this.bottomBox.assetState = JSON.parse(JSON.stringify(u));
- this.bottomBox.targetTab = "detail";
- this.bottomBox.showSubList = true;
- }, */
- del (u) {
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('/asset/stateConf?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
statusChange (obj) {
this.$nextTick(() => {
this.$put('/asset/stateConf', obj).then(response => {
@@ -312,92 +220,7 @@ export default {
}
}
})
- },
- add () {
- this.assetState = this.newAssetState()
- this.rightBox.show = true
- },
- esc () {
- this.rightBox.show = false
- },
- newAssetState () {
- return JSON.parse(JSON.stringify(this.blankAssetState))
- },
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search (searchObj) {
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (this.$refs.assetStateTable) {
- this.$refs.assetStateTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
}
- },
- watch: {
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- },
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
-
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.assetStateTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
- mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
-
- this.getTableData()
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/assetType.vue b/nezha-fronted/src/components/page/config/assetType.vue
index b1818229c..c92ce94e5 100644
--- a/nezha-fronted/src/components/page/config/assetType.vue
+++ b/nezha-fronted/src/components/page/config/assetType.vue
@@ -1,184 +1,150 @@
-<style scoped>
- .asset-type {
- height: 100%;
- }
-</style>
<template>
- <div class="asset-type">
- <!-- 主页面 -->
- <div :class="{'main-list-with-sub': bottomBox.showSubList}" class="main-list">
- <!-- 顶部工具栏 -->
- <div class="main-modal"></div>
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
- <div class="top-tool-search">
- <search-input :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search" ref="searchInput"></search-input>
- </div>
- <button :title="$t('overall.createAssetType')" @click="add" class="nz-btn nz-btn-size-normal nz-btn-style-light margin-l-20" id="assetType-add"
- type="button" v-has="'assetType_toAdd'">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" :filter-function="(arr)=>{return '?ids='+arr.map(t=>t.id).join(',')}" @after="getTableData" @before="delFlag=true" api="/asset/typeConf" id="asset-type-list-batch-delete" v-has="'assetType_delete'"></delete-button>
- </div>
- <!-- 顶部分页组件,当打开底部上滑框时出现 -->
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- @close="tools.showCustomTableTitle = false"
- id="assetTypeList"
- ref="customTableTitle"
- v-if="tools.showCustomTableTitle"
- ></element-set>
- </transition>
- <el-table
- :data="tableData"
- :height="mainTableHeight"
- :id="tableId"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
- @sort-change="tableDataSort"
- border
- class="nz-table"
- ref="assetTypeTable"
- style="width: 100%;"
- v-loading="tools.loading"
- v-show="bottomBox.mainResizeShow"
- >
- <el-table-column
- :resizable="false"
- align="center"
- type="selection"
- width="40">
- </el-table-column>
- <el-table-column
- :fixed="item.fixed"
- :key="`col-${index}`"
- :label="item.label"
- :prop="item.prop"
- :resizable="true"
- :sort-orders="['ascending', 'descending']"
- v-for="(item, index) in tools.customTableTitle"
- v-if="item.show"
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.assetType"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
+ <button id="assetType-add" v-has="'assetType_toAdd'" :title="$t('overall.createAssetType')" class="top-tool-btn margin-l-20"
+ type="button" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="asset-type-list-batch-delete" v-has="'assetType_delete'" :delete-objs="batchDeleteObjs" api="asset/typeConf" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
- <template :column="item" slot-scope="scope">
- <el-switch
- :active-value="1"
- :disabled="scope.row.buildIn == 1 || !hasButton('assetType_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-if="item.prop == 'vm'"
- v-model="scope.row.vm">
- </el-switch>
- <el-switch
- :active-value="1"
- :disabled="scope.row.buildIn == 1 || !hasButton('assetType_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-else-if="item.prop == 'vmh'"
- v-model="scope.row.vmh">
- </el-switch>
- <el-switch
- :active-value="1"
- :disabled="scope.row.buildIn == 1 || !hasButton('assetType_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-else-if="item.prop == 'ssh'"
- v-model="scope.row.ssh">
- </el-switch>
- <el-switch
- :active-value="1"
- :disabled="scope.row.buildIn == 1 || !hasButton('assetType_toEdit')"
- :inactive-value="0"
- @change="(val)=>{statusChange(scope.row)}"
- active-color="#ee9d3f"
- v-else-if="item.prop == 'telnet'"
- v-model="scope.row.telnet">
- </el-switch>
- <div class="content-right-options" v-else-if="item.prop == 'option' && scope.row.buildIn != 1">
- <span :id="'assetType-edit-'+scope.row.id" :title="$t('overall.edit')" @click="edit(scope.row)" class="content-right-option" v-has="'assetType_toEdit'"><i class="nz-icon nz-icon-edit"></i></span>
- &nbsp;
- <span :id="'assetType-del-'+scope.row.id" :title="$t('overall.delete')" @click="del(scope.row)" class="content-right-option" v-has="'assetType_delete'"><i class="nz-icon nz-icon-delete"></i></span>
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <el-switch
+ v-if="item.prop === 'vm'"
+ v-model="scope.row.vm"
+ :active-value="1"
+ :disabled="scope.row.buildIn === 1 || !hasButton('assetType_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <el-switch
+ v-else-if="item.prop === 'vmh'"
+ v-model="scope.row.vmh"
+ :active-value="1"
+ :disabled="scope.row.buildIn === 1 || !hasButton('assetType_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <el-switch
+ v-else-if="item.prop === 'ssh'"
+ v-model="scope.row.ssh"
+ :active-value="1"
+ :disabled="scope.row.buildIn === 1 || !hasButton('assetType_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <el-switch
+ v-else-if="item.prop === 'telnet'"
+ v-model="scope.row.telnet"
+ :active-value="1"
+ :disabled="scope.row.buildIn === 1 || !hasButton('assetType_toEdit')"
+ :inactive-value="0"
+ active-color="#ee9d3f"
+ @change="(val)=>{statusChange(scope.row)}">
+ </el-switch>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `asset/typeConf?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
</div>
- <span v-else>{{scope.row[item.prop]}}</span>
- </template>
- </el-table-column>
- <el-table-column fixed="right" width="28">
- <template slot="header" :resizable="false">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
- </el-table-column>
- </el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" id="assetType-list-totop" v-show="tools.showTopBtn && bottomBox.mainResizeShow"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
-
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<transition name="right-box">
- <asset-type-box :asset-type="assetType" :asset-type-data="assetTypeData" @close="closeRightBox" v-if="rightBox.show"></asset-type-box>
+ <asset-type-box v-if="rightBox.show" :asset-type="object" :asset-type-data="assetTypeData" @close="closeRightBox"></asset-type-box>
</transition>
</div>
</template>
<script>
-import deleteButton from '../../common/deleteButton'
-import assetTypeBox from '../../common/rightBox/assetTypeBox'
-import bus from '../../../libs/bus'
+import assetTypeBox from '@/components/common/rightBox/assetTypeBox'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
name: 'asset-type-list',
components: {
- 'delete-button': deleteButton,
- 'asset-type-box': assetTypeBox
+ deleteButton,
+ assetTypeBox,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
- // 侧滑
- rightBox: {
- show: false
- },
- /* 二级页面相关 */
- bottomBox: {
- assetTypeDetail: {},
- assetType: {},
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
-
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- batchDeleteObjs: [],
- assetType: {},
assetTypeData: [],
tableId: 'assetTypeTable', // 需要分页的table的id,用于记录每页数量
- blankAssetType: { // 空白对象
+ blankObject: { // 空白对象
id: '', pid: '', pname: '', name: '', vm: 0, vmh: 0, ssh: 0, telnet: 0, buildIn: 0, remark: ''
},
- pageObj: { // 分页对象
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [ // 原table列
{
label: 'ID',
@@ -213,12 +179,6 @@ export default {
label: this.$t('overall.remark'),
prop: 'remark',
show: true
- }, {
- label: this.$t('overall.option'),
- prop: 'option',
- show: true,
- width: 120,
- fixed: 'right'
}
],
tableData: [],
@@ -231,63 +191,10 @@ export default {
label: 'name',
disabled: false
}]
- },
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null,
- delFlag: false
+ }
}
},
methods: {
- // 全屏
- /* fullScreen() {
- let vm = this;
- this.$bottomBoxWindow.fullScreen(vm);
- }, */
- // 退出全屏
- /* exitFullScreen() {
- let vm = this;
- this.$bottomBoxWindow.exitFullScreen(vm);
- }, */
- // 鼠标拖动二级列表
- /* listResize(e) {
- let vm = this;
- this.$bottomBoxWindow.listResize(vm, e);
- }, */
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getAssetTypeTreeData()
- this.getTableData()
- }
- },
- edit (u) {
- this.assetType = JSON.parse(JSON.stringify(u))
- this.rightBox.show = true
- },
- /* detail(u) {
- this.bottomBox.assetType = JSON.parse(JSON.stringify(u));
- this.bottomBox.targetTab = "detail";
- this.bottomBox.showSubList = true;
- }, */
- del (u) {
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('/asset/typeConf?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- this.getAssetTypeTreeData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
getAssetTypeTreeData () {
this.$get('/asset/typeConf/tree').then(response => {
if (response.code === 200) {
@@ -322,10 +229,6 @@ export default {
}
})
},
- add () {
- this.assetType = this.newAssetType()
- this.rightBox.show = true
- },
statusChange (obj) {
this.$nextTick(() => {
this.$put('/asset/typeConf', obj).then(response => {
@@ -338,89 +241,10 @@ export default {
this.getTableData()
})
})
- },
- esc () {
- this.rightBox.show = false
- },
- newAssetType () {
- return JSON.parse(JSON.stringify(this.blankAssetType))
- },
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search (searchObj) {
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (this.$refs.assetTypeTable) {
- this.$refs.assetTypeTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- }
- },
- watch: {
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- },
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
-
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.assetTypeTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
}
},
mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
-
this.getAssetTypeTreeData()
- this.getTableData()
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/dc.vue b/nezha-fronted/src/components/page/config/dc.vue
index 0f59757fd..f72c108eb 100644
--- a/nezha-fronted/src/components/page/config/dc.vue
+++ b/nezha-fronted/src/components/page/config/dc.vue
@@ -1,55 +1,32 @@
-<style lang="scss">
-@import '@/assets/css/common/tableCommon.scss';
-</style>
<template>
- <div class="dc list-page">
- <!--dc table start-->
- <div class="main-list" :class="{'main-list-with-sub': bottomBox.showSubList}">
- <div class="main-modal"></div>
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div class="top-tool-main-right" :class="{'top-tool-main-right-to-left-small': bottomBox.showSubList}">
- <div class="top-tool-search">
- <search-input ref="searchInput" :searchMsg="searchMsg" @search="search" :inTransform="bottomBox.inTransform"></search-input>
- </div>
- <button :title="$t('overall.createDatacenter')" @click="add" type="button" v-has="'dc_toAdd'"
- id="dc-add" class="top-tool-btn margin-l-20">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <button :title="$t('overall.createDatacenter')" @click="toDownloadAgent" type="button" id="load-agent" class="top-tool-btn margin-l-20">
- <i class="nz-icon-download nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" @before="delFlag=true" @after="getTableData" api="idc" v-has="'dc_delete'" id="dc-list-batch-delete"></delete-button>
- <button id="account-column-setting" class="top-tool-btn margin-l-10"
- type="button" @click="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)">
- <i class="nz-icon-gear nz-icon"></i>
- </button>
- </div>
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- id="dc-list"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
- <div class="nz-table2">
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.dc"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
+ <button id="dc-add" v-has="'dc_toAdd'" :title="$t('overall.createDatacenter')" class="top-tool-btn margin-l-20"
+ type="button" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="account-list-batch-delete" v-has="'dc_delete'" :delete-objs="batchDeleteObjs" api="dc" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
<el-table
- v-show="bottomBox.mainResizeShow"
id="dc-list-table"
- ref="dcTable"
+ ref="dataTable"
v-loading="tools.loading"
- :cell-class-name="assetStatClassName"
:data="tableData"
:height="mainTableHeight"
+ :cell-class-name="assetStatClassName"
border
- tooltip-effect="light"
+ @header-dragend="dragend"
@sort-change="tableDataSort"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
@@ -61,14 +38,23 @@
v-for="(item, index) in tools.customTableTitle"
v-if="item.show"
:key="`col-${index}`"
+ :fixed="item.fixed"
:label="item.label"
- :prop="$tableSet.propTitle(item.prop,'dc')"
+ :prop="item.prop"
:resizable="true"
- :sortable="sortableShow(item.prop,'dc')"
- show-overflow-tooltip
+ :sort-orders="['ascending', 'descending']"
+ :sortable="sortableShow(item.prop, fromRoute.dc)"
+ :width="`${item.width}`"
+ class="data-column"
>
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
<template slot-scope="scope" :column="item">
- <template v-if="item.prop == 'principal'">
+ <template v-if="item.prop === 'principal'">
<template v-if="scope.row.principal">
<template v-for="item in userData">
<template v-if="scope.row.principal == item.userId">{{item.username}}</template>
@@ -76,7 +62,7 @@
</template>
<template v-else>-</template>
</template>
- <template v-else-if="item.prop == 'state'">
+ <template v-else-if="item.prop === 'state'">
<el-switch
v-model="scope.row.state"
:disabled="!hasButton('dc_toEdit') || !hasButton('dc_toEdit')"
@@ -86,15 +72,15 @@
@change="(val)=>{statusChange(scope.row)}"
/>
</template>
- <template v-else-if="item.prop == 'longitude'">
+ <template v-else-if="item.prop === 'longitude'">
<template v-if="regNumTest(scope.row.longitude)">{{scope.row.longitude}}</template>
<template v-else>-</template>
</template>
- <template v-else-if="item.prop == 'latitude'">
+ <template v-else-if="item.prop === 'latitude'">
<template v-if="regNumTest(scope.row.latitude)">{{scope.row.latitude}}</template>
<template v-else>-</template>
</template>
- <template v-else-if="item.prop == 'assetStat' && scope.row.assetStat">
+ <template v-else-if="item.prop === 'assetStat' && scope.row.assetStat">
<el-popover
:content="$t('overall.result.total') + ':' + scope.row.assetStat.total + ',' + $t('asset.inStock') + ':' + scope.row.assetStat.inStock + ',' + $t('asset.notInStock') + ':' + scope.row.assetStat.outStock + ',' + $t('asset.suspended') + ':' + scope.row.assetStat.suspended"
placement="top"
@@ -108,30 +94,45 @@
</el-popover>
</template >
- <template v-else-if="item.prop == 'cabinetNum'">
- <span class="link" @click="showCabinet(scope.row)">{{scope.row[item.prop]}}</span>
+ <template v-else-if="item.prop === 'cabinetNum'">
+ <span class="link" @click="$refs.dataList.showBottomBox('cabinet', scope.row)">{{scope.row[item.prop]}}</span>
</template>
<template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
<template v-else>-</template>
</template>
</el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `dc?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </div>
+ </el-table-column>
</el-table>
- </div>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow" id="dc-list-totop"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
- <transition name="el-zoom-in-bottom">
- <bottom-box :detail="bottomBox.dcDetail" :from="$CONSTANTS.fromRoute.dc" :is-full-screen="bottomBox.isFullScreen" :obj="bottomBox.dc" :sub-resize-show="bottomBox.subResizeShow" :target-tab.sync="bottomBox.targetTab" v-if="bottomBox.showSubList"
- @closeSubList="bottomBox.showSubList = false" @fullScreen="fullScreen" @exitFullScreen="exitFullScreen" @listResize="listResize" ></bottom-box>
- </transition>
- <!--dc table end-->
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="dc-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<transition name="right-box">
- <dc-box @close="closeDcBox" :dc="dc" :user-data="userData" @reload="getTableData" v-if="rightBox.dc.show"></dc-box>
+ <dc-box v-if="rightBox.dc.show" :dc="object" :user-data="userData" @close="closeDcBox" @reload="getTableData"></dc-box>
</transition>
<transition name="right-box">
- <traffic-setting-box @close="closeTrafficBox" :dc="dc" ref="trafficBox" v-if="rightBox.trafficSetting.show"></traffic-setting-box>
+ <traffic-setting-box v-if="rightBox.trafficSetting.show" ref="trafficBox" :dc="object" @close="closeTrafficBox"></traffic-setting-box>
</transition>
<span v-if="dcDataRefresh" style="display: none"></span>
<el-dialog :visible.sync="showAgentDownload" width="620px" append-to-body class="nz-dialog agent-dialog" @close="closeDialog" :title="$t('config.dc.agent.title')">
@@ -181,54 +182,32 @@
</div>
</template>
<script>
-import bus from '../../../libs/bus'
-import dcBox from '../../common/rightBox/dcBox' // dc弹框
-import trafficSettingBox from '../../common/rightBox/trafficSetting/trafficSettingBox'
-import deleteButton from '../../common/deleteButton'
+import bus from '@/libs/bus'
+import dcBox from '@/components/common/rightBox/dcBox' // dc弹框
+import trafficSettingBox from '@/components/common/rightBox/trafficSetting/trafficSettingBox'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
const regNum = /^[0-9]+.?[0-9]*/
export default {
name: 'dc',
components: {
- 'traffic-setting-box': trafficSettingBox,
- 'dc-box': dcBox,
- 'delete-button': deleteButton
+ trafficSettingBox,
+ dcBox,
+ deleteButton,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
- /* 二级页面相关 */
- bottomBox: {
- dcDetail: {},
- dc: {},
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- batchDeleteObjs: [],
tableId: 'dcTable', // 需要分页的table的id,用于记录每页数量
- dc: {},
- blankDc: {
+ object: {},
+ blankObject: {
id: '',
name: '',
location: '',
tel: '',
principal: '',
- // area: {
- // id: 0,
- // name: ''
- // }
state: 'ON',
longitude: undefined,
latitude: undefined
@@ -237,11 +216,6 @@ export default {
dc: { show: false },
trafficSetting: { show: false }
},
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [
{
label: 'ID',
@@ -286,8 +260,6 @@ export default {
show: true
}
],
- tableData: [],
- userData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
@@ -298,9 +270,7 @@ export default {
disabled: false
}]
},
- searchLabel: {}, // 搜索参数
tabShow: 1, // 控制显示一级页面和二级页面 1 dc 2cabinet
- scrollbarWrap: null,
delFlag: false,
showAgentDownload:false,
token:'',
@@ -319,7 +289,8 @@ export default {
osType:"Centos",
dc:"",
type:1,
- }
+ },
+ userData: []
}
},
computed: {
@@ -369,15 +340,6 @@ export default {
}
return ''
},
- jumpTo (data, id) {
- bus.$emit('menu-change', data)
- this.$router.push({
- path: '/' + data,
- query: {
- t: +new Date()
- }
- })
- },
edit (u) {
this.dc = JSON.parse(JSON.stringify(u))
if (!regNum.test(this.dc.longitude)) {
@@ -391,67 +353,23 @@ export default {
}
this.rightBox.dc.show = true
},
- configTraffic (u) {
- this.dc = JSON.parse(JSON.stringify(u))
- this.rightBox.trafficSetting.show = true
- },
detail (u) {
- this.bottomBox.dc = JSON.parse(JSON.stringify(u))
- if (!this.bottomBox.dc.area) {
- this.$set(this.bottomBox.dc, 'area', { id: '', name: '' })
+ this.bottomBox.object = JSON.parse(JSON.stringify(u))
+ if (!this.bottomBox.object.area) {
+ this.$set(this.bottomBox.object, 'area', { id: '', name: '' })
}
this.bottomBox.targetTab = 'detail'
this.bottomBox.showSubList = true
},
- // 全屏
- fullScreen () {
- const vm = this
- this.$bottomBoxWindow.fullScreen(vm)
- },
- // 退出全屏
- exitFullScreen () {
- const vm = this
- this.$bottomBoxWindow.exitFullScreen(vm)
- },
- // 鼠标拖动二级列表
- listResize (e) {
- const vm = this
- this.$bottomBoxWindow.listResize(vm, e)
- },
- convertToDetail (obj) {
- const detail = JSON.parse(JSON.stringify(obj))
- return detail
- /* let detail = [];
- detail.push({label: this.$t("overall.name"), value: obj.name});
- detail.push({label: this.$t("config.dc.area"), value: obj.area.name});
- detail.push({label: this.$t("asset.location"), value: obj.location});
- detail.push({label: this.$t("config.dc.cabinetNum"), value: obj.cabinetNum});
- let assets = this.$t('overall.result.total') + ' ' + obj.assetStat.total + ',' + this.$t('asset.inStock') + ' ' + obj.assetStat.inStock + ',' + this.$t('asset.notInStock') + ' ' + obj.assetStat.outStock;
- detail.push({label: this.$t("config.dc.assets"), value: assets});
- detail.push({label: this.$t("asset.tel"), value: obj.tel});
- let principal = '';
- for (let i = 0; i < this.userData.length; i++) {
- if (this.userData[i].userId == obj.principal) {
- principal = this.userData[i].username;
- break;
- }
- }
- detail.push({label: this.$t("asset.principal"), value: principal});
- return detail; */
- },
add () {
- this.dc = this.newDc()
+ this.object = this.newObject()
this.rightBox.dc.show = true
},
- newDc () {
- return JSON.parse(JSON.stringify(this.blankDc))
- },
closeDcBox (refresh) {
this.rightBox.dc.show = false
if (refresh) {
this.delFlag = true
this.getTableData()
- bus.$emit('dc-list-change')
}
},
closeTrafficBox (refresh) {
@@ -461,24 +379,6 @@ export default {
this.getTableData()
}
},
- del (u) {
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('dc?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- bus.$emit('dc-list-change')
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
statusChange (idc) {
this.$put('dc', idc).then(response => {
if (response.code === 200) {
@@ -498,14 +398,14 @@ export default {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
- this.$get('idc', this.searchLabel).then(response => {
+ this.$get('dc', this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.dcTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
@@ -522,58 +422,6 @@ export default {
})
})
},
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.pageObj.pageSize = val
- this.getTableData()
- },
- search (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- if (this.$refs.dcTable && this.$refs.dcTable.bodyWrapper) {
- this.$refs.dcTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
- showCabinet (dc) {
- this.bottomBox.targetTab = 'cabinet'
- this.bottomBox.dc = JSON.parse(JSON.stringify(dc))
- this.bottomBox.showSubList = true
- },
- sortableShow (label, form) {
- if (label === 'state') {
- return false
- }
- return this.$tableSet.sortableShow(label, form)
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- },
regNumTest (val) { // 校验是否是数字
return regNum.test(val)
},
@@ -583,59 +431,11 @@ export default {
})
}
},
- watch: {
- 'bottomBox.dc': {
- deep: true,
- handler (n) {
- if (n.id) {
- this.bottomBox.dcDetail = this.convertToDetail(n)
- }
- }
- },
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- },
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
-
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.dcTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
- },
beforeDestroy () {
bus.$off('dc-list-change')
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- };
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
- destroyed () {
-
},
mounted () {
this.getUserData()
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- // this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
- this.getTableData()
- this.getAllDc();
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/exprTemp.vue b/nezha-fronted/src/components/page/config/exprTemp.vue
index 1e9607bc9..986a133ae 100644
--- a/nezha-fronted/src/components/page/config/exprTemp.vue
+++ b/nezha-fronted/src/components/page/config/exprTemp.vue
@@ -1,126 +1,103 @@
<template>
- <div class="main-list main-and-sub-transition" :class="{'main-list-with-sub': bottomBox.showSubList}">
- <!--工具组-->
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}">
- <div class="top-tool-search margin-r-20">
- <search-input :searchMsg="searchMsg" @search="search"
- :inTransform="bottomBox.inTransform" :single="true"></search-input>
- </div>
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.expressionTemplate"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
<export-excel
- id="asset-list"
- export-file-name="asset"
+ id="expression-template-list"
+ class="top-tool-export margin-l-20"
export-url="expression/tmpl/export"
import-url="expression/tmpl/import"
+ export-file-name="expression-template"
:params="searchLabel"
:permissions="{import: 'asset_import', export: 'asset_export'}"
- @afterImport="afterTableListChange"
+ @afterImport="getTableData"
v-has="'expr_temp_save'"
>
<template slot="optionZone">
- <button :title="$t('overall.exportExcelLower')" @click="addTemp" type="button" v-has="'expr_temp_save'"
- class="nz-btn nz-btn-size-normal nz-btn-style-light" id="alert-list-export">
+ <button id="expr-tmpl-list-export" v-has="'expr_temp_save'" :title="$t('overall.createTemplate')" class="top-tool-btn"
+ type="button" @click="add">
<i class="nz-icon nz-icon-create-square"></i>
</button>
</template>
</export-excel>
- <delete-button :delete-objs="batchDeleteObjs" @after="getexprTemp"
+ <delete-button :delete-objs="batchDeleteObjs" @after="getTableData"
:api="'expression/tmpl'" v-has="'expr_temp_delete'" id="alert-msg-batch-delete"></delete-button>
- </div>
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!--表格开始-->
- <transition name="el-zoom-in-top">
- <element-set
- id="alert-rule-element-set"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
- <el-table
- id="alert-rule-table"
- class="nz-table"
- :data="tableData"
- border
- v-show="bottomBox.mainResizeShow"
- ref="exprTempTable"
- tooltip-effect="light"
- :height="mainTableHeight"
- v-loading="tools.loading"
- style="width: 100%;"
- @sort-change="tableDataSort"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
- >
- <el-table-column
- :resizable="false"
- type="selection"
- width="40"
- align="center">
- </el-table-column>
-
- <el-table-column
- :resizable="true"
- v-for="(item, index) in tools.customTableTitle"
- v-if="item.show"
- :key="`col-${index}`"
- :label="item.label"
- :show-overflow-tooltip="item.prop!=='matchers'"
- :sort-orders="['ascending', 'descending']"
- :sortable="$tableSet.sortableShow(item.prop,'exprTemp')"
- :prop="$tableSet.propTitle(item.prop,'exprTemp')"
- :width="item.width"
- >
- <template slot-scope="scope" :column="item">
- <div v-if="item.prop == 'option'" class="content-right-options">
- <span :id="'alert-edit-'+scope.row.id" :title="$t('overall.edit')" @click.stop="edit(scope.row)"
- class="content-right-option" v-has="'expr_temp_update'" v-if="scope.row.buildIn !== 1">
- <i class="nz-icon nz-icon-edit"></i>
- </span>
- <span
- :id="'alert-del-'+scope.row.id"
- :title="$t('overall.delete')"
- @click="del(scope.row)"
- class="content-right-option"
- v-has="'expr_temp_delete'"
- v-if="scope.row.buildIn !== 1">
- <i class="nz-icon nz-icon-delete"></i>
- </span>
- <span
- :id="'alert-copy-'+scope.row.id"
- :title="$t('overall.copy')"
- @click="copyRow(scope.row,'exprTemp')"
- class="content-right-option"
- v-has="'expr_temp_save'">
- <i class="nz-icon nz-icon-override"></i>
- </span>
- </div>
- <span v-else-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
- <template v-else>-</template>
- </template>
- </el-table-column>
-
- <el-table-column width="28" :resizable="false">
- <template slot="header">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)"
- class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
- </el-table-column>
- </el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}"
- @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow"
- id="alert-rule-toTop"><i class="nz-icon nz-icon-top"></i></button>
- <!--表格结束-->
- <!--分页部分-->
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize'
- ref="Pagination"></Pagination>
- </div>
+ </template>
+ <template v-slot:default="slotProps">
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <span v-if="scope.row[item.prop]">{{scope.row[item.prop] || '-'}}</span>
+ <template v-else>-</template>
+ </template>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['copy', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-override"></i><span class="operation-dropdown-text">{{$t('config.exprTemp.copy')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `sys/role?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </div>
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<!--导出-->
<div class="export-xlsx">
<el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false'
@@ -137,56 +114,33 @@
</div>
<!--侧滑-->
<transition name="right-box">
- <exprTempBox v-if="rightBox.show" :exprTemp="exprTemp" @close="closeRightBox"
- ref="exprTempBox"></exprTempBox>
+ <exprTempBox v-if="rightBox.show" ref="exprTempBox" :exprTemp="object"
+ @close="closeRightBox"></exprTempBox>
</transition>
</div>
</template>
<script>
-import bus from '../../../libs/bus'
-import exportXLSX from '../../common/exportXLSX'
-import deleteButton from '../../common/deleteButton'
-import exprTempBox from '../../common/rightBox/exprTempBox'
-import { calcDurationByStringTimeB } from '../../common/js/tools'
+import bus from '@/libs/bus'
+import exportXLSX from '@/components/common/exportXLSX'
+import exprTempBox from '@/components/common/rightBox/exprTempBox'
+import { calcDurationByStringTimeB } from '@/components/common/js/tools'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
+
export default {
name: 'exprTemp',
components: {
deleteButton,
exprTempBox,
+ nzDataList,
'export-excel': exportXLSX
},
+ mixins: [tableMixin],
data () {
return {
tableId: 'exprTemp',
- // 侧滑
- rightBox: {
- show: false
- },
- /* 二级列表相关 */
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- /* 二级页面相关 */
- bottomBox: {
- tabList: [], // 二级列表的标签
- tabDetailList: [], // 多个详情
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- /* 批量删除相关 */
- batchDeleteObjs: [],
/* 搜素相关 */
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
@@ -212,12 +166,6 @@ export default {
}
]
},
- searchLabel: {}, // 搜索参数
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
/* 表格相关 */
tableTitle: [
{
@@ -241,26 +189,19 @@ export default {
label: this.$t('config.exprTemp.remark'),
prop: 'remark',
show: true
- }, {
- label: this.$t('alert.config.option'),
- prop: 'option',
- show: true,
- width: 120
}
],
- tableData: [],
// 导出相关
importBox: { show: false, title: this.$t('overall.exportExcel') },
deleteBox: { show: false, ids: '', remark: '', state: 2 },
// 创建修改相关
- blackExprTemp: {
+ blankObject: {
id: '',
name: '',
gname: '',
expression: '',
remark: ''
},
- exprTemp: {},
nowTime: ''
}
},
@@ -274,31 +215,22 @@ export default {
}
}
},
- created () {
-
- },
mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
this.initEvent()
- this.getexprTemp()
},
methods: {
initEvent () {
bus.$on('alert-rule-list-change', () => {
- this.getexprTemp()
+ this.getTableData()
})
bus.$on('dc-list-change', () => {
- this.getexprTemp()
+ this.getTableData()
})
bus.$on('alert-message-change', () => {
- this.getexprTemp()
+ this.getTableData()
})
},
- getexprTemp () {
+ getTableData () {
if (!this.hasButton('rule_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
@@ -314,55 +246,13 @@ export default {
this.nowTime = this.utcTimeToTimezoneStr(response.time)
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.exprTempTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getexprTemp()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getexprTemp()
- },
- search (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- this.$refs.exprTempTable.bodyWrapper.scrollTop = 0
- this.getexprTemp()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getexprTemp()
- },
- openDelMessageBox () {
- // if (this.batchDeleteObjs.length < 1) return
- },
showExportDialog () {
this.importBox.show = true
},
@@ -383,48 +273,10 @@ export default {
this.exportExcel(temp)
this.closeDialog()
},
- afterTableListChange () {
- this.getexprTemp()
- },
- addTemp () {
- this.exprTemp = JSON.parse(JSON.stringify(this.blackExprTemp))
- this.rightBox.show = true
- },
- edit (row) {
- this.$get('expression/tmpl/' + row.id).then(res => {
- this.exprTemp = { ...res.data }
- this.rightBox.show = true
- })
- },
- del (row) {
- if (this.prevent_opt.save) {
- return
- }
- ;
- this.prevent_opt.save = true
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('expression/tmpl?ids=' + row.id).then(response => {
- this.prevent_opt.save = false
- if (response.code === 200) {
- this.$message({ type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getexprTemp()
- } else {
- this.$message.error(response.msg)
- }
- })
- }).catch(() => {
- this.prevent_opt.save = false
- })
- },
overtime (row) {
if (this.prevent_opt.save) {
return
}
- ;
this.prevent_opt.save = true
this.$confirm(this.$t('tip.confirmOvertime'), {
confirmButtonText: this.$t('tip.yes'),
@@ -435,7 +287,7 @@ export default {
this.prevent_opt.save = false
if (response.code === 200) {
this.$message({ type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getexprTemp()
+ this.getTableData()
} else {
this.$message.error(response.msg)
}
@@ -443,18 +295,7 @@ export default {
}).catch(() => {
this.prevent_opt.save = false
})
- },
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getexprTemp()
- }
}
}
}
</script>
-
-<style scoped lang="scss">
-
-</style>
diff --git a/nezha-fronted/src/components/page/config/mib.vue b/nezha-fronted/src/components/page/config/mib.vue
index 77b795773..8cadc9c9c 100644
--- a/nezha-fronted/src/components/page/config/mib.vue
+++ b/nezha-fronted/src/components/page/config/mib.vue
@@ -1,155 +1,165 @@
-<style scoped>
- .mib {
- height: 100%;
- }
-</style>
<template>
- <div class="mib">
- <template v-if="showTab == 'file'">
- <div class="top-tools">
- <div class="nz-tab top-tool-main-right top-tool-main-right-to-left-little" style="width: 300px">
- <div class="nz-tab-item-box" id="module-type-1">
- <div class="nz-tab-item nz-tab-item-active">{{$t("config.mib.mibFiles")}}</div>
- </div>
- <div @click="showTab = 'browser'" class="nz-tab-item-box" id="module-type-2" v-has="'snmp_browser_view'">
- <div class="nz-tab-item">{{$t("config.mib.mibBrowser")}}</div>
- </div>
+ <div style="height: 100%">
+ <nz-data-list
+ v-if="showTab === 'file'"
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.mib"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-left>
+ <div id="module-type-1" class="nz-tab-item-box">
+ <div class="nz-tab-item nz-tab-item-active">{{$t("config.mib.mibFiles")}}</div>
</div>
- <div class="top-tool-main-right">
- <div class="top-tool-search">
- <search-input :searchMsg="searchMsg" @search="search"></search-input>
- </div>
- <button :title="$t('overall.createMib')" @click="add" class="nz-btn nz-btn-size-normal nz-btn-style-light margin-l-20" id="mib-add" type="button" v-has="'snmp_file_toAdd'">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true" api="mib" v-has="'snmp_file_delete'" id="mib-list-batch-delete"></delete-button>
+ <div id="module-type-2" v-has="'snmp_browser_view'" class="nz-tab-item-box" @click="showTab = 'browser'">
+ <div class="nz-tab-item">{{$t("config.mib.mibBrowser")}}</div>
</div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- id="mib-list"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
- <el-table :data="tableData" :height="$tableHeight.normal" @sort-change="tableDataSort" border class="nz-table mib-table" ref="mibTable" style="width: 100%;" v-loading="tools.loading" id="mib-list-table"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
- >
- <el-table-column
- :resizable="false"
- type="selection"
- width="40"
- align="center">
- </el-table-column>
- <el-table-column :resizable="true" v-for="(item, index) in tools.customTableTitle" v-if="item.show" :class-name="item.prop == 'modelsDetail'?'detail-column':''"
- :key="`col-${index}`" :label="item.label" :sortable="$tableSet.sortableShow(item.prop,'mib')"
- :prop="$tableSet.propTitle(item.prop,'mib')"
- :sort-orders="['ascending', 'descending']">
- <template slot-scope="scope" :column="item">
- <template v-if="item.prop == 'updateUser'" >{{scope.row[item.prop].name}}</template>
- <template v-else-if="item.prop == 'fileName' && scope.row[item.prop]" >
- <span @click="downloadMib(scope.row)" class="link">{{scope.row[item.prop]}}</span>
+ </template>
+ <template v-slot:top-tool-right>
+ <button id="mib-add" v-has="'snmp_file_toAdd'" :title="$t('overall.createMib')" class="top-tool-btn margin-l-20" type="button" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="mib-list-batch-delete" v-has="'snmp_file_delete'" :delete-objs="batchDeleteObjs" api="mib" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
</template>
- <template v-else-if="item.prop == 'modelsDetail' && scope.row['modelsDetail'] && scope.row['modelsDetail'].length >0" >
- <div style="height: 100%">
- <div style="height: 100%; overflow: auto;">
- <div v-for="(n,i) in scope.row['modelsDetail']" :key="n.name+'-'+n.id+'-'+i" class="detail-item-content">
- <el-popover trigger="hover" placement="top" >
- <div>
- <div>
- <span>{{$t('overall.name')}}:</span>
- <span>{{n.name}}</span>
- </div>
+ <template slot-scope="scope" :column="item">
+ <template v-if="item.prop == 'updateUser'" >{{scope.row[item.prop].name}}</template>
+ <template v-else-if="item.prop == 'fileName' && scope.row[item.prop]" >
+ <span class="link" @click="downloadMib(scope.row)">{{scope.row[item.prop]}}</span>
+ </template>
+ <template v-else-if="item.prop === 'modelsDetail' && scope.row['modelsDetail'] && scope.row['modelsDetail'].length >0" >
+ <div style="height: 100%">
+ <div style="height: 100%; overflow: auto;">
+ <div v-for="(n,i) in scope.row['modelsDetail']" :key="n.name+'-'+n.id+'-'+i" class="detail-item-content">
+ <el-popover placement="top" trigger="hover" >
<div>
- <span>{{$t('config.mib.vendor')}}:</span>
- <span>{{n.vendor}}</span>
+ <div>
+ <span>{{$t('overall.name')}}:</span>
+ <span>{{n.name}}</span>
+ </div>
+ <div>
+ <span>{{$t('config.mib.vendor')}}:</span>
+ <span>{{n.vendor}}</span>
+ </div>
+ <div>
+ <span>{{$t('config.mib.type')}}:</span>
+ <span>{{n.type}}</span>
+ </div>
</div>
- <div>
- <span>{{$t('config.mib.type')}}:</span>
- <span>{{n.type}}</span>
- </div>
- </div>
- <template slot="reference">
- <div class="detail-item-content" v-if="i < scope.row['modelsDetail'].length-1">{{n.name}},</div>
- <div class="detail-item-content" v-else>{{n.name}}</div>
- </template>
- </el-popover>
+ <template slot="reference">
+ <div v-if="i < scope.row['modelsDetail'].length-1" class="detail-item-content">{{n.name}},</div>
+ <div v-else class="detail-item-content">{{n.name}}</div>
+ </template>
+ </el-popover>
+ </div>
</div>
</div>
- </div>
+ </template>
+ <span v-else-if="item.prop === 'updateAt'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
+ <template v-else>-</template>
</template>
- <span v-else-if="item.prop == 'updateAt'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
- <div v-else-if="item.prop == 'option'" class="content-right-options">
- <span :id="'mib-download-'+scope.row.id" :title="$t('overall.download')" @click="downloadMib(scope.row)" class="content-right-option" v-has="'snmp_file_download'"><i class="nz-icon nz-icon-download1"></i></span>
- &nbsp;
- <span :id="'mib-edit-'+scope.row.id" :title="$t('overall.edit')" @click="edit(scope.row)" class="content-right-option" v-has="'snmp_file_toEdit'"><i class="nz-icon nz-icon-edit"></i></span>
- &nbsp;
- <span :id="'mib-del-'+scope.row.id" :title="$t('overall.delete')" @click="del(scope.row)" class="content-right-option" v-has="'snmp_file_delete'"><i class="nz-icon nz-icon-delete"></i></span>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item v-has="'snmp_file_download'" :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['download', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-download1"></i><span class="operation-dropdown-text">{{$t('overall.download')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `mib?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
</div>
- <template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
- <template v-else>-</template>
- </template>
- </el-table-column>
- <el-table-column :resizable="false" width="28">
- <template slot="header">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
- </el-table-column>
- </el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn" id="mib-list-totop"><i class="nz-icon nz-icon-top"></i></button>
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </template>
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<mib-browser :show-tab="showTab" v-if="showTab == 'browser'" @toFileTab="showTab = 'file'"></mib-browser>
<transition name="right-box">
- <mib-box v-if="rightBox.show" ref="mibBox" :mib="mib" @reload="getTableData" @close="closeRightBox"></mib-box>
+ <mib-box v-if="rightBox.show" ref="mibBox" :mib="object" @close="closeRightBox" @reload="getTableData"></mib-box>
</transition>
</div>
-
</template>
<script>
import axios from 'axios'
-import bus from '../../../libs/bus'
import mibBrowser from './mibBrowser'
-import deleteButton from '../../common/deleteButton'
+import mibBox from '@/components/common/rightBox/mibBox'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
+
export default {
name: 'mib',
components: {
- 'mib-browser': mibBrowser,
- 'delete-button': deleteButton
+ mibBox,
+ mibBrowser,
+ deleteButton,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
showTab: 'file', // file/browser
- rightBox: { show: false },
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- batchDeleteObjs: [],
tableId: 'mibTable', // 需要分页的table的id,用于记录每页数量
- mib: {},
- blankMib: {
+ object: {},
+ blankObject: {
id: null,
name: '',
remark: '',
models: '',
file: null
},
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [
{
label: 'ID',
@@ -180,14 +190,8 @@ export default {
label: this.$t('config.mib.updateAt'),
prop: 'updateAt',
show: true
- }, {
- label: this.$t('config.account.option'),
- prop: 'option',
- show: true,
- width: 120
}
],
- tableData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
@@ -203,60 +207,10 @@ export default {
label: 'name',
disabled: false
}]
- },
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null,
- delFlag: false
+ }
}
},
methods: {
- clickOutside () {
- this.rightBox.show = false
- },
- edit (u) {
- this.mib = JSON.parse(JSON.stringify(u))
- this.rightBox.show = true
- },
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getTableData()
- }
- },
- del (u) {
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('mib?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
- add () {
- this.mib = this.newMib()
- this.rightBox.show = true
- },
- newMib () {
- return JSON.parse(JSON.stringify(this.blankMib))
- },
- jumpTo (data, id) {
- bus.$emit('menu-change', data)
- this.$router.push({
- path: '/' + data,
- query: {
- t: +new Date()
- }
- })
- },
getTableData () {
if (!this.hasButton('snmp_file_view')) {
this.$message.error(this.$t('tip.noAccess'))
@@ -273,42 +227,13 @@ export default {
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.mibTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.pageObj.pageNo = 1
- this.searchLabel = {}
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- if (this.$refs.mibTable && this.$refs.mibTable.bodyWrapper) {
- this.$refs.mibTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
downloadMib (mib) {
if (!this.hasButton('snmp_file_download')) {
return
@@ -335,55 +260,7 @@ export default {
window.URL.revokeObjectURL(link.href)
}
})
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- watch: {
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.mibTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
}
- },
- mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
-
- this.getTableData()
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- };
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/model.vue b/nezha-fronted/src/components/page/config/model.vue
index 1fccaac01..4f2959bd3 100644
--- a/nezha-fronted/src/components/page/config/model.vue
+++ b/nezha-fronted/src/components/page/config/model.vue
@@ -1,49 +1,30 @@
-<style lang="scss">
-@import '@/assets/css/common/tableCommon.scss';
-</style>
<template>
- <div class="model list-page">
- <div class="main-list" :class="{'main-list-with-sub': bottomBox.showSubList}">
- <div class="main-modal"></div>
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div class="top-tool-main-right" :class="{'top-tool-main-right-to-left-small': bottomBox.showSubList}">
- <div class="top-tool-search">
- <search-input :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search"></search-input>
- </div>
- <button id="model-add" v-has="'model_toAdd'" :title="$t('overall.createModel')" class="top-tool-btn margin-l-20" @click="add">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true" api="model" v-has="'model_delete'" id="model-list-batch-delete"></delete-button>
- <button id="account-column-setting" class="top-tool-btn margin-l-10"
- type="button" @click="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)">
- <i class="nz-icon-gear nz-icon"></i>
- </button>
- </div>
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- id="model-list"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
- <div class="nz-table2">
- <el-table v-show="bottomBox.mainResizeShow"
- id="model-list-table"
- ref="modelTable"
- v-loading="tools.loading"
- :cell-class-name="assetStatClassName"
- :data="tableData"
- :height="mainTableHeight"
- border
- @sort-change="tableDataSort"
- @row-dblclick="panel"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.model"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
+ <button id="model-add" v-has="'model_toAdd'" :title="$t('overall.createModel')" class="top-tool-btn margin-l-20" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="model-list-batch-delete" v-has="'model_delete'" :delete-objs="batchDeleteObjs" api="model" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
+ <el-table
+ id="model-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
@@ -51,89 +32,94 @@
type="selection"
width="55">
</el-table-column>
- <el-table-column v-for="(item, index) in tools.customTableTitle"
- v-if="item.show"
- :key="`col-${index}`"
- :label="item.label"
- :prop="$tableSet.propTitle(item.prop,'model')"
- :resizable="true"
- :sort-orders="['ascending', 'descending']"
- :sortable="$tableSet.sortableShow(item.prop,'model')">
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
<template slot-scope="scope" :column="item">
- <template v-if="item.prop == 'vendor'" >{{scope.row[item.prop].value}}</template>
- <template v-else-if="item.prop == 'type'" >{{scope.row[item.prop].value}}</template>
- <template v-else-if="item.prop == 'assetStat' && scope.row.assetStat" >
+ <template v-if="item.prop === 'vendor'" >{{scope.row[item.prop].value}}</template>
+ <template v-else-if="item.prop === 'type'" >{{scope.row[item.prop].value}}</template>
+ <template v-else-if="item.prop === 'assetStat' && scope.row.assetStat" >
<el-popover
:content="$t('overall.result.total') + ':' + scope.row.assetStat.total + ',' + $t('asset.inStock') + ':' + scope.row.assetStat.inStock + ',' + $t('asset.notInStock') + ':' + scope.row.assetStat.outStock + ',' + $t('asset.suspended') + ':' + scope.row.assetStat.suspended"
placement="top"
trigger="hover">
- <div slot="reference" class="dc-asset-states">
- <span class="dc-asset-state dc-asset-state-total">{{scope.row.assetStat.total}}</span>
- <span class="dc-asset-state dc-asset-state-in">{{scope.row.assetStat.inStock}}</span>
- <span class="dc-asset-state dc-asset-state-out">{{scope.row.assetStat.outStock}}</span>
- <span class="dc-asset-state dc-asset-state-suspended">{{scope.row.assetStat.suspended}}</span>
- </div>
- </el-popover>
+ <div slot="reference" class="dc-asset-states">
+ <span class="dc-asset-state dc-asset-state-total">{{scope.row.assetStat.total}}</span>
+ <span class="dc-asset-state dc-asset-state-in">{{scope.row.assetStat.inStock}}</span>
+ <span class="dc-asset-state dc-asset-state-out">{{scope.row.assetStat.outStock}}</span>
+ <span class="dc-asset-state dc-asset-state-suspended">{{scope.row.assetStat.suspended}}</span>
+ </div>
+ </el-popover>
</template>
<template v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</template>
<template v-else>-</template>
</template>
</el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `sys/role?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </div>
+ </el-table-column>
</el-table>
- </div>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn" id="model-list-totop"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
- <transition name="el-zoom-in-bottom">
- <bottom-box :from="$CONSTANTS.fromRoute.model" :is-fullscreen="bottomBox.isFullScreen" :obj="bottomBox.model" :sub-resize-show="bottomBox.subResizeShow" :target-tab.sync="bottomBox.targetTab" v-if="bottomBox.showSubList"
- @closeSubList="bottomBox.showSubList = false" @fullScreen="fullScreen" @exitFullScreen="exitFullScreen" @listResize="listResize" ref="panelBox"></bottom-box>
- </transition>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<transition name="right-box">
- <model-box v-if="rightBox.show" ref="modelBox" :model="model" @close="closeRightBox" @reload="getTableData"></model-box>
+ <model-box v-if="rightBox.show" ref="modelBox" :model="object" @close="closeRightBox" @reload="getTableData"></model-box>
</transition>
</div>
-
</template>
<script>
-import bus from '../../../libs/bus'
-import deleteButton from '../../common/deleteButton'
+import modelBox from '@/components/common/rightBox/modelBox'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
name: 'model',
components: {
- 'delete-button': deleteButton
+ deleteButton,
+ modelBox,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
- /* 二级页面相关 */
- bottomBox: {
- modelDetail: {}, // asset详情
- model: {}, // 告警信息对应的asset对象
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- batchDeleteObjs: [],
tableId: 'modelTable', // 需要分页的table的id,用于记录每页数量
- rightBox: { show: false },
-
- model: {},
- blankModel: {
+ blankObject: {
id: '',
name: '',
vendor: { id: '', value: '', code: '', type: '' },
@@ -144,11 +130,6 @@ export default {
typeCode: '',
uSize: 1
},
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [
{
label: 'ID',
@@ -173,7 +154,6 @@ export default {
show: true
}
],
- tableData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
@@ -189,10 +169,7 @@ export default {
label: 'dc',
disabled: false
}]
- },
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null,
- delFlag: false
+ }
}
},
methods: {
@@ -210,65 +187,6 @@ export default {
this.bottomBox.model = obj
this.bottomBox.targetTab = 'panel'
},
- // 全屏
- fullScreen () {
- const vm = this
- this.$bottomBoxWindow.fullScreen(vm)
- },
- // 退出全屏
- exitFullScreen () {
- const vm = this
- this.$bottomBoxWindow.exitFullScreen(vm)
- },
- // 鼠标拖动二级列表
- listResize (e) {
- const vm = this
- this.$bottomBoxWindow.listResize(vm, e)
- },
- edit (u) {
- this.model = Object.assign({}, u)
- this.rightBox.show = true
- },
- del (u) {
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('model?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
- add () {
- this.model = this.newModel()
- this.rightBox.show = true
- },
- newModel () {
- return JSON.parse(JSON.stringify(this.blankModel))
- },
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getTableData()
- }
- },
- jumpTo (data, id) {
- bus.$emit('menu-change', data)
- this.$router.push({
- path: '/' + data,
- query: {
- t: +new Date()
- }
- })
- },
getTableData () {
if (!this.hasButton('model_view')) {
this.$message.error(this.$t('tip.noAccess'))
@@ -285,94 +203,12 @@ export default {
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.modelTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
- },
- pageNo (val) {
- console.info(val)
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.pageObj.pageNo = 1
- this.searchLabel = {}
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- if (this.$refs.modelTable && this.$refs.modelTable.bodyWrapper) {
- this.$refs.modelTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
- mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
-
- this.getTableData()
- },
- watch: {
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- },
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.modelTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
}
}
}
diff --git a/nezha-fronted/src/components/page/config/operationLog.vue b/nezha-fronted/src/components/page/config/operationLog.vue
new file mode 100644
index 000000000..a351daa8d
--- /dev/null
+++ b/nezha-fronted/src/components/page/config/operationLog.vue
@@ -0,0 +1,208 @@
+<template>
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle"
+ :from="fromRoute.operationLog">
+ <template v-slot:default="slotProps">
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <span v-if="item.prop === 'time'">
+ {{scope.row[item.prop]}} ms
+ </span>
+ <span v-else-if="item.prop === 'username'">{{formatUsername(scope.row)}}</span>
+ <span v-else-if="item.prop === 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
+ </div>
+</template>
+<script>
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
+
+export default {
+ name: 'oparetionlog',
+ components: {
+ nzDataList
+ },
+ mixins: [tableMixin],
+ data () {
+ return {
+ tableId: 'operationLogTable', // 需要分页的table的id,用于记录每页数量
+ tableTitle: [
+ {
+ label: this.$t('config.operationlog.id'),
+ prop: 'id',
+ show: true,
+ width: 80
+ }, {
+ label: this.$t('config.operationlog.username'),
+ prop: 'username',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.ip'),
+ prop: 'ip',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.operation'),
+ prop: 'operation',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.type'),
+ prop: 'type',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.state'),
+ prop: 'state',
+ show: true
+ },
+ // {
+ // label: this.$t('config.operationlog.userId'),
+ // prop: 'userId',
+ // show: false,
+ // },
+ {
+ label: this.$t('config.operationlog.operaId'),
+ prop: 'operaId',
+ show: false
+ },
+ {
+ label: this.$t('config.operationlog.createDate'),
+ prop: 'createDate',
+ show: true
+ },
+ {
+ label: this.$t('config.operationlog.time'),
+ prop: 'time',
+ show: false
+ },
+ {
+ label: this.$t('config.operationlog.params'),
+ prop: 'params',
+ show: false
+ },
+ {
+ label: this.$t('config.operationlog.response'),
+ prop: 'response',
+ show: false
+ }
+ ],
+ searchMsg: { // 给搜索框子组件传递的信息
+ zheze_none: true,
+ searchLabelList: [
+ {
+ id: 11,
+ name: this.$t('config.operationlog.type'),
+ type: 'input',
+ label: 'type',
+ disabled: false
+ }, {
+ id: 12,
+ name: this.$t('config.operationlog.username'),
+ type: 'input',
+ label: 'username',
+ disabled: false
+ }, {
+ id: 13,
+ name: this.$t('config.operationlog.operation'),
+ type: 'selectString',
+ label: 'operation',
+ disabled: false
+ }
+ ]
+ }
+ }
+ },
+ methods: {
+ messageStyle (e) {
+ if (e.column.label === this.$t('config.operationlog.state')) {
+ if (e.row.state === 'success') {
+ return 'success'
+ } else {
+ return 'danger'
+ }
+ }
+ return ''
+ },
+ getTableData () {
+ this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
+ this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
+ this.tools.loading = true
+ this.$get('sys/log/list', this.searchLabel).then(response => {
+ this.tools.loading = false
+ if (response.code === 200) {
+ this.tableData = response.data.list
+ this.pageObj.total = response.data.total
+ if (!this.scrollbarWrap) {
+ this.$nextTick(() => {
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
+ this.toTopBtnHandler(this.scrollbarWrap)
+ })
+ }
+ }
+ })
+ },
+ formatUsername (row) {
+ if (row.username) {
+ return row.username
+ } else if (row.operation === 'login' && !row.username) { // 如果是登录 且登录失败
+ return JSON.parse(row.params).username
+ } else {
+ return '-'
+ }
+ }
+ }
+}
+</script>
diff --git a/nezha-fronted/src/components/page/config/operationlog.vue b/nezha-fronted/src/components/page/config/operationlog.vue
index ad28d7222..021b4ed3a 100644
--- a/nezha-fronted/src/components/page/config/operationlog.vue
+++ b/nezha-fronted/src/components/page/config/operationlog.vue
@@ -1,112 +1,82 @@
-<style scoped>
- .operationlog {
- height: 100%;
- }
-</style>
<template>
- <div class="operationlog">
- <div class="top-tools">
- <div></div>
- <div>
- <div class="top-tool-search margin-r-5">
- <search-input :searchMsg="searchMsg" @search="search"></search-input>
- </div>
- </div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- id="operation-log-list"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
- <el-table
- id="operation-log-list-table"
- class="nz-table"
- :data="tableData"
- border
- ref="operationLogTable"
- :height="$tableHeight.normal"
- v-loading="tools.loading"
- :cell-class-name="messageStyle"
- style="width: 100%;"
- @sort-change="tableDataSort"
- >
- <el-table-column
- :resizable="true"
- v-for="(item, index) in tools.customTableTitle"
- v-if="item.show"
- :key="`col-${index}`"
- :label="item.label"
- :sortable="$tableSet.sortableShow(item.prop,'operationlog')"
- :prop="$tableSet.propTitle(item.prop,'operationlog')"
- :sort-orders="['ascending', 'descending']"
- >
- <template slot-scope="scope" :column="item">
- <span v-if="item.prop == 'time'">
- {{scope.row[item.prop]}} ms
- </span>
- <span v-else-if="item.prop == 'username'">{{formatUsername(scope.row)}}</span>
- <span v-else-if="item.prop == 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
- <span v-else>{{scope.row[item.prop]}}</span>
- </template>
- </el-table-column>
- <el-table-column width="28">
- <template slot="header">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
- </el-table-column>
- </el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn" id="operation-log-totop"><i class="nz-icon nz-icon-top"></i></button>
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.operationLog"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:default="slotProps">
+ <el-table
+ id="role-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <span v-if="item.prop === 'time'">
+ {{scope.row[item.prop]}} ms
+ </span>
+ <span v-else-if="item.prop === 'username'">{{formatUsername(scope.row)}}</span>
+ <span v-else-if="item.prop === 'createDate'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
</div>
</template>
<script>
-import bus from '../../../libs/bus'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
+
export default {
name: 'oparetionlog',
+ components: {
+ nzDataList
+ },
+ mixins: [tableMixin],
data () {
return {
tableId: 'operationLogTable', // 需要分页的table的id,用于记录每页数量
-
- rightBox: { // 弹出框相关
- show: false
- },
- rightBoxResize: { // resize弹出框相关
- show: false,
- isAdd: false, // false,true:resize
- title: ''
- },
- rightBoxDownload: { // 下载弹出框相关
- show: false,
- isAdd: false, // false,true:resize
- title: ''
- },
- rightBoxUpload: { // 上传弹出框相关
- show: false,
- isAdd: false, // false,true:resize
- title: ''
- },
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [
{
label: this.$t('config.operationlog.id'),
@@ -169,7 +139,6 @@ export default {
show: false
}
],
- tableData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [
@@ -193,15 +162,13 @@ export default {
disabled: false
}
]
- },
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null
+ }
}
},
methods: {
messageStyle (e) {
- if (e.column.label == this.$t('config.operationlog.state')) {
- if (e.row.state == 'success') {
+ if (e.column.label === this.$t('config.operationlog.state')) {
+ if (e.row.state === 'success') {
return 'success'
} else {
return 'danger'
@@ -209,7 +176,7 @@ export default {
}
return ''
},
- getTableData: function () {
+ getTableData () {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
@@ -220,22 +187,13 @@ export default {
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.operationLogTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
formatUsername (row) {
if (row.username) {
return row.username
@@ -244,70 +202,7 @@ export default {
} else {
return '-'
}
- },
- search: function (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- this.getTableData()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- watch: {
- tableData () {
- if (this.$refs.operationLogTable && this.$refs.operationLogTable.bodyWrapper) {
- this.$refs.operationLogTable.bodyWrapper.scrollTop = 0
- }
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- };
- },
- computed: {
- isCurrentUser () {
- return function (username) {
- return localStorage.getItem('nz-username') == username
- }
}
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
- mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
- this.getTableData()
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/promServer.vue b/nezha-fronted/src/components/page/config/promServer.vue
index 71943db10..65a797ea8 100644
--- a/nezha-fronted/src/components/page/config/promServer.vue
+++ b/nezha-fronted/src/components/page/config/promServer.vue
@@ -1,42 +1,29 @@
-<style lang="scss">
-@import '@/assets/css/common/tableCommon.scss';
-</style>
<template>
- <div class="prom list-page">
- <div class="main-list" :class="{'main-list-with-sub': bottomBox.showSubList}">
- <div class="main-modal"></div>
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}">
- <div class="top-tool-search">
- <search-input ref="searchInput" :searchMsg="searchMsg" @search="search" :inTransform="bottomBox.inTransform"></search-input>
- </div>
- <button :title="$t('overall.createPrometheusServer')" @click="add" type="button" v-has="'prom_toAdd'"
- id="prom-add" class="top-tool-btn margin-l-20">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true" api="promServer" v-has="'prom_delete'" id="promserver-list-batch-delete"></delete-button>
- <button id="prom-column-setting" class="top-tool-btn margin-l-10"
- type="button" @click="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)">
- <i class="nz-icon-gear nz-icon"></i>
- </button>
- </div>
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- id="promserver-list"
- v-if="tools.showCustomTableTitle"
- @close="tools.showCustomTableTitle = false"
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- ref="customTableTitle"
- ></element-set>
- </transition>
- <div class="nz-table2">
- <el-table v-show="bottomBox.mainResizeShow" ref="promTable" v-loading="tools.loading" :data="tableData"
- :height="mainTableHeight" border @sort-change="tableDataSort"
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.promServer"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
+ <button id="prom-add" v-has="'prom_toAdd'" :title="$t('overall.createPrometheusServer')" class="top-tool-btn margin-l-20"
+ type="button" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="promserver-list-batch-delete" v-has="'prom_delete'" :delete-objs="batchDeleteObjs" api="agent" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
+ <el-table ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
@@ -47,20 +34,24 @@
<el-table-column v-for="(item, index) in tools.customTableTitle" v-if="item.show"
:key="`col-${index}`"
:label="item.label"
- :prop="$tableSet.propTitle(item.prop,'promServer')"
+ :prop="propTitle(item.prop, fromRoute.promServer)"
:resizable="true"
:sort-orders="['ascending', 'descending']"
- :sortable="$tableSet.sortableShow(item.prop,'promServer')">
+ :sortable="sortableShow(item.prop, fromRoute.promServer)">
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
<template slot-scope="scope" :column="item">
- <span v-if="item.prop == 'idc'" >{{scope.row[item.prop]?scope.row[item.prop].name:'-'}}</span>
+ <span v-if="item.prop === 'idc'" >{{scope.row[item.prop]?scope.row[item.prop].name:'-'}}</span>
- <span v-else-if="item.prop == 'type'">
- <!--{{scope.row[item.prop] == '1' ? 'Global' : ''}}
- {{scope.row[item.prop] == '2' ? 'Per-Datacenter' : ''}}-->
+ <span v-else-if="item.prop === 'type'">
{{findServerType(scope.row[item.prop]).text}}
</span>
- <span v-else-if="item.prop == 'checkTime'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
- <span v-else-if="item.prop == 'status'">
+ <span v-else-if="item.prop === 'checkTime'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <span v-else-if="item.prop === 'status'">
<el-popover :content="$t('asset.assetStatPre')+(scope.row.checkTime?utcTimeToTimezoneStr(scope.row.checkTime):$t('asset.assetStatDown'))" placement="right" trigger="hover" width="200">
<div slot="reference" style="width: 20px">
<div :class="{'active-icon green':scope.row[item.prop] == '1','active-icon red':scope.row[item.prop] == '0' || scope.row[item.prop] == '-1' || scope.row[item.prop] == '-2'}"></div>
@@ -71,74 +62,62 @@
<template v-else>-</template>
</template>
</el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `agent?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </div>
+ </el-table-column>
</el-table>
- </div>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow" id="promserver-list-totop"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
- <transition name="el-zoom-in-bottom">
- <bottom-box v-if="bottomBox.showSubList" :sub-resize-show="bottomBox.subResizeShow" :obj="bottomBox.promServer" :is-full-screen="bottomBox.isFullScreen" :from="'promServer'" :target-tab.sync="bottomBox.targetTab" :detail="bottomBox.promDetail"
- @closeSubList="bottomBox.showSubList = false" @fullScreen="fullScreen" @exitFullScreen="exitFullScreen" @listResize="listResize" ></bottom-box>
- </transition>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="account-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<transition name="right-box">
- <prom-server-box v-if="rightBox.show" :prom-server="promServer" @close="closeRightBox"></prom-server-box>
+ <prom-server-box v-if="rightBox.show" :prom-server="object" @close="closeRightBox"></prom-server-box>
</transition>
</div>
</template>
<script>
-import bus from '../../../libs/bus'
-import promServerBox from '../../common/rightBox/promServerBox'
-import deleteButton from '../../common/deleteButton'
+import deleteButton from '@/components/common/deleteButton'
+import promServerBox from '@/components/common/rightBox/promServerBox'
+import { promServer } from '@/components/common/js/constants'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
name: 'promServer',
components: {
- 'prom-server-box': promServerBox,
- 'delete-button': deleteButton
+ nzDataList,
+ promServerBox,
+ deleteButton
},
+ mixins: [tableMixin],
data () {
return {
- // 侧滑
- rightBox: {
- show: false
- },
- /* 二级页面相关 */
- bottomBox: {
- promDetail: {},
- promServer: {},
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- batchDeleteObjs: [],
tableId: 'promTable', // 需要分页的table的id,用于记录每页数量
- promServer: {},
- blankPromServer: {
+ blankObject: {
id: '',
host: '',
port: 9090,
idc: { id: '', name: '', location: '' }
},
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [
{
label: 'ID',
@@ -207,97 +186,10 @@ export default {
disabled: false
}]
},
- searchLabel: {}, // 搜索参数
- promServerType: null,
- scrollbarWrap: null,
- delFlag: false
+ promServerType: null
}
},
methods: {
- // 全屏
- fullScreen () {
- const vm = this
- this.$bottomBoxWindow.fullScreen(vm)
- },
- // 退出全屏
- exitFullScreen () {
- const vm = this
- this.$bottomBoxWindow.exitFullScreen(vm)
- },
- // 鼠标拖动二级列表
- listResize (e) {
- const vm = this
- this.$bottomBoxWindow.listResize(vm, e)
- },
- convertToDetail (obj) {
- const detail = []
- detail.push({ label: this.$t('config.dc.dc'), value: obj.idc.name })
- detail.push({ label: 'Host', value: obj.host })
- detail.push({ label: 'Port', value: obj.port })
- let type = ''
- for (let i = 0; i < this.$CONSTANTS.promServer.typeData.length; i++) {
- if (obj.value == this.$CONSTANTS.promServer.typeData[i].type) {
- type = this.$CONSTANTS.promServer.typeData[i].label
- break
- }
- }
- detail.push({ label: this.$t('config.promServer.type'), value: type })
- detail.push({
- label: this.$t('asset.state'),
- value: obj.status,
- type: 'status',
- msg: this.$t('asset.assetStatPre') + (obj.checkTime ? obj.checkTime : this.$t('asset.assetStatDown'))
- })
- return detail
- },
- edit (u) {
- this.promServer = JSON.parse(JSON.stringify(u))
- this.rightBox.show = true
- },
- /* 删除 */
- del (u) {
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('promServer?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
- detail (u) {
- this.bottomBox.promServer = JSON.parse(JSON.stringify(u))
- this.bottomBox.targetTab = 'detail'
- this.bottomBox.showSubList = true
- },
- add () {
- this.promServer = this.newPromServer()
- this.rightBox.show = true
- },
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getTableData()
- }
- },
-
- jumpTo (data, id) {
- bus.$emit('menu-change', data)
- this.$router.push({
- path: '/' + data,
- query: {
- t: +new Date()
- }
- })
- },
getTableData () {
if (!this.hasButton('prom_view')) {
this.$message.error(this.$t('tip.noAccess'))
@@ -306,7 +198,7 @@ export default {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.loading = true
- this.$get('promServer', this.searchLabel).then(response => {
+ this.$get('agent', this.searchLabel).then(response => {
this.loading = false
if (response.code === 200) {
for (let i = 0; i < response.data.list.length; i++) {
@@ -321,45 +213,13 @@ export default {
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.promTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
- newPromServer () {
- return JSON.parse(JSON.stringify(this.blankPromServer))
- },
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.pageObj.pageNo = 1
- this.searchLabel = {}
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- if (this.$refs.promTable && this.$refs.promTable.bodyWrapper) {
- this.$refs.promTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
// 获取dc数据
getDcData () {
return new Promise(resolve => {
@@ -371,22 +231,10 @@ export default {
})
})
},
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- },
findServerType (type) {
if (!this.promServerType) {
this.promServerType = []
- this.$CONSTANTS.promServer.theData.forEach(item => {
+ promServer.theData.forEach(item => {
this.promServerType = this.promServerType.concat(item.children)
})
}
@@ -395,59 +243,11 @@ export default {
})
}
},
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
mounted () {
// 初始化数据
Promise.all([this.getDcData()]).then(response => {
this.getTableData()
})
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- };
- },
-
- watch: {
- 'bottomBox.promServer': {
- deep: true,
- handler (n) {
- this.bottomBox.promDetail = this.convertToDetail(n)
- }
- },
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- },
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.promTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
- }
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/roles.vue b/nezha-fronted/src/components/page/config/roles.vue
index 31f892840..9db864629 100644
--- a/nezha-fronted/src/components/page/config/roles.vue
+++ b/nezha-fronted/src/components/page/config/roles.vue
@@ -1,49 +1,31 @@
-<style lang="scss">
-@import '@/assets/css/common/tableCommon.scss';
-</style>
<template>
- <div class="roles list-page">
- <!-- 主页面 -->
- <div class="main-list" >
- <!-- 顶部工具栏 -->
- <div class="main-modal"></div>
- <div class="top-tools" >
- <div class="top-tool-main-right" >
- <div class="top-tool-search">
- <search-input :searchMsg="searchMsg" @search="search" ref="searchInput" ></search-input>
- </div>
- <button v-has="'role_toAdd'" :title="$t('overall.createRole')" class="top-tool-btn margin-l-20" @click="add"
- id="roles-add" type="button">
- <i class="nz-icon-create-square nz-icon"></i>
- </button>
- <delete-button :delete-objs="batchDeleteObjs" :filter-function="(arr)=>{return '?ids='+arr.map(t=>t.id).join(',')}" @after="getTableData" @before="delFlag=true" api="sys/role" v-has="'role_delete'" id="role-list-batch-delete"></delete-button>
- <button id="account-column-setting" class="top-tool-btn margin-l-10"
- type="button" @click="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)">
- <i class="nz-icon-gear nz-icon"></i>
- </button>
- </div>
- <!-- 顶部分页组件,当打开底部上滑框时出现 -->
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- @close="tools.showCustomTableTitle = false"
- ref="customTableTitle"
- v-if="tools.showCustomTableTitle"
- ></element-set>
- </transition>
- <div class="nz-table2">
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.role"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:top-tool-right>
+ <button id="roles-add" v-has="'role_toAdd'" :title="$t('overall.createRole')" class="top-tool-btn margin-l-20"
+ type="button" @click="add">
+ <i class="nz-icon-create-square nz-icon"></i>
+ </button>
+ <delete-button id="role-list-batch-delete" v-has="'role_delete'" :delete-objs="batchDeleteObjs" api="sys/role" @after="getTableData" @before="delFlag=true"></delete-button>
+ </template>
+ <template v-slot:default="slotProps">
<el-table
- ref="rolesTable"
+ id="role-list-table"
+ ref="dataTable"
v-loading="tools.loading"
:data="tableData"
:height="mainTableHeight"
border
- @selection-change="(selection)=>{this.batchDeleteObjs=selection}"
+ @header-dragend="dragend"
@sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
<el-table-column
:resizable="false"
@@ -60,22 +42,16 @@
:prop="item.prop"
:resizable="true"
:sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
>
- <template slot="header" >
- <span v-if="item.type == 'tag'" :title="item.label" class="tag-header"><span class="tag-value">{{item.label}}</span><span style="color:orange;">&nbsp;[Notification]</span></span>
- <span v-else><span>{{item.label}}</span></span>
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
</template>
<template slot-scope="scope" :column="item">
- <div v-if="item.prop == 'option'" class="content-right-options">
- <template v-if="scope.row.buildIn != 1">
- <span :id="'roles-edit-'+scope.row.id" v-has="'role_toEdit'" :title="$t('overall.edit')" class="content-right-option" @click="edit(scope.row)"><i :class="{'gray-filter':scope.row.buildIn == 1}" class="nz-icon nz-icon-edit"></i></span>
- &nbsp;
- <span :id="'roles-del-'+scope.row.id" v-has="'role_delete'" :title="$t('overall.delete')" class="content-right-option" @click="del(scope.row)"><i :class="{'gray-filter':scope.row.buildIn == 1}" class="nz-icon nz-icon-delete"></i></span>
- </template>
- <template v-else>
- <span :id="'roles-detail-'+scope.row.id" :title="$t('overall.view')" class="content-right-option" @click="detail(scope.row)"><i class="nz-icon nz-icon-view"></i></span>
- </template>
- </div>
<template v-if="item.prop == 'name'">
<template v-if="scope.row.i18n">
<span>{{$t(scope.row.i18n)}}</span>
@@ -93,72 +69,54 @@
<el-table-column
:resizable="false"
fixed="right"
- width="165">
+ :width="operationWidth">
<div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
<div slot-scope="scope" class="table-operation-items">
- <button class="table-operation-item" @click="showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('operationLog', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
<el-dropdown size="medium" trigger="hover" @command="tableOperation">
<div class="table-operation-item table-operation-item--more">
<span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
- <el-dropdown-item :command="['edit', scope.row]" ><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
- <el-dropdown-item :command="['delete', scope.row]" ><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['edit', scope.row]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('overall.edit')}}</span></el-dropdown-item>
+ <el-dropdown-item :command="['delete', scope.row, `sys/role?ids=${scope.row.id}`]" :disabled="isBuildIn(scope.row)"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-table-column>
</el-table>
- </div>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn && bottomBox.mainResizeShow"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" >
- <Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
<transition name="right-box">
- <role-box :detail="rightBox.detail" :role="role" @close="closeRightBox" v-if="rightBox.show"></role-box>
+ <role-box v-if="rightBox.show" :role="object" @close="closeRightBox"></role-box>
</transition>
</div>
</template>
<script>
-import deleteButton from '../../common/deleteButton'
-import roleBox from '../../common/rightBox/roleBox'
-import bus from '../../../libs/bus'
+import roleBox from '@/components/common/rightBox/roleBox'
+import deleteButton from '@/components/common/deleteButton'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
name: 'roles',
components: {
- 'role-box': roleBox,
- 'delete-button': deleteButton
+ roleBox,
+ deleteButton,
+ nzDataList
},
+ mixins: [tableMixin],
data () {
return {
- // 侧滑
- rightBox: {
- show: false,
- detail: false
- },
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- mainTableHeight: this.$tableHeight.normal, // 主列表table高度
- batchDeleteObjs: [],
- role: {},
-
tableId: 'rolesTable', // 需要分页的table的id,用于记录每页数量
- blankRole: { // 空白对象
-
- },
- pageObj: { // 分页对象
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
+ blankObject: { // 空白对象
+ name: ''
},
tableTitle: [ // 原table列
{
@@ -176,7 +134,6 @@ export default {
show: true
}
],
- tableData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
@@ -186,53 +143,10 @@ export default {
label: 'name',
disabled: false
}]
- },
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null,
- delFlag: false
+ }
}
},
methods: {
- closeRightBox (refresh) {
- this.rightBox.show = false
- if (refresh) {
- this.delFlag = true
- this.getTableData()
- }
- },
- edit (u) {
- if (u.buildIn == 1) {
- return
- }
- this.role = JSON.parse(JSON.stringify(u))
- this.$get('sys/role/menu/' + this.role.id).then(response => {
- if (response.code == 200) {
- this.role.menuIds = response.data.selectedIds
- this.rightBox.show = true
- this.rightBox.detail = false
- }
- })
- },
- del (u) {
- if (u.buildIn == 1) {
- return
- }
- this.$confirm(this.$t('tip.confirmDelete'), {
- confirmButtonText: this.$t('tip.yes'),
- cancelButtonText: this.$t('tip.no'),
- type: 'warning'
- }).then(() => {
- this.$delete('sys/role?ids=' + u.id).then(response => {
- if (response.code === 200) {
- this.delFlag = true
- this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
- this.getTableData()
- } else {
- this.$message.error(response.msg)
- }
- })
- })
- },
getTableData () {
if (!this.hasButton('role_view')) {
this.$message.error(this.$t('tip.noAccess'))
@@ -255,93 +169,7 @@ export default {
}
}
})
- },
- add () {
- this.role = this.newRole()
- this.rightBox.show = true
- this.rightBox.detail = false
- },
- esc () {
- this.rightBox.show = false
- this.rightBox.detail = false
- },
- detail: function (data) {
- this.role = JSON.parse(JSON.stringify(data))
- this.rightBox.show = true
- this.rightBox.detail = true
- },
- newRole () {
- return JSON.parse(JSON.stringify(this.blankRole))
- },
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search (searchObj) {
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (this.$refs.rolesTable) {
- this.$refs.rolesTable.bodyWrapper.scrollTop = 0
- }
- this.getTableData()
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- watch: {
- tableData: {
- deep: true,
- handler (n) {
- if (n.length === 0 && this.pageObj.pageNo > 1) {
- this.pageNo(this.pageObj.pageNo - 1)
- }
- if (!this.delFlag) { // 不是删除时回到顶部
- this.$refs.rolesTable.bodyWrapper.scrollTop = 0
- } else {
- this.delFlag = false
- }
- }
}
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- };
- },
- mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
- this.getTableData()
}
}
</script>
diff --git a/nezha-fronted/src/components/page/config/terminalLog.vue b/nezha-fronted/src/components/page/config/terminalLog.vue
new file mode 100644
index 000000000..fd58c1c3d
--- /dev/null
+++ b/nezha-fronted/src/components/page/config/terminalLog.vue
@@ -0,0 +1,292 @@
+<template>
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle"
+ :from="fromRoute.terminalLog">
+ <template v-slot:default="slotProps">
+ <el-table
+ id="terminal-log-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
+ >
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
+ </template>
+ <template slot-scope="scope" :column="item">
+ <span v-if="item.prop === 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <template v-else-if="item.prop === 'status'">
+ <span>{{getStatusText(scope.row.status)}}</span>
+ </template>
+ <template v-else-if="item.prop === 'uuid'">
+ <span>{{scope.row.uuid.substring(0, 8).toUpperCase()}}</span>
+ </template>
+ <template v-else-if="item.prop === 'remote'">
+ <span>{{getRemoteText(scope.row)}}</span>
+ </template>
+ <template v-else-if="item.prop === 'duration'">
+ <el-tooltip placement="right" effect="light" :disabled="!scope.row.status">
+ <div slot="content">
+ {{$t('config.terminallog.endTime')}}<br/>
+ {{scope.row.endTime}}
+ </div>
+ <span>{{getDuration(scope.row)}}</span>
+ </el-tooltip>
+ </template>
+ <template v-else-if="item.prop === 'authType'">
+ <span v-if="scope.row.authType == 1">{{$t('config.terminallog.password')}}</span>
+ <span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
+ </template>
+ <span v-else>{{scope.row[item.prop]}}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ fixed="right"
+ :width="operationWidth">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
+ <template v-if="scope.row.status == 0">
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('monitor', scope.row)" :title="$t('config.terminallog.monitor.monitor')"><i class="nz-icon nz-icon-JC"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['shutdown', scope.row]"><i class="nz-icon nz-icon-ZD"></i><span class="operation-dropdown-text">Kill</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </template>
+ <template v-else>
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('cmd', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['record', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('config.terminallog.record.record')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
+ </template>
+ </div>
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
+ </div>
+</template>
+<script>
+import { terminalLog } from '@/components/common/js/constants'
+import { calcDurationByStringTimeB } from '@/components/common/js/tools'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
+
+export default {
+ name: 'terminalLog',
+ components: {
+ nzDataList
+ },
+ mixins: [tableMixin],
+ data () {
+ return {
+ tableId: 'terminalLogTable', // 需要分页的table的id,用于记录每页数量
+
+ tableTitle: [
+ {
+ label: this.$t('config.terminallog.id'),
+ prop: 'id',
+ show: true,
+ width: 80
+ }, {
+ label: 'Session ID',
+ prop: 'uuid',
+ show: true
+ }, {
+ label: 'Username',
+ prop: 'username',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.source'),
+ prop: 'remoteAddr',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.remote'),
+ prop: 'remote',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.protocol'),
+ prop: 'protocol',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.startTime'),
+ prop: 'startTime',
+ show: true
+ },
+ {
+ label: this.$t('config.terminallog.duration'),
+ prop: 'duration',
+ show: true
+ },
+ {
+ label: 'AuthType',
+ prop: 'authType',
+ show: false
+ },
+ {
+ label: this.$t('config.terminallog.status'), // killusername鼠标悬停形式
+ prop: 'status',
+ show: true,
+ width: 100
+ }
+ ],
+ searchMsg: { // 给搜索框子组件传递的信息
+ zheze_none: true,
+ searchLabelList: [
+ {
+ id: 11,
+ name: this.$t('config.terminallog.host'),
+ type: 'input',
+ label: 'host',
+ disabled: false
+ }, {
+ id: 12,
+ name: this.$t('config.terminallog.user'),
+ type: 'input',
+ label: 'username',
+ disabled: false
+ }
+ ]
+ },
+ nowTime: ''
+ }
+ },
+ computed: {
+ getStatusText () {
+ return function (status) {
+ return terminalLog.status[status]
+ }
+ },
+ getRemoteText () {
+ return function (record) {
+ return `${record.loginUser}@${record.host}:${record.port}`
+ }
+ },
+ getDuration () {
+ return function (record) {
+ if (record.endTime) {
+ return calcDurationByStringTimeB(record.startTime, record.endTime)
+ }
+ return calcDurationByStringTimeB(record.startTime, this.nowTime)
+ }
+ }
+ },
+ methods: {
+ tableOperation ([command, row]) {
+ switch (command) {
+ case 'shutdown': {
+ this.shutdown(row)
+ break
+ }
+ default:
+ this.$refs.dataList.showBottomBox(command, row)
+ break
+ }
+ },
+ getTableData () {
+ const params = {
+ ...this.searchLabel,
+ pageNo: this.pageObj.pageNo,
+ pageSize: this.pageObj.pageSize
+ }
+ this.$get('terminal/session', params).then(response => {
+ this.tools.loading = false
+ if (response.code === 200) {
+ this.tableData = response.data.list
+ this.nowTime = this.utcTimeToTimezoneStr(response.time)
+ this.pageObj.total = response.data.total
+ if (!this.scrollbarWrap) {
+ this.$nextTick(() => {
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
+ this.toTopBtnHandler(this.scrollbarWrap)
+ })
+ }
+ }
+ })
+ },
+ shutdown (record) {
+ this.$confirm(this.$t('tip.killTerm'), {
+ confirmButtonText: this.$t('tip.yes'),
+ cancelButtonText: this.$t('tip.no'),
+ type: 'warning'
+ }).then(() => {
+ this.$put('/terminal/kill', { uuid: record.uuid }).then(res => {
+ if (res.code === 200) {
+ this.$message.success(this.$t('config.terminallog.success'))
+ this.bottomBox.showSubList = false
+ this.getTableData()
+ } else {
+ this.$message.error(this.$t('config.terminallog.killErrorTip'))
+ }
+ })
+ })
+ },
+ messageStyle (e) {
+ if (e.column.label == this.$t('config.terminallog.status')) {
+ if (e.row.status == '0') {
+ return 'success'
+ } else if (e.row.status == '1') {
+ return 'warning'
+ } else if (e.row.status == '2') {
+ return 'suspended'
+ } else if (e.row.status == '3') {
+ return 'danger'
+ } else if (e.row.status == '4') {
+ return 'danger'
+ }
+ }
+ return ''
+ }
+ }
+}
+</script>
diff --git a/nezha-fronted/src/components/page/config/terminallog.vue b/nezha-fronted/src/components/page/config/terminallog.vue
index 1d1cfc2d4..a04a8e238 100644
--- a/nezha-fronted/src/components/page/config/terminallog.vue
+++ b/nezha-fronted/src/components/page/config/terminallog.vue
@@ -1,169 +1,133 @@
-<style scoped>
- .terminallog {
- height: 100%;
- }
-</style>
<template>
- <div class="terminallog">
- <div :class="{'main-list-with-sub': bottomBox.showSubList}" class="main-list">
- <!-- 顶部工具栏 -->
- <div class="main-modal"></div>
- <div class="top-tools" v-show="bottomBox.mainResizeShow">
- <div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
- <div class="top-tool-search margin-r-5">
- <search-input :searchMsg="searchMsg" @search="search"></search-input>
- </div>
- </div>
- <div class="pagination-top pagination-top-hide display-none"></div>
- </div>
- <!-- 自定义table列 -->
- <transition name="el-zoom-in-top">
- <element-set
- :custom-table-title.sync="tools.customTableTitle"
- :original-table-title="tableTitle"
- @close="tools.showCustomTableTitle = false"
- ref="customTableTitle"
- v-if="tools.showCustomTableTitle"
- ></element-set>
- </transition>
- <el-table
- :cell-class-name="messageStyle"
- :data="tableData"
- :height="$tableHeight.normal"
- @sort-change="tableDataSort"
- border
- class="nz-table"
- ref="terminalLogTable"
- style="width: 100%;"
- v-loading="tools.loading">
- <el-table-column
- :key="`col-${index}`"
- :label="item.label"
- :prop="$tableSet.propTitle(item.prop,'temrminallog')"
- :resizable="true"
- :sort-orders="['ascending', 'descending']"
- :sortable="$tableSet.sortableShow(item.prop,'temrminallog')"
- v-for="(item, index) in tools.customTableTitle"
- v-if="item.show"
+ <div style="height: 100%">
+ <nz-data-list
+ ref="dataList"
+ :components="['searchInput', 'elementSet']"
+ :custom-table-title.sync="tools.customTableTitle"
+ :from="fromRoute.terminalLog"
+ :search-msg="searchMsg"
+ :table-id="tableId"
+ :table-title="tableTitle">
+ <template v-slot:default="slotProps">
+ <el-table
+ id="terminal-log-list-table"
+ ref="dataTable"
+ v-loading="tools.loading"
+ :data="tableData"
+ :height="mainTableHeight"
+ border
+ @header-dragend="dragend"
+ @sort-change="tableDataSort"
+ @selection-change="(selection)=>{batchDeleteObjs=selection}"
>
- <template :column="item" slot-scope="scope">
- <span v-if="item.prop == 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
- <template v-else-if="item.prop == 'status'">
- <span>{{getStatusText(scope.row.status)}}</span>
- </template>
- <template v-else-if="item.prop == 'uuid'">
- <span>{{scope.row.uuid.substring(0, 8).toUpperCase()}}</span>
+ <el-table-column
+ :resizable="false"
+ align="center"
+ type="selection"
+ width="55">
+ </el-table-column>
+ <el-table-column
+ v-for="(item, index) in tools.customTableTitle"
+ v-if="item.show"
+ :key="`col-${index}`"
+ :fixed="item.fixed"
+ :label="item.label"
+ :prop="item.prop"
+ :resizable="true"
+ :sort-orders="['ascending', 'descending']"
+ :width="`${item.width}`"
+ class="data-column"
+ >
+ <template slot="header">
+ <span>
+ <span>{{item.label}}</span>
+ <div class="col-resize-area"></div>
+ </span>
</template>
- <template v-else-if="item.prop == 'remote'">
- <span>{{getRemoteText(scope.row)}}</span>
- </template>
- <template v-else-if="item.prop == 'duration'">
- <el-tooltip placement="right" effect="light" :disabled="!scope.row.status">
- <div slot="content">
- {{$t('config.terminallog.endTime')}}<br/>
- {{scope.row.endTime}}
- </div>
- <span>{{getDuration(scope.row)}}</span>
- </el-tooltip>
+ <template slot-scope="scope" :column="item">
+ <span v-if="item.prop === 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
+ <template v-else-if="item.prop === 'status'">
+ <span>{{getStatusText(scope.row.status)}}</span>
+ </template>
+ <template v-else-if="item.prop === 'uuid'">
+ <span>{{scope.row.uuid.substring(0, 8).toUpperCase()}}</span>
+ </template>
+ <template v-else-if="item.prop === 'remote'">
+ <span>{{getRemoteText(scope.row)}}</span>
+ </template>
+ <template v-else-if="item.prop === 'duration'">
+ <el-tooltip :disabled="!scope.row.status" effect="light" placement="right">
+ <div slot="content">
+ {{$t('config.terminallog.endTime')}}<br/>
+ {{scope.row.endTime}}
+ </div>
+ <span>{{getDuration(scope.row)}}</span>
+ </el-tooltip>
+ </template>
+ <template v-else-if="item.prop === 'authType'">
+ <span v-if="scope.row.authType == 1">{{$t('config.terminallog.password')}}</span>
+ <span v-else-if="scope.row.authType == 2">{{$t('config.terminallog.key')}}</span>
+ </template>
+ <span v-else>{{scope.row[item.prop]}}</span>
</template>
- <template v-else-if="item.prop == 'option'">
+ </el-table-column>
+ <el-table-column
+ :resizable="false"
+ :width="operationWidth"
+ fixed="right">
+ <div slot="header" class="table-operation-title">{{$t('overall.option')}}</div>
+ <div slot-scope="scope" class="table-operation-items">
<template v-if="scope.row.status == 0">
- <span :id="'terminalLog-shutdown-'+scope.row.id" @click="shutdown(scope.row)" class="content-right-option" title="Kill"><i class="nz-icon nz-icon-ZD"></i></span>
- &nbsp;
- <span :id="'terminalLog-monitor-'+scope.row.id" :title="$t('config.terminallog.monitor.monitor')" @click="monitor(scope.row)" class="content-right-option"><i class="nz-icon nz-icon-JC"></i></span>
+ <button :title="$t('config.terminallog.monitor.monitor')" class="table-operation-item" @click="$refs.dataList.showBottomBox('monitor', scope.row)"><i class="nz-icon nz-icon-JC"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['shutdown', scope.row]"><i class="nz-icon nz-icon-ZD"></i><span class="operation-dropdown-text">Kill</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
</template>
<template v-else>
- <span :id="'terminalLog-replay-'+scope.row.id" :title="$t('config.terminallog.record.record')" @click="showRecord(scope.row)" class="content-right-option"><i class="nz-icon nz-icon-replay2"></i></span>
- &nbsp;
- <span :id="'terminalLog-log-'+scope.row.id" :title="$t('config.terminallog.log')" @click="showHistoryCMD(scope.row)" class="content-right-option"><i class="nz-icon nz-icon-terminal-log"></i></span>
+ <button class="table-operation-item" @click="$refs.dataList.showBottomBox('cmd', scope.row)"><i class="nz-icon nz-icon-view1"></i></button>
+ <el-dropdown size="medium" trigger="hover" @command="tableOperation">
+ <div class="table-operation-item table-operation-item--more">
+ <span>…</span><i class="nz-icon nz-icon-arrow-down"></i>
+ </div>
+ <el-dropdown-menu slot="dropdown">
+ <el-dropdown-item :command="['record', scope.row]"><i class="nz-icon nz-icon-edit"></i><span class="operation-dropdown-text">{{$t('config.terminallog.record.record')}}</span></el-dropdown-item>
+ </el-dropdown-menu>
+ </el-dropdown>
</template>
-
- </template>
- <template v-else-if="item.prop == 'authType'">
- <span v-if="scope.row.authType==1">{{$t('config.terminallog.password')}}</span>
- <span v-else-if="scope.row.authType==2">{{$t('config.terminallog.key')}}</span>
- </template>
- <span v-else>{{scope.row[item.prop]}}</span>
- </template>
- </el-table-column>
- <el-table-column width="28">
- <template slot="header">
- <span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
- <i class="nz-icon nz-icon-gear"></i>
- </span>
- </template>
- </el-table-column>
- </el-table>
- <button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn"><i class="nz-icon nz-icon-top"></i></button>
- <div class="pagination-bottom" v-show="!bottomBox.showSubList">
- <Pagination :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
- </div>
- </div>
-
- <!-- 底部上滑框 -->
- <transition name="el-zoom-in-bottom">
- <bottom-box :detail="bottomBox.terminalLog" :is-full-screen="bottomBox.isFullScreen" :obj="bottomBox.terminalLog" :sub-resize-show="bottomBox.subResizeShow" :target-tab.sync="bottomBox.targetTab" @closeSubList="closeSubList" @exitFullScreen="exitFullScreen"
- @fullScreen="fullScreen" @listResize="listResize" from="terminal" v-if="bottomBox.showSubList" ></bottom-box>
- </transition>
+ </div>
+ </el-table-column>
+ </el-table>
+ <!-- 回到table顶部的按钮 -->
+ <button v-show="tools.showTopBtn && slotProps.mainResizeShow" id="role-list-totop" :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" class="to-top" @click="toTop(scrollbarWrap)"><i class="nz-icon nz-icon-top"></i></button>
+ </template>
+ <!-- 分页组件 -->
+ <template v-slot:pagination>
+ <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
+ </template>
+ </nz-data-list>
</div>
</template>
<script>
-import bus from '../../../libs/bus'
-import { terminalLog } from '../../common/js/constants'
-import { calcDurationByStringTimeB } from '../../common/js/tools'
+import { terminalLog } from '@/components/common/js/constants'
+import { calcDurationByStringTimeB } from '@/components/common/js/tools'
+import nzDataList from '@/components/common/table/nzDataList'
+import tableMixin from '@/components/common/mixin/table'
export default {
- name: 'terminallog',
+ name: 'terminalLog',
+ components: {
+ nzDataList
+ },
+ mixins: [tableMixin],
data () {
return {
tableId: 'terminalLogTable', // 需要分页的table的id,用于记录每页数量
- /* 二级页面相关 */
- bottomBox: {
- terminalLog: {},
- mainResizeShow: true, // dom高度改变时是否展示|隐藏
- subResizeShow: true,
- isFullScreen: false, // 全屏状态
- showSubList: false, // 是否显示二级列表
- targetTab: '', // 显示二级列表中的哪个页签
- inTransform: false // 搜索框相关,搜索条件下拉框是否在transform里
- },
-
- /* 工具参数 */
- tools: {
- loading: false, // 是否显示table加载动画
- toTopBtnTop: this.$tableHeight.toTopBtnTop, // to-top按钮的top属性
- tableHover: false, // 控制滚动条和top按钮同时出现
- showTopBtn: false, // 显示To top按钮
- showCustomTableTitle: false, // 自定义列弹框是否显示
- customTableTitle: [] // 自定义列工具的数据
- },
- rightBox: { // 弹出框相关
- show: false,
- isEdit: false, // false查看,true编辑
- title: ''
-
- },
- rightBoxResize: { // resize弹出框相关
- show: false,
- isAdd: false, // false,true:resize
- title: ''
- },
- rightBoxDownload: { // 下载弹出框相关
- show: false,
- isAdd: false, // false,true:resize
- title: ''
- },
- rightBoxUpload: { // 上传弹出框相关
- show: false,
- isAdd: false, // false,true:resize
- title: ''
- },
- pageObj: {
- pageNo: 1,
- pageSize: this.$CONSTANTS.defaultPageSize,
- total: 0
- },
tableTitle: [
{
label: this.$t('config.terminallog.id'),
@@ -214,16 +178,8 @@ export default {
prop: 'status',
show: true,
width: 100
- },
- {
- label: this.$t('config.account.option'),
- prop: 'option',
- show: true,
- width: 120,
- fixed: 'right'
}
],
- tableData: [],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [
@@ -242,8 +198,6 @@ export default {
}
]
},
- searchLabel: {}, // 搜索参数
- scrollbarWrap: null,
nowTime: ''
}
},
@@ -267,13 +221,18 @@ export default {
}
}
},
- watch: {
- 'bottomBox.showSubList': function (n) {
- const vm = this
- this.$bottomBoxWindow.showSubListWatch(vm, n)
- }
- },
methods: {
+ tableOperation ([command, row]) {
+ switch (command) {
+ case 'shutdown': {
+ this.shutdown(row)
+ break
+ }
+ default:
+ this.$refs.dataList.showBottomBox(command, row)
+ break
+ }
+ },
getTableData () {
const params = {
...this.searchLabel,
@@ -288,29 +247,13 @@ export default {
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
- this.scrollbarWrap = this.$refs.terminalLogTable.bodyWrapper
+ this.scrollbarWrap = this.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
-
- showRecord (record) {
- this.bottomBox.targetTab = 'record'
- this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record))
- this.bottomBox.showSubList = true
- },
- showHistoryCMD (record) {
- this.bottomBox.targetTab = 'cmd'
- this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record))
- this.bottomBox.showSubList = true
- },
- monitor (record) {
- this.bottomBox.targetTab = 'monitor'
- this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record))
- this.bottomBox.showSubList = true
- },
shutdown (record) {
this.$confirm(this.$t('tip.killTerm'), {
confirmButtonText: this.$t('tip.yes'),
@@ -328,21 +271,6 @@ export default {
})
})
},
- // 全屏
- fullScreen () {
- const vm = this
- this.$bottomBoxWindow.fullScreen(vm)
- },
- // 退出全屏
- exitFullScreen () {
- const vm = this
- this.$bottomBoxWindow.exitFullScreen(vm)
- },
- // 鼠标拖动二级列表
- listResize (e) {
- const vm = this
- this.$bottomBoxWindow.listResize(vm, e)
- },
messageStyle (e) {
if (e.column.label == this.$t('config.terminallog.status')) {
if (e.row.status == '0') {
@@ -358,72 +286,7 @@ export default {
}
}
return ''
- },
- pageNo (val) {
- this.pageObj.pageNo = val
- this.getTableData()
- },
- pageSize (val) {
- this.pageObj.pageSize = val
- localStorage.setItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId, val)
- this.getTableData()
- },
- search: function (searchObj) {
- let orderBy = ''
- if (this.searchLabel.orderBy) {
- orderBy = this.searchLabel.orderBy
- }
- this.searchLabel = {}
- this.pageObj.pageNo = 1
- for (const item in searchObj) {
- if (searchObj[item]) {
- this.$set(this.searchLabel, item, searchObj[item])
- }
- }
- if (orderBy) {
- this.$set(this.searchLabel, 'orderBy', orderBy)
- }
- this.getTableData()
- },
- closeSubList () {
- this.bottomBox.showSubList = false
- if (this.bottomBox.targetTab == 'monitor') {
- this.getTableData()
- }
- },
- // 数据排序
- tableDataSort (item) {
- let orderBy = ''
- if (item.order === 'ascending') {
- orderBy = item.prop
- }
- if (item.order === 'descending') {
- orderBy = '-' + item.prop
- }
- this.$set(this.searchLabel, 'orderBy', orderBy)
- this.getTableData()
- }
- },
- beforeDestroy () {
- if (this.scrollbarWrap) {
- this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
- };
- },
- created () {
- // 是否存在分页缓存
- const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
- if (pageSize != 'undefined' && pageSize != null) {
- this.pageObj.pageSize = pageSize
}
- },
- mounted () {
- // 初始化表头
- this.tools.customTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path)
- ? JSON.parse(localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.$route.path))
- : this.tableTitle
- this.tableTitleReset(this.tableTitle, this.tools.customTableTitle)
-
- this.getTableData()
}
}
</script>
diff --git a/nezha-fronted/src/main.js b/nezha-fronted/src/main.js
index 38f223a9f..f92a1c7b6 100644
--- a/nezha-fronted/src/main.js
+++ b/nezha-fronted/src/main.js
@@ -27,42 +27,14 @@ import Pagination from './components/common/pagination' // 引入全局分页组
import searchInput from './components/common/searchInput' // 搜索框组件
import elementSet from './components/common/elementSet' // 自定义表头组件
-import projectBox from './components/common/rightBox/projectBox' // project弹框组件
-import moduleBox from './components/common/rightBox/moduleBox' // module弹框组件
-import editEndpointBox from './components/common/rightBox/editEndpointBox' // endpoint弹框组件
-import addEndpointBox from './components/common/rightBox/addEndpointBox' // endpoint弹框组件
-import assetBox from './components/common/rightBox/assetBox' // 资产添加组件
-import batchEditAsset from './components/common/rightBox/batchEditAsset' // 资产批量修改组件
-import alertConfigBox from './components/common/rightBox/alertConfigBox' // 告警规则弹框组件
-import panelBox from './components/common/rightBox/panelBox' // 面板弹框组件
-import moduleListPop from './components/page/asset/moduleListPop' // 面板弹框组件
-import cabinetConfigBox from './components/common/popBox/cabinetConfig' // 面板弹框组件
-import modelBox from './components/common/rightBox/modelBox' // model弹框
-import bottomBox from './components/common/bottomBox/bottomBox' // 上滑框
-import loading from './components/common/loading'
-import mibBox from './components/common/rightBox/mibBox'
-import leftMenu from './components/common/leftMenu'
-import pickTime from './components/common/pickTime'
-import bus from './libs/bus'
+import loading from '@/components/common/loading'
+import pickTime from '@/components/common/pickTime'
+import bus from '@/libs/bus'
Vue.component('Pagination', Pagination)
Vue.component('searchInput', searchInput)
Vue.component('element-set', elementSet)
-Vue.component('project-box', projectBox)
-Vue.component('module-box', moduleBox)
-Vue.component('edit-endpoint-box', editEndpointBox)
-Vue.component('add-endpoint-box', addEndpointBox)
-Vue.component('asset-box', assetBox)
-Vue.component('batch-edit-asset', batchEditAsset)
-Vue.component('alert-config-box', alertConfigBox)
-Vue.component('panel-box', panelBox)
-Vue.component('module-list-pop', moduleListPop)
-Vue.component('cabinet-config-box', cabinetConfigBox)
-Vue.component('model-box', modelBox)
Vue.component('loading', loading)
-Vue.component('bottom-box', bottomBox)
-Vue.component('mib-box', mibBox)
-Vue.component('left-menu', leftMenu)
Vue.component('pick-time', pickTime)
Vue.prototype.$axios = axios
diff --git a/nezha-fronted/src/router/index.js b/nezha-fronted/src/router/index.js
index cafbe7a00..1a41d3b35 100644
--- a/nezha-fronted/src/router/index.js
+++ b/nezha-fronted/src/router/index.js
@@ -79,11 +79,11 @@ export default new Router({
},
{
path: '/terminalLog',
- component: resolve => require(['../components/page/config/terminallog.vue'], resolve)
+ component: resolve => require(['../components/page/config/terminalLog.vue'], resolve)
},
{
path: '/operationLog',
- component: resolve => require(['../components/page/config/operationlog.vue'], resolve)
+ component: resolve => require(['../components/page/config/operationLog.vue'], resolve)
},
{
path: '/about',