summaryrefslogtreecommitdiff
path: root/nezha-fronted/src/components/common
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 /nezha-fronted/src/components/common
parentf259ed27507d30ebb0d345cac732f3c64ec2bc8a (diff)
perf: settings列表改版(细节未调整)codeCheck
Diffstat (limited to 'nezha-fronted/src/components/common')
-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
13 files changed, 863 insertions, 54 deletions
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,