diff --git a/src/router/index.js b/src/router/index.js
index 2be959d2..ba53fafb 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -11,6 +11,7 @@ import componentsRouter from './modules/components'
import chartsRouter from './modules/charts'
import tableRouter from './modules/table'
import nestedRouter from './modules/nested'
+import userRouter from './modules/user'
/**
* Note: sub-menu only appear when route children.length >= 1
@@ -189,6 +190,7 @@ export const asyncRoutes = [
chartsRouter,
nestedRouter,
tableRouter,
+ userRouter,
{
path: '/example',
diff --git a/src/router/modules/user.js b/src/router/modules/user.js
new file mode 100644
index 00000000..b1f54604
--- /dev/null
+++ b/src/router/modules/user.js
@@ -0,0 +1,24 @@
+/** 用户管理路由模块 **/
+
+import Layout from '@/layout'
+
+const userRouter = {
+ path: '/user',
+ component: Layout,
+ redirect: '/user/list',
+ name: 'User',
+ meta: {
+ title: '用户管理',
+ icon: 'people'
+ },
+ children: [
+ {
+ path: 'list',
+ component: () => import('@/views/user/index'),
+ name: 'UserList',
+ meta: { title: '用户列表', icon: 'peoples' }
+ }
+ ]
+}
+
+export default userRouter
diff --git a/src/views/table/complex-table.vue b/src/views/table/complex-table.vue
index 295c5fc4..7a687529 100644
--- a/src/views/table/complex-table.vue
+++ b/src/views/table/complex-table.vue
@@ -25,7 +25,30 @@
+
+
+ 批量删除 ({{ selectedList.length }})
+
+
+ 批量导出 ({{ selectedList.length }})
+
+
+
+
{{ row.id }}
@@ -223,7 +249,10 @@ export default {
timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
title: [{ required: true, message: 'title is required', trigger: 'blur' }]
},
- downloadLoading: false
+ downloadLoading: false,
+ selectedList: [],
+ selectedMap: {},
+ batchExportLoading: false
}
},
created() {
@@ -243,9 +272,17 @@ export default {
})
},
handleFilter() {
+ this.clearSelection()
this.listQuery.page = 1
this.getList()
},
+ clearSelection() {
+ if (this.$refs.multipleTable) {
+ this.$refs.multipleTable.clearSelection()
+ }
+ this.selectedMap = {}
+ this.selectedList = []
+ },
handleModifyStatus(row, status) {
this.$message({
message: '操作Success',
@@ -340,6 +377,9 @@ export default {
duration: 2000
})
this.list.splice(index, 1)
+ this.total = Math.max(0, this.total - 1)
+ delete this.selectedMap[row.id]
+ this.selectedList = Object.values(this.selectedMap)
},
handleFetchPv(pv) {
fetchPv(pv).then(response => {
@@ -350,19 +390,39 @@ export default {
handleDownload() {
this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => {
- const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
- const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
- const data = this.formatJson(filterVal)
- excel.export_json_to_excel({
- header: tHeader,
- data,
- filename: 'table-list'
- })
+ try {
+ const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
+ const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
+ const data = this.formatJson(filterVal)
+ const timestamp = parseTime(new Date(), '{y}{m}{d}-{h}{i}{s}')
+ excel.export_json_to_excel({
+ header: tHeader,
+ data,
+ filename: `article-list-${timestamp}`
+ })
+ this.$message({
+ message: '导出成功',
+ type: 'success'
+ })
+ } catch (error) {
+ this.$message({
+ message: '导出失败',
+ type: 'error'
+ })
+ } finally {
+ this.downloadLoading = false
+ }
+ }).catch(() => {
this.downloadLoading = false
+ this.$message({
+ message: '导出失败',
+ type: 'error'
+ })
})
},
- formatJson(filterVal) {
- return this.list.map(v => filterVal.map(j => {
+ formatJson(filterVal, dataSource) {
+ const data = dataSource || this.list
+ return data.map(v => filterVal.map(j => {
if (j === 'timestamp') {
return parseTime(v[j])
} else {
@@ -373,6 +433,101 @@ export default {
getSortClass: function(key) {
const sort = this.listQuery.sort
return sort === `+${key}` ? 'ascending' : 'descending'
+ },
+ handleSelectionChange(selection) {
+ if (!this.list || this.list.length === 0) return
+
+ const currentPageIds = this.list.map(item => item.id)
+
+ for (const id of currentPageIds) {
+ delete this.selectedMap[id]
+ }
+
+ for (const row of selection) {
+ this.selectedMap[row.id] = row
+ }
+
+ this.selectedList = Object.values(this.selectedMap)
+ },
+ handleBatchDelete() {
+ if (this.selectedList.length === 0) {
+ this.$message({
+ message: '请先选择要删除的记录',
+ type: 'warning'
+ })
+ return
+ }
+
+ this.$confirm(`确定要删除选中的 ${this.selectedList.length} 条记录吗?`, '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ }).then(() => {
+ // 批量删除操作
+ const ids = this.selectedList.map(item => item.id)
+ const newList = this.list.filter(item => !ids.includes(item.id))
+ this.list = newList
+ this.total = Math.max(0, this.total - ids.length)
+
+ for (const id of ids) {
+ delete this.selectedMap[id]
+ }
+ this.selectedList = Object.values(this.selectedMap)
+
+ if (this.$refs.multipleTable) {
+ this.$refs.multipleTable.clearSelection()
+ }
+
+ this.$notify({
+ title: 'Success',
+ message: `成功删除 ${ids.length} 条记录`,
+ type: 'success',
+ duration: 2000
+ })
+ }).catch(() => {
+ // 用户取消删除
+ })
+ },
+ handleBatchExport() {
+ if (this.selectedList.length === 0) {
+ this.$message({
+ message: '请先选择要导出的记录',
+ type: 'warning'
+ })
+ return
+ }
+
+ this.batchExportLoading = true
+ import('@/vendor/Export2Excel').then(excel => {
+ try {
+ const tHeader = ['timestamp', 'title', 'type', 'importance', 'status']
+ const filterVal = ['timestamp', 'title', 'type', 'importance', 'status']
+ const data = this.formatJson(filterVal, this.selectedList)
+ const timestamp = parseTime(new Date(), '{y}{m}{d}-{h}{i}{s}')
+ excel.export_json_to_excel({
+ header: tHeader,
+ data,
+ filename: `article-list-${timestamp}`
+ })
+ this.$message({
+ message: '导出成功',
+ type: 'success'
+ })
+ } catch (error) {
+ this.$message({
+ message: '导出失败',
+ type: 'error'
+ })
+ } finally {
+ this.batchExportLoading = false
+ }
+ }).catch(() => {
+ this.batchExportLoading = false
+ this.$message({
+ message: '导出失败',
+ type: 'error'
+ })
+ })
}
}
}
diff --git a/src/views/user/index.vue b/src/views/user/index.vue
new file mode 100644
index 00000000..44582e66
--- /dev/null
+++ b/src/views/user/index.vue
@@ -0,0 +1,542 @@
+
+
+
+
+
+ {{ advancedSearchVisible ? '收起高级搜索' : '展开高级搜索' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 启用
+ 禁用
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+ 导出选中
+
+
+ 导出全部
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getRoleLabel(row.role) }}
+
+
+
+
+
+ {{ row.createTime | parseTime('{y}-{m}-{d} {h}:{i}') }}
+
+
+
+
+
+ {{ row.status === 'enabled' ? '启用' : '禁用' }}
+
+
+
+
+
+
+ 编辑
+
+
+ {{ row.status === 'enabled' ? '禁用' : '启用' }}
+
+
+
+
+
+
+
+
+
+
+
+
+