perf: panel样式;列表的table抽取

This commit is contained in:
chenjinsong
2021-04-12 13:00:59 +08:00
parent 80fdfd3850
commit e15d8dff15
29 changed files with 735 additions and 870 deletions

View File

@@ -19,3 +19,27 @@
margin-top: 0;
transform: translate(-50%, -50%);
}
/* 自定义的dropdown */
.nz-dropdown {
width: 90px;
right: 0;
left: unset !important;
top: 35px;
}
.nz-dropdown::after {
content: '';
display: block;
width:0;
height:0;
overflow: hidden;
font-size: 0;
line-height: 0;
border: 5px;
border-style: dashed dashed solid dashed;
border-color: transparent transparent #fff transparent;
position: absolute;
right: 3px;
top: 44px;
transform: translate(-50%, -54px);
}

View File

@@ -36,10 +36,10 @@
.top-tool-btn-group {
display: flex;
.top-tool-btn:first-of-type {
.top-tool-btn:first-of-type:not(:last-of-type) {
border-radius: $--button-border-radius 0 0 $--button-border-radius;
}
.top-tool-btn:last-of-type {
.top-tool-btn:last-of-type:not(:first-of-type) {
border-radius: 0 $--button-border-radius $--button-border-radius 0;
border-left: none;
}
@@ -76,6 +76,9 @@
color: #F0745A;
}
}
.top-tool-btn--dropdown {
position: relative;
}
}
.nz-table2 {

View File

@@ -3,8 +3,11 @@
}
$--theme-color: var(--theme-color); // 主题色
$--primary-border-color: #DEDEDE;
$--primary-border-radius: 2px;
/* 按钮 */
$--button-border-radius: 2px; // 按钮圆角
$--button-border-radius: $--primary-border-radius; // 按钮圆角
$--button-primary-color: #FFF; // 普通按钮字色
$--button-primary-background-color: var(--theme-color); // 普通按钮背景色
@@ -17,10 +20,13 @@ $--button-gray-active-color: var(--theme-color); // 灰色按钮focus字色
$--button-gray-background-color: #F9F9F9; // 灰色按钮背景色
$--button-gray-hover-background-color: #FFF; // 灰色按钮hover背景色
$--button-gray-active-background-color: $--button-gray-hover-background-color; // 灰色按钮focus背景色
$--button-gray-border-color: #DEDEDE; // 灰色按钮边框色
$--button-gray-border-color: $--primary-border-color; // 灰色按钮边框色
$--button-gray-hover-border-color: $--button-gray-border-color; // 灰色按钮hover边框色
$--button-gray-active-border-color-tint-percent: 30%; // 灰色按钮在focus时边框色相对于主题色变浅的幅度
:export {
themeColor: $--theme-color
}
/* element-ui变量覆盖 */
/*$--color-primary: red; // 覆盖element-ui的主题色
$--box-shadow-base: none; // 取消box-shadow

View File

@@ -1876,7 +1876,7 @@ li{
}
/* panel-tool-tip列表搜索框 样式重写*/
.relative-position{
/*.relative-position{
position: relative;
}
.query-input-inactive{
@@ -1893,7 +1893,7 @@ li{
.query-input-active .el-input__inner, .query-input-inactive .el-input__inner {
height: 30px;
line-height: 30px !important;
}
}*/
.el-textarea:not(.not-fixed-height) textarea {
height: 140px !important;

View File

@@ -1,4 +1,4 @@
<style scoped>
<style lang="scss" scoped>
.chartBox {
float:left;
padding: 0px 10px 10px 0;
@@ -9,11 +9,16 @@
text-align: center
}
.list-width{
width: calc(100% - 2px);
padding: 5px 5px 5px 0px;
width: 100%;
height: 100%;
padding: 0 10px 5px 20px;
box-sizing: border-box;
overflow: hidden;/*避免鼠标第一次放到曲线时x轴出现滚动条后消失*/
min-height: calc(100vh - 150px);
&>div {
height: 100%;
overflow-y: auto;
}
}
</style>
<style lang="scss">

View File

@@ -37,8 +37,8 @@
<terminal-log-monitor-tab v-if="from === fromRoute.terminalLog && targetTab === 'monitor'" ref="reminalLogRecordTab" :from="from" :obj="obj" @changeTab="changeTab" @exit="closeSubList"></terminal-log-monitor-tab>
<!--user列表的两个日志-->
<operation-log-tab v-if="from === fromRoute.account && targetTab === 'operationLogTab'" :from="from" :obj="obj" @changeTab="changeTab"></operation-log-tab>
<terminal-log-tab v-if="from === fromRoute.account && targetTab === 'terminalLogTab'" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-tab>
<operation-log-tab v-if="from === fromRoute.user && targetTab === 'operationLogTab'" :from="from" :obj="obj" @changeTab="changeTab"></operation-log-tab>
<terminal-log-tab v-if="from === fromRoute.user && targetTab === 'terminalLogTab'" :from="from" :obj="obj" @changeTab="changeTab"></terminal-log-tab>
</div>
</div>
</template>

View File

@@ -61,7 +61,7 @@
</template>
<script>
import tableMixin from '@/components/common/mixin/table'
import tableMixin from '@/components/common/mixin/dataList'
export default {
name: 'operationLogTab',
mixins: [tableMixin],

View File

@@ -109,7 +109,7 @@
</template>
<script>
import tableMixin from '@/components/common/mixin/table'
import tableMixin from '@/components/common/mixin/dataList'
import { terminalLog } from '@/components/common/js/constants'
import { calcDurationByStringTimeB } from '@/components/common/js/tools'

View File

@@ -2,10 +2,10 @@
<div class="export-xlsx">
<div class="top-tool-btn-group">
<slot name="optionZone"></slot>
<button id="browser-go" v-has="[permissions.import, permissions.export]" class="top-tool-btn" style="position: relative" @mouseenter="exportMenuHandler(true)" @mouseleave="exportMenuHandler(false)">
<button id="browser-go" v-has="[permissions.import, permissions.export]" class="top-tool-btn top-tool-btn--dropdown" @mouseenter="exportMenuHandler(true)" @mouseleave="exportMenuHandler(false)">
<i class="nz-icon nz-icon-arrow-down" style="font-size: 12px;"></i>
<transition name="el-zoom-in-top">
<ul v-show="exportShow" class="el-dropdown-menu el-popper el-dropdown-menu--mini export-dropdown">
<ul v-show="exportShow" class="el-dropdown-menu el-popper el-dropdown-menu--mini nz-dropdown">
<li @click="showImportBox(1)" class="el-dropdown-menu__item dropdown-content" v-has="permissions.import" :id="id+'-xlsx-import'"><i class="nz-icon nz-icon-upload"></i>{{$t('overall.importExcel')}}</li>
<li @click="showImportBox(2)" class="el-dropdown-menu__item dropdown-content" v-has="permissions.export" :id="id+'-xlsx-export'"><i class="nz-icon nz-icon-download1"></i>{{$t('overall.exportExcel')}}</li>
</ul>
@@ -112,7 +112,7 @@ export default {
showCur: { type: Boolean, default: true },
id: { type: String, default: 'export' }
},
data: function () {
data () {
return {
importBox: { show: false, title: this.$t('overall.importExcel'), type: 1 },
importFile: null,
@@ -137,17 +137,17 @@ export default {
}
}, */
methods: {
importChange: function (file, fileList) {
importChange (file, fileList) {
if (fileList.length > 0) {
this.importFileList = [fileList[fileList.length - 1]]
}
this.importFile = this.importFileList[0]
this.validateFile()
},
validateFile: function () {
validateFile () {
},
rollbackImport: function () {
rollbackImport () {
let url
if (this.importUrl.indexOf('asset') > -1) {
url = '/asset/cancelImport'
@@ -170,7 +170,7 @@ export default {
this.closeDialog()
})
},
importExcel: function () {
importExcel () {
if (this.importFile && this.importFile.raw) {
this.prevent_opt.import = true
const form = new FormData()
@@ -207,13 +207,13 @@ export default {
}, 700)
}
},
closeDialog: function () {
closeDialog () {
this.importBox.show = false
this.importResult = null
this.importFileList = []
this.importFile = null
},
downloadTemplate: function () {
downloadTemplate () {
const language = localStorage.getItem('nz-language') || 'en' // 初始未选择默认 en 英文
const fileName = this.exportFileName + '-' + this.$t('overall.template') + '-' + this.getTimeString() + '.xlsx'
@@ -239,13 +239,13 @@ export default {
formatJson (filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
},
exportCur: function () {
exportCur () {
const params = Object.assign({}, this.params)
params.language = localStorage.getItem('nz-language') || 'en'
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.xlsx')
this.closeDialog()
},
exportAll: function () {
exportAll () {
const params = JSON.parse(JSON.stringify(this.params))
params.pageSize = -1
if (this.importUrl.indexOf('panel') > -1) {
@@ -259,7 +259,7 @@ export default {
this.exportExcel(this.exportUrl, params, this.exportFileName + '-' + this.getTimeString() + '.xlsx')
this.closeDialog()
},
exportExcel: function (url, params, fileName) {
exportExcel (url, params, fileName) {
if (this.paramsType) {
params.type = this.paramsType
}
@@ -293,7 +293,7 @@ export default {
reader.readAsText(error.response.data)
})
},
showImportBox: function (type) {
showImportBox (type) {
this.importBox.show = true
this.importBox.type = type
if (type == 2 && (!this.showCur)) {
@@ -308,7 +308,7 @@ export default {
this.importBox.width = '300px'
}
},
getTimeString: function () {
getTimeString () {
const split = '-'
const date = new Date()
const year = date.getFullYear()
@@ -319,7 +319,7 @@ export default {
const seconds = this.formatNum(date.getSeconds())
return year + split + month + split + day + ' ' + hours + split + minutes + split + seconds
},
formatNum: function (num) {
formatNum (num) {
return num > 9 ? num : '0' + num
},
getParamsType () {
@@ -368,21 +368,18 @@ export default {
width: 55px;
}
.export-dropdown-btn {
position: relative;
}
.endpoint-query-dropdown {
position: absolute;
right: 0;
top: 31px;
}
.export-dropdown {
.nz-dropdown {
width: 90px;
right: 0;
left: unset !important;
top: 35px;
}
.endpoint-query-dropdown::after, .export-dropdown::after {
.endpoint-query-dropdown::after {
content: '';
display: block;
width:0;
@@ -396,10 +393,6 @@ export default {
position: absolute;
right: 3px;
bottom: 0;
}
.export-dropdown::after {
transform: translate(-50%, -54px);
}
.endpoint-query-dropdown::after {
transform: translate(-50%, -45px);

View File

@@ -187,7 +187,7 @@ export const fromRoute = {
assetType: 'assetType',
assetState: 'assetState',
expressionTemplate: 'expressionTemplate',
account: 'account',
user: 'user',
promServer: 'promServer',
dc: 'dc',
role: 'role',

View File

@@ -46,7 +46,7 @@ const cn = {
createEndpoint: '新增Endpoint',
createAsset: '新增资产',
createAlertRule: '新增告警规则',
createAccount: '新增用户',
createUser: '新增用户',
createRole: '新增角色',
createTemplate: '新增模板',
createPrometheusServer: '新增prometheus服务',
@@ -640,9 +640,9 @@ const cn = {
},
config: {
config: '设置',
account: {
accountList: '用户列表',
account: '用户',
user: {
userList: '用户列表',
user: '用户',
name: '姓名', // "用户"
username: '登录名', // 登录名
roles: '角色',
@@ -654,9 +654,9 @@ const cn = {
lastLoginTime: '最后登录时间', // 最后登录时间
lastLoginIp: '最后登录IP', // 最后登录IP
source: '来源',
accountId: '用户ID',
createAccount: '新增用户',
editAccount: '编辑用户',
userId: '用户ID',
createUser: '新增用户',
editUser: '编辑用户',
notCurrentlySupport: '暂不支持',
password: '密码',
oldPwd: '旧密码',

View File

@@ -53,7 +53,7 @@ const en = {
createEndpoint: 'Create endpoint',
createAsset: 'Create asset',
createAlertRule: 'Create alert rule',
createAccount: 'Create account',
createUser: 'Create user',
createRole: 'Create role',
createPrometheusServer: 'Create prometheus server',
createDatacenter: 'Create Data center',
@@ -641,9 +641,9 @@ const en = {
},
config: {
config: 'Settings', // "设置"
account: {
accountList: 'User list', // "用户列表"
account: 'User',
user: {
userList: 'User list', // "用户列表"
user: 'User',
// 列表表头
name: 'Name', // "用户"
username: 'Username', // 登录名
@@ -657,9 +657,9 @@ const en = {
lastLoginIp: 'Last login IP', // 最后登录IP
source: 'Source',
// 侧滑框//
accountId: 'User ID', // "用户ID"
createAccount: 'New user', // "新增用户"
editAccount: 'Edit user', // "编辑用户"
userId: 'User ID', // "用户ID"
createUser: 'New user', // "新增用户"
editUser: 'Edit user', // "编辑用户"
notCurrentlySupport: 'Not available', // '暂不支持'
password: 'Password', // '密码'
oldPwd: 'Old password',

View File

@@ -0,0 +1,212 @@
import bus from '@/libs/bus'
import { tableSet } from '@/components/common/js/tools'
import { fromRoute } from '@/components/common/js/constants'
export default {
data () {
return {
fromRoute: fromRoute,
// 侧滑
rightBox: {
show: false
},
pageObj: { // 分页对象
pageNo: 1,
pageSize: this.$CONSTANTS.defaultPageSize,
total: 0
},
/* 工具参数 */
tools: {
loading: false, // 是否显示table加载动画
customTableTitle: [] // 自定义列工具的数据
},
mainTableHeight: this.$tableHeight.normal, // 主列表table高度
batchDeleteObjs: [],
object: {},
tableData: [],
searchLabel: {}, // 搜索参数
scrollbarWrap: null,
delFlag: false,
operationWidth: '165' // 操作列宽
}
},
methods: {
sortableShow: tableSet.sortableShow,
propTitle: tableSet.propTitle,
asce: tableSet.asce,
desc: tableSet.desc,
strTodate: tableSet.strTodate,
tableOperation ([command, row, url]) {
switch (command) {
case 'edit': {
this.edit(row)
break
}
case 'delete': {
this.del(row, url)
break
}
default:
break
}
},
isBuildIn (row) {
return (row.buildIn && row.buildIn == 1) || (row.builtIn && row.builtIn == 1)
},
getTableData () {
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
this.$get(this.url, this.searchLabel).then(response => {
this.tools.loading = false
if (response.code === 200) {
for (let i = 0; i < response.data.list.length; i++) {
response.data.list[i].status = response.data.list[i].status + ''
}
this.tableData = response.data.list
this.pageObj.total = response.data.total
if (!this.scrollbarWrap) {
this.$nextTick(() => {
this.scrollbarWrap = this.$refs.dataTable.$refs.dataTable.bodyWrapper
this.toTopBtnHandler(this.scrollbarWrap)
})
}
}
})
},
del (row) {
this.$confirm(this.$t('tip.confirmDelete'), {
confirmButtonText: this.$t('tip.yes'),
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
this.$delete(this.url).then(response => {
if (response.code === 200) {
this.delFlag = true
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.getTableData()
} else {
this.$message.error(response.msg)
}
})
})
},
newObject () {
return JSON.parse(JSON.stringify(this.blankObject))
},
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()
},
add () {
this.object = this.newObject()
this.rightBox.show = true
},
closeRightBox (refresh) {
this.rightBox.show = false
if (refresh) {
this.delFlag = true
this.getTableData()
}
},
edit (u) {
this.object = JSON.parse(JSON.stringify(u))
this.rightBox.show = true
},
esc () {
this.rightBox.show = false
},
dragend () {
this.$nextTick(() => {
this.$refs.dataTable.$refs.dataTable.doLayout()
})
},
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.dataTable) {
this.$refs.dataTable.bodyWrapper.scrollTop = 0
}
this.getTableData()
},
tableDataSort (orderBy) {
this.$set(this.searchLabel, 'orderBy', orderBy)
this.getTableData()
},
tableTitleReset (src, dist) {
dist.forEach(item => {
const title = src.find(t => t.prop === item.prop)
if (title && title.label) {
item.label = title.label
}
})
},
toTop (wrap) {
let currentTop = wrap.scrollTop
const interval = currentTop / 10
const intervalFunc = setInterval(function () { // 花200ms分10次回到顶部模拟动画效果
if (currentTop === 0) {
clearInterval(intervalFunc)
} else {
currentTop = (currentTop - interval) < interval * 0.5 ? 0 : currentTop - interval
wrap.scrollTop = currentTop
}
}, 20)
},
toTopBtnHandler (wrap) {
const vm = this
wrap.addEventListener('scroll', bus.debounce(function () {
vm.tools.showTopBtn = wrap.scrollTop > 50
vm.tools.tableHover = wrap.scrollTop > 50
}, 100))
}
},
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.dataTable.bodyWrapper.scrollTop = 0
} else {
this.delFlag = false
} */
}
},
'tools.customTableTitle': {
deep: true,
handler (n) {
this.dragend()
}
}
},
mounted () {
const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
if (pageSize && pageSize !== 'undefined') {
this.pageObj.pageSize = pageSize
}
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.$refs.dataTable.tableTitle
this.getTableData()
},
beforeDestroy () {
if (this.scrollbarWrap) {
this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
}
}
}

View File

@@ -1,123 +1,51 @@
import bus from '@/libs/bus'
import { tableSet } from '@/components/common/js/tools'
import { fromRoute } from '@/components/common/js/constants'
export default {
props: {
tableData: {
type: Array
},
customTableTitle: {
type: Array
},
height: {
type: String,
default: '100%'
},
url: {
type: String
}
},
data () {
return {
fromRoute: fromRoute,
// 侧滑
rightBox: {
show: false
},
pageObj: { // 分页对象
pageNo: 1,
pageSize: this.$CONSTANTS.defaultPageSize,
total: 0
},
/* 工具参数 */
tools: {
loading: false, // 是否显示table加载动画
customTableTitle: [] // 自定义列工具的数据
},
mainTableHeight: this.$tableHeight.normal, // 主列表table高度
batchDeleteObjs: [],
object: {},
tableData: [],
searchLabel: {}, // 搜索参数
scrollbarWrap: null,
delFlag: false,
operationWidth: '165' // 操作列宽
}
},
methods: {
sortableShow: tableSet.sortableShow,
propTitle: tableSet.propTitle,
asce: tableSet.asce,
desc: tableSet.desc,
strTodate: tableSet.strTodate,
tableOperation ([command, row, url]) {
tableOperation ([command, row]) {
switch (command) {
case 'edit': {
this.edit(row)
this.$emit('edit', row)
break
}
case 'delete': {
this.del(row, url)
this.$emit('del', row)
break
}
default:
break
}
},
isBuildIn (row) {
isBuiltIn (row) {
return (row.buildIn && row.buildIn == 1) || (row.builtIn && row.builtIn == 1)
},
del (row, url) {
this.$confirm(this.$t('tip.confirmDelete'), {
confirmButtonText: this.$t('tip.yes'),
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
this.$delete(url).then(response => {
if (response.code === 200) {
this.delFlag = true
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.getTableData()
} else {
this.$message.error(response.msg)
}
})
})
},
newObject () {
return JSON.parse(JSON.stringify(this.blankObject))
},
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()
},
add () {
this.object = this.newObject()
this.rightBox.show = true
},
closeRightBox (refresh) {
this.rightBox.show = false
if (refresh) {
this.delFlag = true
this.getTableData()
}
},
edit (u) {
this.object = JSON.parse(JSON.stringify(u))
this.rightBox.show = true
},
esc () {
this.rightBox.show = false
},
dragend () {
this.$nextTick(() => {
console.info(1)
this.$refs.dataTable.doLayout()
})
},
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.dataTable) {
this.$refs.dataTable.bodyWrapper.scrollTop = 0
}
this.getTableData()
showBottomBox (targetTab, row) {
this.$emit('showBottomBox', targetTab, JSON.parse(JSON.stringify(row)))
},
tableDataSort (item) {
let orderBy = ''
@@ -127,73 +55,7 @@ export default {
if (item.order === 'descending') {
orderBy = '-' + item.prop
}
this.$set(this.searchLabel, 'orderBy', orderBy)
this.getTableData()
},
tableTitleReset (src, dist) {
dist.forEach(item => {
const title = src.find(t => t.prop === item.prop)
if (title && title.label) {
item.label = title.label
}
})
},
toTop (wrap) {
let currentTop = wrap.scrollTop
const interval = currentTop / 10
const intervalFunc = setInterval(function () { // 花200ms分10次回到顶部模拟动画效果
if (currentTop === 0) {
clearInterval(intervalFunc)
} else {
currentTop = (currentTop - interval) < interval * 0.5 ? 0 : currentTop - interval
wrap.scrollTop = currentTop
}
}, 20)
},
toTopBtnHandler (wrap) {
const vm = this
wrap.addEventListener('scroll', bus.debounce(function () {
vm.tools.showTopBtn = wrap.scrollTop > 50
vm.tools.tableHover = wrap.scrollTop > 50
}, 100))
}
},
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.dataTable.bodyWrapper.scrollTop = 0
} else {
this.delFlag = false
}
}
},
'tools.customTableTitle': {
deep: true,
handler (n) {
this.dragend()
}
}
},
mounted () {
const pageSize = localStorage.getItem('nz-pageSize-' + localStorage.getItem('nz-username') + '-' + this.tableId)
if (pageSize != 'undefined' && pageSize != null) {
this.pageObj.pageSize = pageSize
}
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)
this.$emit('orderBy', orderBy)
}
}
}

View File

@@ -115,7 +115,7 @@
<div :class="showDropdown?'compare-box':''"><i class="nz-icon nz-icon-compare" @click="changeShowDropdown" /></div>
<!-- name="multiple-time-datepicker"-->
<transition>
<div class="calendar top-tools" id="panel-calender" v-show="showDropdown">
<div v-show="showDropdown" id="panel-calender" class="calendar">
<el-date-picker prefix-icon=" " size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm:ss" class="panel-time-picker-hidden" @change="dateChange" v-model="startTime" type="datetime"
popper-class="panel-time-picker-popper"

View File

@@ -1,24 +1,34 @@
<template>
<div class="interval-refresh ">
<time-picker v-if="showTimePicker" ref="timePicker" class="time-picker" @change="dateChange" :default-pick="defaultPick" :show-empty="showEmpty" v-model="this.searchTime"></time-picker>
<div class="interval-refresh">
<time-picker v-if="showTimePicker" ref="timePicker" v-model="searchTime" :default-pick="defaultPick" :show-empty="showEmpty" class="time-picker margin-r-10" size="small" @change="dateChange"></time-picker>
<multipleTime ref="multipleTime" v-if="showMultiple" :stepSearchTime="searchTime" @change="dateChange(searchTime)" class="multiple-time"/>
<chart-unit v-model="unit" v-if="useChartUnit"></chart-unit>
<div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light margin-r-20" style="height: 28px;line-height: 28px;vertical-align: middle;" v-show="useRefresh">
<button style="border-right: 1px solid rgba(162,162,162,0.50);" type="button" class="nz-btn nz-btn-size-normal nz-btn-style-light" @click="refreshDataFunc" :id="id+'-refresh'">
<i style="font-size: 14px" class="global-active-color nz-icon nz-icon-refresh"></i>&nbsp;
<span class="nz-btn nz-btn-text" ><slot name="added-text"></slot></span>
</button>
<el-popover v-model="visible" placement="bottom-start" :width="50" trigger="click" popper-class="interval-refresh-popover" >
<ul class="popover_ul">
<li v-for="i in $CONSTANTS.intervalList" :style="{color:interval == i.value ? '#31749C' : ''}" :key="i.value + i.label" @click="selectInterval(i)">
<div v-show="useRefresh" class="top-tool-btn-group">
<button :id="id+'-refresh'" class="top-tool-btn" @click="refreshDataFunc">
<i class="global-active-color nz-icon nz-icon-refresh" style="font-size: 14px"></i>&nbsp;
<span class="nz-btn nz-btn-text" ><slot name="added-text"></slot></span>
</button>
<button id="browser-go" class="top-tool-btn top-tool-btn--dropdown" @mouseenter="dropdownHandler(true)" @mouseleave="dropdownHandler(false)">
<i class="nz-icon nz-icon-arrow-down" style="font-size: 12px;"></i>
<transition name="el-zoom-in-top">
<ul v-show="dropdownShow" class="el-dropdown-menu el-popper el-dropdown-menu--mini nz-dropdown">
<li v-for="i in $CONSTANTS.intervalList" :key="i.value + i.label" :style="{color:interval === i.value || interval.value === i.value ? theme.themeColor : ''}" class="el-dropdown-menu__item dropdown-content" @click="selectInterval(i)">
{{i.label}}
</li>
</ul>
<button type="button" style="border-radius: 0 4px 4px 0;padding:0px;" class="nz-btn nz-btn-size-normal nz-btn-style-light" slot="reference">
<span class="nz-btn nz-btn-text" style="padding-left: 10px;" v-if="interval.value && interval.value != -1">{{interval.label}}</span><i class="nz-icon nz-icon-arrow-down" style="font-size: 14px"></i>
</button>
</el-popover>
</div>
</transition>
</button>
<!-- <el-popover v-model="visible" placement="bottom-start" :width="50" trigger="click" popper-class="interval-refresh-popover" >
<ul class="popover_ul">
<li v-for="i in $CONSTANTS.intervalList" :style="{color:interval == i.value ? '#31749C' : ''}" :key="i.value + i.label" @click="selectInterval(i)">
{{i.label}}
</li>
</ul>
<button type="button" class="top-tool-btn" slot="reference">
<span v-if="interval.value && interval.value != -1">{{interval.label}}</span><i class="nz-icon nz-icon-arrow-down" style="font-size: 14px"></i>
</button>
</el-popover>-->
</div>
</div>
</template>
@@ -27,6 +37,7 @@ import bus from '../../libs/bus'
import timePicker from './timePicker'
import multipleTime from './multipleTime'
import chartUnit from './chartUnit'
let timeout
export default {
name: 'intervalRefresh',
components: {
@@ -73,7 +84,8 @@ export default {
visible: false,
intervalTimer: null,
interval: -1,
unit: 2
unit: 2,
dropdownShow: false
}
},
created () {
@@ -83,8 +95,8 @@ export default {
methods: {
selectInterval (val) {
this.visible = false
clearInterval(this.intervalTimer)
this.interval = val
this.interval = val.value
console.info(this.interval, val)
if (!this.showTimePicker && val && val.value != -1) {
this.intervalTimer = setInterval(() => {
this.$emit('change', this.searchTime)
@@ -104,6 +116,16 @@ export default {
}, val.value * 1000)
}
},
dropdownHandler (show) {
if (show) {
clearTimeout(timeout)
this.dropdownShow = true
} else {
timeout = setTimeout(() => {
this.dropdownShow = false
}, 700)
}
},
getIntervalData (interval) { // interval:结束时间到现在的秒数
// const start = new Date(this.searchTime[0])
// const end = new Date(this.searchTime[1])
@@ -141,35 +163,8 @@ export default {
}
</script>
<style scoped lang="scss">
.interval-refresh{
<style lang="scss">
.interval-refresh {
display: flex;
align-items: center;
}
.interval-refresh .time-picker{
margin-right: 20px;
}
.popover_ul{
text-align: center;
}
.popover_ul li {
padding: 10px 3px;
cursor: pointer;
}
.popover_ul li:hover {
background: $dropdown-hover-background-color !important;
color: $global-text-color-active !important;
}
</style>
<style>
.interval-refresh-popover{
min-width: unset !important;
z-index:3000 !important;
}
.sub-top-tools .interval-refresh {
margin-top: -1px;
}
.multiple-time{
margin-right: 20px;
}
</style>

View File

@@ -2,12 +2,12 @@
$--input-focus-border: red;
</style>
<template>
<div class="right-box right-box-account" v-clickoutside="{obj:editUser,func:clickOutside}">
<div v-clickoutside="{obj:editUser,func:clickOutside}" class="right-box right-box-account">
<!-- begin--顶部按钮-->
<div class="right-box-top-btns right-box-form-delete">
<button v-if="editUser.id&&editUser.id!==1" v-has="'account_delete'" type="button" @click="del"
class="nz-btn nz-btn-size-normal nz-btn-size-alien"
id="account-edit-del">
<button v-if="editUser.id&&editUser.id!==1" id="account-edit-del" v-has="'account_delete'" class="nz-btn nz-btn-size-normal nz-btn-size-alien"
type="button"
@click="del">
<span class="right-box-top-btn-icon"><i class="nz-icon nz-icon-delete"></i></span>
<span class="right-box-top-btn-txt">{{$t('overall.delete')}}</span>
</button>
@@ -23,22 +23,22 @@ $--input-focus-border: red;
<el-form ref="accountForm" :model="editUser" :rules="editUser.id ? rules2 : rules" class="right-box-form right-box-form-left" label-position = "top" label-width="120px">
<!--username-->
<el-form-item :label="$t('config.account.account')" prop="username">
<el-input autocomplete="new-password" type="text" placeholder="" id="account-input-username"
v-model="editUser.username" :disabled="editUser.username==='admin' && editUser.id==1" maxlength="64" show-word-limit size="small"></el-input>
<el-input id="account-input-username" v-model="editUser.username" :disabled="editUser.username==='admin' && editUser.id==1" autocomplete="new-password"
maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
</el-form-item>
<!--password-->
<el-form-item :label="$t('config.account.password')" prop="pin">
<el-input autocomplete="new-password" type="password" placeholder="" v-model="editUser.pin" id="account-input-password"
maxlength="16" show-word-limit size="small" @blur="passwordBlur"></el-input>
<el-input id="account-input-password" v-model="editUser.pin" autocomplete="new-password" maxlength="16" placeholder=""
show-word-limit size="small" type="password" @blur="passwordBlur"></el-input>
</el-form-item>
<!--passwordChange-->
<el-form-item :label="$t('config.account.confirmPwd')" label-width="200px" prop="passwordChange">
<el-input autocomplete="new-password" type="password" placeholder="" v-model="editUser.pinChange" id="account-input-passwordChange"
maxlength="16" show-word-limit size="small"></el-input>
<el-input id="account-input-passwordChange" v-model="editUser.pinChange" autocomplete="new-password" maxlength="16" placeholder=""
show-word-limit size="small" type="password"></el-input>
</el-form-item>
<!--email-->
<el-form-item label="E-mail" prop="email">
<el-input type="text" placeholder="" v-model="editUser.email" size="small" id="account-input-email"></el-input>
<el-input id="account-input-email" v-model="editUser.email" placeholder="" size="small" type="text"></el-input>
</el-form-item>
<!--enable-->
<el-form-item :label="$t('config.account.enable')">
@@ -59,7 +59,7 @@ $--input-focus-border: red;
</el-form-item>
<div class="right-box-sub-title">{{$t('config.account.notification')}}
<button @click="addNotification" id="add-notification" type="button" class="float-right" :disabled="addDisabled">
<button id="add-notification" :disabled="addDisabled" class="float-right" type="button" @click="addNotification">
<span><i class="nz-icon nz-icon-create-square"></i></span>
</button>
</div>
@@ -67,11 +67,11 @@ $--input-focus-border: red;
<div class="right-box-line"></div>
<div id="account-input-box">
<el-form-item v-for="(notification, index) in editUser.notifications" :key="index" class="notification-item">
<el-select placeholder="" popper-class="no-style-class" size="small" v-model="notification.scriptId" style="display: inline-block;width: 100px;margin-left: 15px">
<el-option v-for="(item, i) in selectableScripts" :label="item.name" :key="i" :value="item.id" :disabled="item.disabled"></el-option>
<el-select v-model="notification.scriptId" placeholder="" popper-class="no-style-class" size="small" style="display: inline-block;width: 100px;margin-left: 15px">
<el-option v-for="(item, i) in selectableScripts" :key="i" :disabled="item.disabled" :label="item.name" :value="item.id"></el-option>
</el-select>
<el-input placeholder="" v-model="notification.account" size="small" style="width: calc(100% - 157px);"></el-input>
<span @click="removeNotification(index)" style="padding-left: 5px;"><i class="nz-icon nz-icon-shanchu1"></i></span>
<el-input v-model="notification.account" placeholder="" size="small" style="width: calc(100% - 157px);"></el-input>
<span style="padding-left: 5px;" @click="removeNotification(index)"><i class="nz-icon nz-icon-shanchu1"></i></span>
</el-form-item>
</div>
</el-form>
@@ -83,9 +83,9 @@ $--input-focus-border: red;
class="nz-btn nz-btn-size-normal-new nz-btn-style-light-new">
<span>{{$t('overall.cancel')}}</span>
</button>
<button @click="save" id="account-save"
class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new"
:disabled="prevent_opt.save" :class="{'nz-btn-disabled':prevent_opt.save}"
<button id="account-save" :class="{'nz-btn-disabled':prevent_opt.save}"
:disabled="prevent_opt.save"
class="nz-btn nz-btn-size-normal-new nz-btn-style-normal-new" @click="save"
>
<span>{{$t('overall.save')}}</span>
</button>

View File

@@ -1364,13 +1364,12 @@ export default {
.top-tools input {
background-color: white;
}
.new-search{
.new-search{
display: flex;
position: relative;
line-height: 25px;
border-radius: 2px;
border: 1px solid #D8D8D8;
/*box-shadow: inset 0 0 5px 0 rgba(184,184,184,0.80);*/
border: 1px solid $--primary-border-color;
}
.new-search .search-input-all{
width: 226px !important;

View File

@@ -9,17 +9,17 @@
<slot name="top-tool-left"></slot>
</div>
<div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
<div v-if="components.indexOf('searchInput') > -1" class="top-tool-search">
<div v-if="layout.indexOf('searchInput') > -1" class="top-tool-search">
<search-input ref="searchInput" :inTransform="bottomBox.inTransform" :searchMsg="searchMsg" @search="search"></search-input>
</div>
<slot name="top-tool-right"></slot>
<button v-if="components.indexOf('elementSet') > -1" id="account-column-setting" class="top-tool-btn margin-l-10"
type="button" @click="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)">
<button v-if="layout.indexOf('elementSet') > -1" id="account-column-setting" class="top-tool-btn margin-l-10"
type="button" @click="tools.showCustomTableTitle = true">
<i class="nz-icon-gear nz-icon"></i>
</button>
</div>
<!-- 顶部分页组件当打开底部上滑框时出现 -->
<div v-if="components.indexOf('pagination') > -1" class="pagination-top pagination-top-hide display-none"></div>
<div v-if="layout.indexOf('pagination') > -1" class="pagination-top pagination-top-hide display-none"></div>
</div>
<!-- 自定义table列 -->
<transition name="el-zoom-in-top">
@@ -76,7 +76,7 @@ export default {
customTableTitle: {
type: Array
},
components: {
layout: {
type: Array,
default () { return [] }
},
@@ -114,7 +114,6 @@ export default {
// 全屏
fullScreen () {
const vm = this
// this.$bottomBoxWindow.fullScreen(vm)
bottomBoxWindow.fullScreen(vm)
},
// 退出全屏

View File

@@ -0,0 +1,162 @@
<template>
<el-table
id="userTable"
ref="dataTable"
:data="tableData"
:height="height"
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 customTableTitle"
v-if="item.show"
:key="`col-${index}`"
:fixed="item.fixed"
:label="item.label"
:min-width="`${item.minWidth}`"
: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">
<template v-if="item.prop === 'roles'">
<template v-if="scope.row[item.prop]">
<template v-for="(role, index) in scope.row[item.prop]">
<span v-if="role" :key="index"></span>
</template>
</template>
<template v-else>
<span>-</span>
</template>
</template>
<template v-else-if="item.prop === 'status'">
<el-switch
v-model="scope.row.status"
:active-color="theme.themeColor"
:disabled="isCurrentUser(scope.row.username) || !hasButton('account_toEdit') || !hasButton('account_toAdd') || (scope.row.username === 'admin' && scope.row.id === 1)"
active-value="1"
inactive-value="0"
@change="val => {statusChange(scope.row)}">
</el-switch>
</template>
<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"
: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="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, `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>
</el-table-column>
</el-table>
</template>
<script>
import table from '@/components/common/mixin/table'
export default {
name: 'userTable',
mixins: [table],
data () {
return {
tableTitle: [ // 原始table列
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.user.name'),
prop: 'name',
show: true,
width: 150
}, {
label: this.$t('config.user.username'),
prop: 'username',
show: true,
width: 150
}, {
label: this.$t('config.user.roles'),
prop: 'roles',
show: true,
width: 150
}, {
label: 'E-mail',
prop: 'email',
show: true,
minWidth: 150
}, {
label: this.$t('config.user.lastLoginTime'),
prop: 'lastLoginTime',
show: true,
width: 200
}, {
label: this.$t('config.user.lastLoginIp'),
prop: 'lastLoginIp',
show: true,
width: 150
}, {
label: this.$t('config.user.source'),
prop: 'source',
show: true,
width: 150
}, {
label: this.$t('config.user.enable'),
prop: 'status',
show: true,
width: 100
}
]
}
},
methods: {
statusChange (user) {
if (user.roles) {
user.roleIds = user.roles.map(t => t.id)
}
this.$put(this.url, user).then(response => {
if (response.code === 200) {
this.rightBox.show = false
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
} else {
this.$message.error(response.msg)
}
this.$emit('reload')
})
}
},
computed: {
isCurrentUser () {
return function (username) {
return localStorage.getItem('nz-username') === username
}
}
}
}
</script>

View File

@@ -1,26 +1,39 @@
<style scoped lang="scss">
<style lang="scss">
.loading-font{
color:#232f3e !important;
}
popper-z-index{
z-index: 3000 !important;
}
.calendar{
.calendar {
line-height: 40px;
height: 40px;
box-sizing: border-box;
border: 1px solid $--primary-border-color;
border-radius: $--primary-border-radius;
}
.calendar.calendar--small {
line-height: 32px;
height: 32px;
.calendar-dropdown-title {
line-height: 30px;
}
}
.nz-dashboard-dropdown-bg {
background: $global-text-color-active;
color: #fff;
}
.calendar-dropdown-title {
line-height:28px;
/*line-height:28px;
padding-left:5px;
margin-left:0px;
margin-top: 0px !important;
margin-left:0;
margin-top: 0 !important;
text-align:left;
border-radius:2px;
min-width:80px;
height:28px;
border:solid 1px #d8dce1;
min-width: 80px;
height: 28px;
border:solid 1px #d8dce1;*/
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -74,7 +87,7 @@
}
</style>
<template>
<div class="calendar top-tools" id="panel-calender">
<div id="panel-calender" :class="{'calendar--small': size === 'small'}" class="calendar">
<el-date-picker prefix-icon=" " class="panel-time-picker-hidden " size="mini" ref="calendar"
format="yyyy/MM/dd HH:mm:ss" @change="dateChange" v-model="searchTime" type="datetimerange"
popper-class="panel-time-picker-popper"
@@ -87,7 +100,7 @@
class="nz-btn nz-btn-size-normal nz-btn-style-light time-picker-button time-picker-right-button" >
<i style="font-size: 12px" class="el-icon-arrow-right"></i>
</button>-->
<el-dropdown @command="timeChange" @visible-change="popoverClick" class="calendar-dropdown-title" ref="timePickerDropdown" trigger="click">
<el-dropdown ref="timePickerDropdown" class="calendar-dropdown-title" trigger="click" @command="timeChange" @visible-change="popoverClick">
<el-popover
placement="bottom-end"
min-width="120px"
@@ -132,13 +145,16 @@
</template>
<script>
import bus from '../../libs/bus'
import bus from '@/libs/bus'
export default {
name: 'timePicker',
props: {
defaultPick: Number,
showEmpty: { default: false, type: Boolean }
showEmpty: { default: false, type: Boolean },
size: {
type: String
}
},
data () {
return {

View File

@@ -14,11 +14,15 @@ export default {
}
</script>
<style scoped>
<style lang="scss">
.container {
padding: 10px;
box-sizing: border-box;
height: calc(100% - 50px);
background-color: #f6f6f6;
&>div {
height: 100%;
}
}
</style>

View File

@@ -134,7 +134,7 @@
</template>
<script>
import deleteButton from '../../common/deleteButton'
import accountBox from '../../common/rightBox/accountBox'
import accountBox from '../../common/rightBox/userBox'
import bus from '../../../libs/bus'
export default {

View File

@@ -1,294 +0,0 @@
<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.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" api="sys/user" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot:default="slotProps">
<el-table
id="account-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}`"
:min-width="`${item.minWidth}`"
class="data-column"
>
<template slot="header">
<span>{{item.label}}</span>
<div class="col-resize-area"></div>
</template>
<template slot-scope="scope" :column="item">
<template v-if="item.prop === 'roles'">
<template v-if="scope.row[item.prop]">
<template v-for="(role, index) in scope.row[item.prop]">
<span v-if="role" :key="index">{{role.i18n?$t(role.i18n):role.name}}</span>
</template>
</template>
<template v-else>
<span>-</span>
</template>
</template>
<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.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 === '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="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('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, `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>
</el-table-column>
</el-table>
<!-- 回到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">
<account-box v-if="rightBox.show" :roles="roles" :user="object" @close="closeRightBox"></account-box>
</transition>
</div>
</template>
<script>
import deleteButton from '@/components/common/deleteButton'
import accountBox from '@/components/common/rightBox/accountBox'
import nzDataList from '@/components/common/table/nzDataList'
import tableMixin from '@/components/common/mixin/table'
export default {
name: 'account',
components: {
nzDataList,
accountBox,
deleteButton
},
mixins: [tableMixin],
data () {
return {
tableId: 'accountTable', // 需要分页的table的id用于记录每页数量
blankObject: { // 空白对象
id: '',
name: '',
username: '',
email: '',
status: '1',
createTime: '',
receiver: [],
roleIds: 0,
roles: [],
lang: '',
notifications: []
},
tableTitle: [ // 原table列
{
label: 'ID',
prop: 'id',
show: true,
width: 80
}, {
label: this.$t('config.account.name'),
prop: 'name',
show: true,
width: 150
}, {
label: this.$t('config.account.username'),
prop: 'username',
show: true,
width: 150
}, {
label: this.$t('config.account.roles'),
prop: 'roles',
show: true,
width: 150
}, {
label: 'E-mail',
prop: 'email',
show: true,
minWidth: 150
}, {
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,
width: 100
}
],
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 10,
name: this.$t('config.account.account'),
type: 'input',
label: 'username',
disabled: false
}]
},
roles: []
}
},
methods: {
getTableData () {
if (!this.hasButton('account_view')) {
this.$message.error(this.$t('tip.noAccess'))
return
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
this.tools.loading = true
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++) {
response.data.list[i].status = response.data.list[i].status + ''
}
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)
})
}
}
})
},
statusChange (user) {
if (user.roles) {
user.roleIds = user.roles.map(t => t.id)
}
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') })
} else {
this.$message.error(response.msg)
}
this.getTableData()
})
},
getRoles () {
this.roles = []
this.$get('sys/role?pageSize=-1').then(response => {
if (response.code == 200) {
this.roles = response.data.list
} else {
this.$message.error('load roles faild')
}
})
},
resetTableTitle () {
const title = this.tools.customTableTitle
const tableTitle = title.slice(0, this.tableTitle.length)
const tagTitle = title.slice(this.tableTitle.length, title.length)
this.$get('/alert/script?pageNo=1&pageSize=-1').then(response => {
let scripts = response.data.list
scripts = scripts.map(item => {
return { label: item.name, prop: 'tags', show: false, allowed: true, scriptId: item.id, type: 'tag' }
})
const newTags = scripts.filter(item => { return !tagTitle.find(t => { return item.label == t.label }) })
const keepTags = tagTitle.filter(item => { return scripts.find(t => { return item.label == t.label }) })
keepTags.forEach(item => {
const script = scripts.find(t => { return item.label == t.label })
item.scriptId = script.scriptId
})
let result = tableTitle.concat([{ label: this.$t('config.account.notification'), show: false, NotSet: true, type: 'title', prop: 'table-tag' }])
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 => {
return head.scriptId === item.scriptId
})
if (notification) {
return notification.account
}
}
} */
},
computed: {
isCurrentUser () {
return function (username) {
return localStorage.getItem('nz-username') == username
}
}
},
mounted () {
this.getRoles()
this.resetTableTitle()
}
}
</script>

View File

@@ -191,11 +191,6 @@ export default {
label: this.$t('config.assetMeta.params'),
prop: 'param',
show: false
}, {
label: this.$t('alert.config.option'),
prop: 'option',
show: true,
width: 120
}
],
groupData: [{

View File

@@ -0,0 +1,124 @@
<template>
<div>
<nz-data-list
ref="dataList"
:api="url"
:custom-table-title.sync="tools.customTableTitle"
:from="fromRoute.user"
:layout="['searchInput', 'elementSet']"
:search-msg="searchMsg">
<template v-slot:top-tool-right>
<button id="account-add" v-has="'account_toAdd'" :title="$t('overall.createUser')" 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'" :api="url" :delete-objs="batchDeleteObjs" @after="getTableData" @before="delFlag=true"></delete-button>
</template>
<template v-slot="slotProps">
<user-table
ref="dataTable"
v-loading="slotProps.loading"
:api="url"
:custom-table-title="tools.customTableTitle"
:height="mainTableHeight"
:table-data="tableData"
@del="del"
@edit="edit"
@orderBy="tableDataSort"
@reload="getTableData"
@showBottomBox="(targetTab, object) => { $refs.dataList.showBottomBox(targetTab, object) }"></user-table>
</template>
<template v-slot:pagination>
<Pagination ref="Pagination" :page-obj="pageObj" :table-id="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template>
</nz-data-list>
<transition name="right-box">
<user-box v-if="rightBox.show" :roles="roles" :user="object" @close="closeRightBox"></user-box>
</transition>
</div>
</template>
<script>
import deleteButton from '@/components/common/deleteButton'
import userBox from '@/components/common/rightBox/userBox'
import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList'
import userTable from '@/components/common/table/settings/userTable'
export default {
name: 'user',
components: {
nzDataList,
userBox,
deleteButton,
userTable
},
mixins: [dataListMixin],
data () {
return {
url: 'sys/user',
blankObject: { // 空白对象
id: '',
name: '',
username: '',
email: '',
status: '1',
createTime: '',
receiver: [],
roleIds: 0,
roles: [],
lang: '',
notifications: []
},
tableId: 'userTable',
queryPermission: 'account_view',
searchMsg: { // 给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
id: 10,
name: this.$t('config.user.user'),
type: 'input',
label: 'username',
disabled: false
}]
},
roles: []
}
},
methods: {
statusChange (user) {
if (user.roles) {
user.roleIds = user.roles.map(t => t.id)
}
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') })
} else {
this.$message.error(response.msg)
}
this.getTableData()
})
},
getRoles () {
this.roles = []
this.$get('sys/role?pageSize=-1').then(response => {
if (response.code === 200) {
this.roles = response.data.list
} else {
this.$message.error('load roles faild')
}
})
}
},
computed: {
isCurrentUser () {
return function (username) {
return localStorage.getItem('nz-username') === username
}
}
},
mounted () {
this.getRoles()
}
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="panel">
<div class="panel list-page">
<div class="top-tools">
<div class="top-tool-main-left" v-if="panelData.length == 0" style="margin-left: 10px;">
<button @click="toAdd" class="nz-btn nz-btn-style-light nz-btn-size-small" id="panel-add-panel"><i class="nz-icon nz-icon-create-square"></i>&nbsp;&nbsp;{{$t("dashboard.panel.createPanelTitleSec")}}</button>
@@ -10,12 +10,12 @@
@deletePanel="del" @editPanel="edit" @selectPanel="panelChange" ref="selectPanel" style="width: 300px;display: inline-block">
<template v-slot:header>
<div class="panel-select-header">
<el-input :placeholder="$t('overall.search')" clearable size="mini" style="width: 340px; margin-right: 5px;" v-model="filterPanel" id="panel-list-search"></el-input>
<el-input id="panel-list-search" v-model="filterPanel" :placeholder="$t('overall.search')" clearable size="mini" style="width: 340px;"></el-input>
<span :title='$t("dashboard.panel.createPanelTitleSec")' @click="toAdd" class="panel-select-add" v-has="'panel_toAdd'" id="panel-list-toadd"><i class="nz-icon nz-icon-plus"></i></span>
</div>
</template>
<template v-slot:trigger>
<el-input class="panel-name input-x-mini-26" placeholder="" readonly="readonly" v-model="showPanel.name">
<el-input v-model="showPanel.name" class="panel-name" placeholder="" readonly="readonly" size="small">
<i class="el-icon-menu" slot="prefix"></i>
</el-input>
</template>
@@ -64,8 +64,8 @@
</el-dropdown>-->
</div>
<div class="top-tool-main-right">
<div class="top-tool-search relative-position margin-r-20">
<el-input ref="queryPanel" @clear="clearInput" id="queryPanel" @focus="focusInput" @blur="blurInput" v-model="filter.searchName" class="query-input-inactive" size="mini" clearable >
<div class="top-tool-search margin-r-20">
<el-input id="queryPanel" ref="queryPanel" v-model="filter.searchName" class="query-input-inactive" clearable size="small" @blur="blurInput" @clear="clearInput" @focus="focusInput">
<i slot="suffix" class="el-input__icon nz-icon nz-icon-search" @click="focusInput" style="float: right"></i>
</el-input>
</div>
@@ -82,18 +82,16 @@
export: 'panel_chart_export'
}"
@afterImport="dateChange"
class="margin-r-20"
class="top-tool-export margin-l-10"
>
<template slot="optionZone">
<button :title="$t('overall.createChart')" @click="addChart" v-has="'panel_chart_toAdd'"
class="nz-btn nz-btn-size-normal nz-btn-style-light " id="panel-add-chart">
id="panel-add-chart" class="top-tool-btn">
<i class="nz-icon-create-square nz-icon"></i>
</button>
</template>
</export-excel>
<div class="relative-position ">
<button @click="panelLock=!panelLock" class="nz-btn nz-btn-size-normal nz-btn-style-light" type="button" id="panel-lock"><i :class="{'nz-icon nz-icon-lock':panelLock,'nz-icon nz-icon-unlock':!panelLock}"></i></button>
</div>
<button id="panel-lock" class="top-tool-btn margin-l-10" type="button" @click="panelLock=!panelLock"><i :class="{'nz-icon nz-icon-lock':panelLock,'nz-icon nz-icon-unlock':!panelLock}"></i></button>
</div>
</template>
</div>
@@ -788,7 +786,7 @@ export default {
}
}
</script>
<style scoped lang="scss">
<style lang="scss">
.panel {
height: 100%;
display: flex;
@@ -799,60 +797,6 @@ export default {
border-radius: 5px;
}
.panel-list-width {
width: 400px;
}
.panel-dropdown-title {
line-height:24px;
padding-left:5px;
/*margin-left:10px;*/
margin-top: 3px;
text-align:left;
border-radius:4px;
width:260px;
height:24px;
border:solid 1px #d8dce1;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.panel-list-title {
min-height:24px;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.panel-list-item {
width:190px;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
.content-right-option {
cursor: pointer;
display: inline-block;
margin-right: 6px;
}
.content-right-option .nz-icon-delete {
color: #F98D9A;
}
.content-right-option .nz-icon-delete:hover {
color: #D96D7A;
}
.content-right-option .nz-icon-view {
color: #60BEFF;
}
.content-right-option .nz-icon-view:hover {
color: #409EFF;
}
/* begin-chart list*/
.table-list {
margin-top: 0px;
@@ -863,212 +807,26 @@ export default {
.box-content {
position: relative;
min-height: 100%;
height: 100%;
}
/* end-chart list*/
/* begin--Panel-自定义可编辑的el-select下拉框样式*/
.panel-dropdown-btn {
display: inline-block;
margin-left: 7px;
float: right;
color: #60BEFF;
font-size: 13px
}
.panel-dropdown-btn:hover {
color: #409EFF;
}
.panel-dropdown-btn-create {
display: inline-block;
float: left;
font-size: 13px;
color: #F98D9A;
width: 100%;
}
.panel-dropdown-btn-create:hover {
color: #D96D7A;
}
.panel-dropdown-btn-delete {
color: #F98D9A;
font-size: 13px
}
.panel-dropdown-btn-delete:hover {
color: #D96D7A;
}
.panel-dropdown-error-message {
color: #F98D9A;
}
/* end--Panel-自定义可编辑的el-select下拉框样式*/
.panel-refresh-interval {
margin-right: 5px;
float: right;
}
.panel-refresh-interval-select {
width: 95px;
}
.panel-calendar {
float: right;
margin-right: 1px;
}
.top-tools {
button {
background: $btn-light-background-color;
outline: none;
border: 1px solid #ccc;
}
button:hover {
}
}
.nz-dashboard-dropdown {
height: 300px;
overflow-y: hidden;
li {
/*padding: 0 20px !important;*/
padding-left:20px !important;
padding-right:0px !important;
width:240px;
white-space:nowrap;
overflow-x:hidden;
text-overflow:ellipsis;
}
}
.nz-dashboard-dropdown-bg {
background: $global-text-color-active;
color: #fff;
}
.el-dropdown-link {
cursor: pointer;
font-weight: bold;
}
.refresh {
display: flex;
background: #fff;
border-radius: 4px;
align-items: center;
justify-content: center;
margin: 0 10px;
border: 1px solid #ccc;
background: $btn-light-background-color;
span {
display: inline-block;
padding: 1px 8px;
}
}
.popover_ul li {
padding: 10px 3px;
cursor: pointer;
}
.popover_ul li:hover {
background: $dropdown-hover-background-color !important;
color: $global-text-color-active !important;
}
.nz-dashboard-refresh {
border-right: 1px solid #ccc;
color: #F0BF84;
}
.nz-dashboard-picker {
}
.move-area:hover{
cursor: move;
}
</style>
<style lang="scss">
.panel-name {
position: relative;
.el-input__prefix i {
position: absolute;
left: 3px;
top: calc(50% + 1px);
transform: translateY(-50%);
.el-input__prefix {
line-height: 32px;
left: 10px;
}
}
.panel-name>input {
cursor: pointer;
padding-left: 27px !important;
}
.panel-select-header {
padding: 0 0 10px 16px;
width: 400px;
}
.panel-select-add {
cursor: pointer;
}
.panel-select-add:hover {
color: $global-text-color-active;
}
.panel .top-tools input {
background-color: $content-right-background-color;
}
.panel .top-tools .el-input__inner {
background-color: $content-right-background-color;
}
.panel-calendar .el-range-editor--mini.el-input__inner {
height: 25px !important;
border-color: #d8d8d8;
}
.panel-calendar .el-range-editor--mini .el-range__close-icon {
line-height: 18px;
}
.panel-calendar .el-range-editor--mini .el-range__icon {
display: none;
}
.panel-calendar .el-range-editor--mini .el-range-separator {
line-height: 17px;
}
.panel-calendar .el-date-editor--datetimerange.el-input, .panel-calendar .el-date-editor--datetimerange.el-input__inner {
padding-right: 0;
vertical-align: top;
}
.nz-dashboard-dropdown .nz-icon-edit {
font-size: 16px;
vertical-align: middle;
}
.nz-dashboard-dropdown .nz-icon-delete {
vertical-align: middle;
}
.panel-title-li{
.panel-dropdown-btn{
visibility: hidden;
}
}
.panel-title-li:hover{
.panel-dropdown-btn{
visibility: visible;
display: flex;
justify-content: space-evenly;
margin-bottom: 15px;
.panel-select-add {
line-height: 26px;
cursor: pointer;
}
}
/* end-chart list*/
</style>
<style>
.box-content .show-top .chartBox:last-child{
margin-bottom: 50px !important;
}
.box-content .show-top .chart-group .chartBox:last-child{
margin-bottom: 0px !important;
}
<style lang="scss">
@import '@/assets/css/common/tableCommon.scss';
</style>

View File

@@ -30,6 +30,7 @@ import elementSet from './components/common/elementSet' // 自定义表头组件
import loading from '@/components/common/loading'
import pickTime from '@/components/common/pickTime'
import bus from '@/libs/bus'
import theme from '@/assets/css/theme.scss'
Vue.component('Pagination', Pagination)
Vue.component('searchInput', searchInput)
@@ -66,11 +67,12 @@ Vue.mixin({
prevent_opt: {
save: false,
import: false,
dumplicate: false,
duplicate: false,
delete: false,
refresh: false,
query: false
}
},
theme: theme // scss主题变量
}
},
methods: {

View File

@@ -43,7 +43,7 @@ export default new Router({
},
{
path: '/account',
component: resolve => require(['../components/page/config/account2.vue'], resolve)
component: resolve => require(['../components/page/config/user.vue'], resolve)
},
{
path: '/menu',