diff options
Diffstat (limited to 'nezha-fronted/src/components/page')
| -rw-r--r-- | nezha-fronted/src/components/page/config/account2.vue | 152 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/assetMeta.vue | 384 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/assetState.vue | 415 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/assetType.vue | 432 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/dc.vue | 378 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/exprTemp.vue | 367 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/mib.vue | 387 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/model.vue | 348 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/operationLog.vue | 208 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/operationlog.vue | 255 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/promServer.vue | 356 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/roles.vue | 276 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/terminalLog.vue | 292 | ||||
| -rw-r--r-- | nezha-fronted/src/components/page/config/terminallog.vue | 387 |
14 files changed, 1657 insertions, 2980 deletions
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"> [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> - - <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> - - <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> - - <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> - - <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;"> [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> - - <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> - - <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> - - <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> |
