优化更新
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
"dependencies": {
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@ckeditor/ckeditor5-vue": "^7.3.0",
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.13.2",
|
||||
"ckeditor5": "^47.4.0",
|
||||
|
||||
@@ -2,171 +2,148 @@ import request from '@/utils/request'
|
||||
|
||||
export default {
|
||||
login: {
|
||||
url: `auth/login`,
|
||||
name: '用户登录',
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('auth/login', params)
|
||||
},
|
||||
},
|
||||
logout: {
|
||||
url: `auth/logout`,
|
||||
name: '用户登出',
|
||||
get: async function () {
|
||||
return await request.get(this.url)
|
||||
return await request.get('auth/logout')
|
||||
},
|
||||
},
|
||||
user: {
|
||||
url: `auth/user`,
|
||||
name: '获取用户信息',
|
||||
get: async function () {
|
||||
return await request.get(this.url)
|
||||
return await request.get('auth/user')
|
||||
},
|
||||
},
|
||||
users: {
|
||||
list: {
|
||||
url: `auth/users/index`,
|
||||
name: "获得用户列表",
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params });
|
||||
return await request.get('auth/users/index', { params });
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `auth/users/add`,
|
||||
name: "添加用户",
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params);
|
||||
return await request.post('auth/users/add', params);
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `auth/users/edit`,
|
||||
name: "编辑用户",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/users/edit', params);
|
||||
},
|
||||
},
|
||||
uppasswd: {
|
||||
url: `auth/users/passwd`,
|
||||
name: "修改密码",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/users/passwd', params);
|
||||
},
|
||||
},
|
||||
uprole: {
|
||||
url: `auth/users/uprole`,
|
||||
name: "设置角色",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/users/uprole', params);
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `auth/users/delete`,
|
||||
name: "删除用户",
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params);
|
||||
return await request.delete('auth/users/delete', params);
|
||||
},
|
||||
},
|
||||
},
|
||||
role: {
|
||||
list: {
|
||||
url: `auth/role/index`,
|
||||
name: "获得角色列表",
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params });
|
||||
return await request.get('auth/role/index', { params });
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `auth/role/add`,
|
||||
name: "添加角色",
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params);
|
||||
return await request.post('auth/role/add', params);
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `auth/role/edit`,
|
||||
name: "编辑角色",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/role/edit', params);
|
||||
},
|
||||
},
|
||||
auth: {
|
||||
url: `auth/role/auth`,
|
||||
name: "角色授权",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/role/auth', params);
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `auth/role/delete`,
|
||||
name: "删除角色",
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params);
|
||||
return await request.delete('auth/role/delete', params);
|
||||
},
|
||||
},
|
||||
},
|
||||
department: {
|
||||
list: {
|
||||
url: `auth/department/index`,
|
||||
name: "获得部门列表",
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params });
|
||||
return await request.get('auth/department/index', { params });
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `auth/department/add`,
|
||||
name: "添加部门",
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params);
|
||||
return await request.post('auth/department/add', params);
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `auth/department/edit`,
|
||||
name: "编辑部门",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/department/edit', params);
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `auth/department/delete`,
|
||||
name: "删除部门",
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params);
|
||||
return await request.delete('auth/department/delete', params);
|
||||
},
|
||||
},
|
||||
},
|
||||
menu: {
|
||||
my: {
|
||||
url: `auth/menu/my`,
|
||||
name: '获取我的菜单',
|
||||
get: async function () {
|
||||
return await request.get(this.url)
|
||||
return await request.get('auth/menu/my')
|
||||
},
|
||||
},
|
||||
list: {
|
||||
url: `auth/menu/index`,
|
||||
name: "获取菜单",
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params });
|
||||
return await request.get('auth/menu/index', { params });
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `auth/menu/add`,
|
||||
name: "添加菜单",
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params);
|
||||
return await request.post('auth/menu/add', params);
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `auth/menu/edit`,
|
||||
name: "编辑菜单",
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params);
|
||||
return await request.put('auth/menu/edit', params);
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `auth/menu/delete`,
|
||||
name: "删除菜单",
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params);
|
||||
return await request.delete('auth/menu/delete', params);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,347 +2,301 @@ import request from '@/utils/request'
|
||||
|
||||
export default {
|
||||
version: {
|
||||
url: `system/index/version`,
|
||||
name: '获取最新版本号',
|
||||
get: async function () {
|
||||
return await request.get(this.url)
|
||||
return await request.get('system/index/version')
|
||||
},
|
||||
},
|
||||
clearcache: {
|
||||
url: `system/index/clearcache`,
|
||||
name: '清除缓存',
|
||||
post: async function () {
|
||||
return await request.post(this.url)
|
||||
return await request.post('system/index/clearcache')
|
||||
},
|
||||
},
|
||||
info: {
|
||||
url: `system/index/info`,
|
||||
name: '系统信息',
|
||||
get: function (params) {
|
||||
return request.get(this.url, { params })
|
||||
return request.get('system/index/info', { params })
|
||||
},
|
||||
},
|
||||
setting: {
|
||||
list: {
|
||||
url: `system/setting/index`,
|
||||
name: '获取配置信息',
|
||||
get: function (params) {
|
||||
return request.get(this.url, { params })
|
||||
return request.get('system/setting/index', { params })
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
url: `system/setting/fields`,
|
||||
name: '获取配置字段',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/setting/fields', { params })
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `system/setting/add`,
|
||||
name: '保存配置信息',
|
||||
post: function (data) {
|
||||
return request.post(this.url, data)
|
||||
return request.post('system/setting/add', data)
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `system/setting/edit`,
|
||||
name: '编辑配置信息',
|
||||
post: function (data) {
|
||||
return request.put(this.url, data)
|
||||
return request.put('system/setting/edit', data)
|
||||
},
|
||||
},
|
||||
save: {
|
||||
url: `system/setting/save`,
|
||||
name: '保存配置信息',
|
||||
post: function (data) {
|
||||
return request.put(this.url, data)
|
||||
return request.put('system/setting/save', data)
|
||||
},
|
||||
},
|
||||
},
|
||||
dictionary: {
|
||||
category: {
|
||||
url: `system/dict/category`,
|
||||
name: '获取字典树',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/dict/category', { params })
|
||||
},
|
||||
},
|
||||
editcate: {
|
||||
url: `system/dict/editcate`,
|
||||
name: '编辑字典树',
|
||||
post: async function (data = {}) {
|
||||
return await request.put(this.url, data)
|
||||
return await request.put('system/dict/editcate', data)
|
||||
},
|
||||
},
|
||||
addcate: {
|
||||
url: `system/dict/addcate`,
|
||||
name: '添加字典树',
|
||||
post: async function (data = {}) {
|
||||
return await request.post(this.url, data)
|
||||
return await request.post('system/dict/addcate', data)
|
||||
},
|
||||
},
|
||||
delCate: {
|
||||
url: `system/dict/deletecate`,
|
||||
name: '删除字典树',
|
||||
post: async function (data = {}) {
|
||||
return await request.delete(this.url, data)
|
||||
return await request.delete('system/dict/deletecate', data)
|
||||
},
|
||||
},
|
||||
list: {
|
||||
url: `system/dict/lists`,
|
||||
name: '字典明细',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/dict/lists', { params })
|
||||
},
|
||||
},
|
||||
get: {
|
||||
url: `system/dict/detail`,
|
||||
name: '获取字典数据',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/dict/detail', { params })
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `system/dict/edit`,
|
||||
name: '编辑字典明细',
|
||||
post: async function (data = {}) {
|
||||
return await request.put(this.url, data)
|
||||
return await request.put('system/dict/edit', data)
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `system/dict/add`,
|
||||
name: '添加字典明细',
|
||||
post: async function (data = {}) {
|
||||
return await request.post(this.url, data)
|
||||
return await request.post('system/dict/add', data)
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `system/dict/delete`,
|
||||
name: '删除字典明细',
|
||||
post: async function (data = {}) {
|
||||
return await request.delete(this.url, data)
|
||||
return await request.delete('system/dict/delete', data)
|
||||
},
|
||||
},
|
||||
detail: {
|
||||
url: `system/dict/detail`,
|
||||
name: '字典明细',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/dict/detail', { params })
|
||||
},
|
||||
},
|
||||
alldic: {
|
||||
url: `system/dict/all`,
|
||||
name: '全部字典',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/dict/all', { params })
|
||||
},
|
||||
},
|
||||
},
|
||||
area: {
|
||||
list: {
|
||||
url: `system/area/index`,
|
||||
name: '地区列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/area/index', { params })
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `system/area/add`,
|
||||
name: '地区添加',
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('system/area/add', params)
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `system/area/edit`,
|
||||
name: '地区编辑',
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params)
|
||||
return await request.put('system/area/edit', params)
|
||||
},
|
||||
},
|
||||
},
|
||||
app: {
|
||||
list: {
|
||||
url: `system/app/list`,
|
||||
name: '应用列表',
|
||||
get: async function () {
|
||||
return await request.get(this.url)
|
||||
return await request.get('system/app/list')
|
||||
},
|
||||
},
|
||||
},
|
||||
client: {
|
||||
list: {
|
||||
url: `system/client/index`,
|
||||
name: '客户端列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/client/index', { params })
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `system/client/add`,
|
||||
name: '客户端添加',
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('system/client/add', params)
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `system/client/edit`,
|
||||
name: '客户端编辑',
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params)
|
||||
return await request.put('system/client/edit', params)
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `system/client/delete`,
|
||||
name: '客户端删除',
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params)
|
||||
return await request.delete('system/client/delete', params)
|
||||
},
|
||||
},
|
||||
menu: {
|
||||
list: {
|
||||
url: `system/menu/index`,
|
||||
name: '客户端菜单列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/menu/index', { params })
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `system/menu/add`,
|
||||
name: '客户端菜单添加',
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('system/menu/add', params)
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `system/menu/edit`,
|
||||
name: '客户端菜单编辑',
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params)
|
||||
return await request.put('system/menu/edit', params)
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `system/menu/delete`,
|
||||
name: '客户端菜单删除',
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params)
|
||||
return await request.delete('system/menu/delete', params)
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
log: {
|
||||
list: {
|
||||
url: `system/log/index`,
|
||||
name: '日志列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/log/index', { params })
|
||||
},
|
||||
},
|
||||
my: {
|
||||
url: `system/log/my`,
|
||||
name: '我的日志',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/log/my', { params })
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `system/log/delete`,
|
||||
name: '日志删除',
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params)
|
||||
return await request.delete('system/log/delete', params)
|
||||
},
|
||||
},
|
||||
},
|
||||
tasks: {
|
||||
list: {
|
||||
url: `system/tasks/index`,
|
||||
name: '任务列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/tasks/index', { params })
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `system/tasks/delete`,
|
||||
name: '任务删除',
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params)
|
||||
return await request.delete('system/tasks/delete', params)
|
||||
},
|
||||
},
|
||||
},
|
||||
crontab: {
|
||||
list: {
|
||||
url: `system/crontab/index`,
|
||||
name: '定时任务列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/crontab/index', { params })
|
||||
},
|
||||
},
|
||||
add: {
|
||||
url: `system/crontab/add`,
|
||||
name: '定时任务添加',
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('system/crontab/add', params)
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
url: `system/crontab/edit`,
|
||||
name: '定时任务编辑',
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params)
|
||||
return await request.put('system/crontab/edit', params)
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
url: `system/crontab/delete`,
|
||||
name: '定时任务删除',
|
||||
post: async function (params) {
|
||||
return await request.delete(this.url, params)
|
||||
return await request.delete('system/crontab/delete', params)
|
||||
},
|
||||
},
|
||||
log: {
|
||||
url: `system/crontab/log`,
|
||||
name: '定时任务日志',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/crontab/log', { params })
|
||||
},
|
||||
},
|
||||
reload: {
|
||||
url: `system/crontab/reload`,
|
||||
name: '定时任务重载',
|
||||
post: async function (params) {
|
||||
return await request.put(this.url, params)
|
||||
return await request.put('system/crontab/reload', params)
|
||||
},
|
||||
},
|
||||
},
|
||||
modules: {
|
||||
list: {
|
||||
url: `system/modules/index`,
|
||||
name: '模块列表',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/modules/index', { params })
|
||||
},
|
||||
},
|
||||
update: {
|
||||
url: `system/modules/update`,
|
||||
name: '更新模块',
|
||||
post: async function (params) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('system/modules/update', params)
|
||||
},
|
||||
},
|
||||
},
|
||||
sms: {
|
||||
count: {
|
||||
url: `system/sms/count`,
|
||||
name: '短信发送统计',
|
||||
get: async function (params) {
|
||||
return await request.get(this.url, { params })
|
||||
return await request.get('system/sms/count', { params })
|
||||
},
|
||||
},
|
||||
},
|
||||
upload: {
|
||||
url: `system/file/upload`,
|
||||
name: '文件上传',
|
||||
post: async function (params = {}) {
|
||||
return await request.post(this.url, params)
|
||||
return await request.post('system/file/upload', params)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as AIcons from '@ant-design/icons-vue'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
|
||||
export default {
|
||||
install(app) {
|
||||
@@ -6,5 +7,9 @@ export default {
|
||||
for (let icon in AIcons) {
|
||||
app.component(`${icon}`, AIcons[icon])
|
||||
}
|
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(`El${key}`, component)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
239
src/hooks/useTable.js
Normal file
239
src/hooks/useTable.js
Normal file
@@ -0,0 +1,239 @@
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
/**
|
||||
* 表格通用hooks
|
||||
* @param {Object} options 配置选项
|
||||
* @param {Function} options.api 获取列表数据的API函数,必须返回包含data和total的响应
|
||||
* @param {Object} options.searchForm 搜索表单的初始值
|
||||
* @param {Array} options.columns 表格列配置
|
||||
* @param {String} options.rowKey 行的唯一标识,默认为'id'
|
||||
* @param {Boolean} options.needPagination 是否需要分页,默认为true
|
||||
* @param {Object} options.paginationConfig 分页配置,可选
|
||||
* @param {Boolean} options.needSelection 是否需要行选择,默认为false
|
||||
* @param {Boolean} options.immediateLoad 是否在组件挂载时自动加载数据,默认为true
|
||||
* @returns {Object} 返回表格相关的状态和方法
|
||||
*/
|
||||
export function useTable(options = {}) {
|
||||
const {
|
||||
api,
|
||||
searchForm: initialSearchForm = {},
|
||||
columns = [],
|
||||
rowKey = 'id',
|
||||
needPagination = true,
|
||||
paginationConfig = {},
|
||||
needSelection = false,
|
||||
immediateLoad = true
|
||||
} = options
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref(null)
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({ ...initialSearchForm })
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
|
||||
// 选中的行数据
|
||||
const selectedRows = ref([])
|
||||
|
||||
// 选中的行keys
|
||||
const selectedRowKeys = computed(() => selectedRows.value.map(item => item[rowKey]))
|
||||
|
||||
// 分页配置
|
||||
const defaultPaginationConfig = {
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
pageSizeOptions: ['20', '50', '100', '200']
|
||||
}
|
||||
|
||||
const pagination = reactive({
|
||||
...defaultPaginationConfig,
|
||||
...paginationConfig
|
||||
})
|
||||
|
||||
// 行选择配置
|
||||
const rowSelection = computed(() => {
|
||||
if (!needSelection) return null
|
||||
return {
|
||||
selectedRowKeys: selectedRowKeys.value,
|
||||
onChange: (keys, rows) => {
|
||||
selectedRows.value = rows
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 行选择事件处理(用于scTable的@select事件)
|
||||
const handleSelectChange = (record, selected, selectedRows) => {
|
||||
if (!needSelection) return
|
||||
if (selected) {
|
||||
selectedRows.value.push(record)
|
||||
} else {
|
||||
const index = selectedRows.value.findIndex(item => item[rowKey] === record[rowKey])
|
||||
if (index > -1) {
|
||||
selectedRows.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 全选/取消全选处理(用于scTable的@selectAll事件)
|
||||
const handleSelectAll = (selected, selectedRows, changeRows) => {
|
||||
if (!needSelection) return
|
||||
if (selected) {
|
||||
changeRows.forEach(record => {
|
||||
if (!selectedRows.value.find(item => item[rowKey] === record[rowKey])) {
|
||||
selectedRows.value.push(record)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
changeRows.forEach(record => {
|
||||
const index = selectedRows.value.findIndex(item => item[rowKey] === record[rowKey])
|
||||
if (index > -1) {
|
||||
selectedRows.value.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
const loadData = async (params = {}) => {
|
||||
if (!api) {
|
||||
console.warn('useTable: 未提供api函数,无法加载数据')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const requestParams = {
|
||||
...searchForm,
|
||||
...params
|
||||
}
|
||||
|
||||
// 如果需要分页,添加分页参数
|
||||
if (needPagination) {
|
||||
requestParams.page = pagination.current
|
||||
requestParams.limit = pagination.pageSize
|
||||
}
|
||||
|
||||
// 调用API函数,确保this上下文正确
|
||||
const res = await api(requestParams)
|
||||
|
||||
if (res.code === 1) {
|
||||
// 如果是分页数据
|
||||
if (needPagination) {
|
||||
tableData.value = res.data?.data || []
|
||||
pagination.total = res.data?.total || 0
|
||||
} else {
|
||||
// 非分页数据(如树形数据)
|
||||
tableData.value = res.data || []
|
||||
}
|
||||
} else {
|
||||
message.error(res.message || '加载数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error)
|
||||
message.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 分页变化处理
|
||||
const handlePaginationChange = ({ page, pageSize }) => {
|
||||
if (!needPagination) return
|
||||
pagination.current = page
|
||||
pagination.pageSize = pageSize
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
if (needPagination) {
|
||||
pagination.current = 1
|
||||
}
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
// 重置搜索表单为初始值
|
||||
Object.keys(searchForm).forEach(key => {
|
||||
searchForm[key] = initialSearchForm[key]
|
||||
})
|
||||
// 清空选择
|
||||
selectedRows.value = []
|
||||
// 重置分页
|
||||
if (needPagination) {
|
||||
pagination.current = 1
|
||||
}
|
||||
// 重新加载数据
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 刷新表格
|
||||
const refreshTable = () => {
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 清空选择
|
||||
const clearSelection = () => {
|
||||
selectedRows.value = []
|
||||
}
|
||||
|
||||
// 设置选中行
|
||||
const setSelectedRows = (rows) => {
|
||||
selectedRows.value = rows
|
||||
}
|
||||
|
||||
// 更新搜索表单
|
||||
const setSearchForm = (data) => {
|
||||
Object.assign(searchForm, data)
|
||||
}
|
||||
|
||||
// 直接设置表格数据(用于特殊场景)
|
||||
const setTableData = (data) => {
|
||||
tableData.value = data
|
||||
}
|
||||
|
||||
// 组件挂载时自动加载数据
|
||||
if (immediateLoad) {
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
// ref
|
||||
tableRef,
|
||||
// 响应式数据
|
||||
searchForm,
|
||||
tableData,
|
||||
loading,
|
||||
pagination,
|
||||
selectedRows,
|
||||
selectedRowKeys,
|
||||
// 配置
|
||||
columns,
|
||||
rowKey,
|
||||
rowSelection,
|
||||
// 方法
|
||||
loadData,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
handlePaginationChange,
|
||||
handleSelectChange,
|
||||
handleSelectAll,
|
||||
refreshTable,
|
||||
clearSelection,
|
||||
setSelectedRows,
|
||||
setSearchForm,
|
||||
setTableData
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,23 @@
|
||||
<template>
|
||||
<div v-show="showTags" class="tags-view">
|
||||
<a-dropdown :trigger="['contextmenu']">
|
||||
<div class="tags-wrapper">
|
||||
<a-space :size="4">
|
||||
<a-tag v-for="tag in visitedViews" :key="tag.fullPath" :closable="!tag.meta?.affix" class="tag-item"
|
||||
:class="{ active: isActive(tag) }" @click="clickTag(tag)" @close="closeSelectedTag(tag)"
|
||||
@contextmenu.prevent="handleContextMenu($event, tag)">
|
||||
{{ tag.meta?.title || tag.name }}
|
||||
</a-tag>
|
||||
</a-space>
|
||||
</div>
|
||||
<template #overlay>
|
||||
<a-menu @click="handleMenuClick">
|
||||
<a-menu-item key="refresh">
|
||||
<ReloadOutlined />
|
||||
<span>刷新</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="!selectedTag.meta?.affix" key="close">
|
||||
<CloseOutlined />
|
||||
<span>关闭</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="closeOthers">
|
||||
<ColumnWidthOutlined />
|
||||
<span>关闭其他</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="closeAll">
|
||||
<CloseCircleOutlined />
|
||||
<span>关闭所有</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<div class="tags-wrapper" @contextmenu.prevent>
|
||||
<a-space :size="4">
|
||||
<a-tag
|
||||
v-for="tag in visitedViews"
|
||||
:key="tag.fullPath"
|
||||
:closable="!tag.meta?.affix"
|
||||
class="tag-item"
|
||||
:class="{ active: isActive(tag), 'tag-affix': tag.meta?.affix }"
|
||||
@click="clickTag(tag)"
|
||||
@close="closeSelectedTag(tag)"
|
||||
@contextmenu.prevent="handleContextMenu($event, tag)">
|
||||
<template #icon v-if="tag.meta?.affix">
|
||||
<PushpinFilled />
|
||||
</template>
|
||||
{{ tag.meta?.title || tag.name }}
|
||||
</a-tag>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<div class="tags-actions">
|
||||
<a-tooltip title="刷新当前页">
|
||||
@@ -49,17 +36,55 @@
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
|
||||
<!-- 右键菜单 -->
|
||||
<teleport to="body">
|
||||
<div
|
||||
v-if="contextMenu.visible"
|
||||
:style="{
|
||||
position: 'fixed',
|
||||
left: contextMenu.x + 'px',
|
||||
top: contextMenu.y + 'px',
|
||||
zIndex: 9999
|
||||
}"
|
||||
class="context-menu"
|
||||
@click="closeContextMenu">
|
||||
<a-menu @click="handleMenuClick">
|
||||
<a-menu-item key="refresh">
|
||||
<ReloadOutlined />
|
||||
<span>刷新</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="selectedTag && !selectedTag.meta?.affix" key="close">
|
||||
<CloseOutlined />
|
||||
<span>关闭</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="closeOthers">
|
||||
<ColumnWidthOutlined />
|
||||
<span>关闭其他</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="closeAll">
|
||||
<CloseCircleOutlined />
|
||||
<span>关闭所有</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
</teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useLayoutStore } from '@/stores/modules/layout'
|
||||
import { ReloadOutlined, CloseOutlined, ColumnWidthOutlined, CloseCircleOutlined } from '@ant-design/icons-vue'
|
||||
import {
|
||||
ReloadOutlined,
|
||||
CloseOutlined,
|
||||
ColumnWidthOutlined,
|
||||
CloseCircleOutlined,
|
||||
PushpinFilled
|
||||
} from '@ant-design/icons-vue'
|
||||
import config from '@/config'
|
||||
|
||||
// 定义组件名称(多词命名)
|
||||
defineOptions({
|
||||
name: 'TagsView',
|
||||
})
|
||||
@@ -69,8 +94,15 @@ const router = useRouter()
|
||||
const layoutStore = useLayoutStore()
|
||||
|
||||
const showTags = ref(true)
|
||||
const selectedTag = ref({})
|
||||
const selectedTag = ref(null)
|
||||
const visitedViews = computed(() => layoutStore.viewTags)
|
||||
console.log(visitedViews)
|
||||
// 右键菜单状态
|
||||
const contextMenu = ref({
|
||||
visible: false,
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
|
||||
// 判断是否是当前激活的标签
|
||||
const isActive = (tag) => {
|
||||
@@ -87,7 +119,7 @@ const addTags = () => {
|
||||
name: name,
|
||||
query: route.query,
|
||||
params: route.params,
|
||||
meta: route.meta,
|
||||
meta: route.meta
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -120,7 +152,9 @@ const closeOthersTags = () => {
|
||||
}
|
||||
|
||||
// 保留固定标签和当前选中的标签
|
||||
const tagsToKeep = visitedViews.value.filter((tag) => tag.meta?.affix || tag.fullPath === selectedTag.value.fullPath)
|
||||
const tagsToKeep = visitedViews.value.filter(
|
||||
(tag) => tag.meta?.affix || tag.fullPath === selectedTag.value.fullPath
|
||||
)
|
||||
|
||||
// 更新标签列表
|
||||
layoutStore.viewTags = tagsToKeep
|
||||
@@ -142,7 +176,7 @@ const closeAllTags = () => {
|
||||
router.push(affixTags[0].fullPath)
|
||||
} else {
|
||||
// 如果没有固定标签,跳转到首页
|
||||
router.push('/home')
|
||||
router.push(config.DASHBOARD_URL)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,23 +187,52 @@ const clickTag = (tag) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新当前标签
|
||||
// 刷新指定标签
|
||||
const refreshTag = (tag) => {
|
||||
// 如果刷新的是当前激活的标签
|
||||
if (isActive(tag)) {
|
||||
// 调用 store 的刷新方法,触发组件重新渲染
|
||||
layoutStore.refreshTag()
|
||||
} else {
|
||||
// 如果刷新的是其他标签,先跳转到该标签
|
||||
router.push(tag.fullPath)
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新当前选中的标签(用于顶部操作按钮)
|
||||
const refreshSelectedTag = () => {
|
||||
// 使用 router.go(0) 刷新页面
|
||||
router.go(0)
|
||||
// 找到当前激活的标签
|
||||
const currentTag = visitedViews.value.find((tag) => isActive(tag))
|
||||
if (currentTag) {
|
||||
refreshTag(currentTag)
|
||||
}
|
||||
}
|
||||
|
||||
// 右键菜单处理
|
||||
const handleContextMenu = (event, tag) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
selectedTag.value = tag
|
||||
contextMenu.value = {
|
||||
visible: true,
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭右键菜单
|
||||
const closeContextMenu = () => {
|
||||
contextMenu.value.visible = false
|
||||
}
|
||||
|
||||
// 菜单点击处理
|
||||
const handleMenuClick = ({ key }) => {
|
||||
switch (key) {
|
||||
case 'refresh':
|
||||
refreshSelectedTag()
|
||||
if (selectedTag.value) {
|
||||
refreshTag(selectedTag.value)
|
||||
}
|
||||
break
|
||||
case 'close':
|
||||
if (selectedTag.value && !selectedTag.value.meta?.affix) {
|
||||
@@ -183,6 +246,17 @@ const handleMenuClick = ({ key }) => {
|
||||
closeAllTags()
|
||||
break
|
||||
}
|
||||
closeContextMenu()
|
||||
}
|
||||
|
||||
// 点击其他地方关闭右键菜单
|
||||
const handleClickOutside = (event) => {
|
||||
if (contextMenu.value.visible) {
|
||||
const menuElement = document.querySelector('.context-menu')
|
||||
if (menuElement && !menuElement.contains(event.target)) {
|
||||
closeContextMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听路由变化,自动添加标签
|
||||
@@ -191,15 +265,22 @@ watch(
|
||||
() => {
|
||||
addTags()
|
||||
// 更新当前选中的标签
|
||||
selectedTag.value = visitedViews.value.find((tag) => isActive(tag)) || {}
|
||||
selectedTag.value = visitedViews.value.find((tag) => isActive(tag)) || null
|
||||
},
|
||||
{ immediate: true },
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
addTags()
|
||||
// 初始化选中的标签
|
||||
selectedTag.value = visitedViews.value.find((tag) => isActive(tag)) || {}
|
||||
selectedTag.value = visitedViews.value.find((tag) => isActive(tag)) || null
|
||||
// 添加点击事件监听器
|
||||
document.addEventListener('click', handleClickOutside)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
// 移除点击事件监听器
|
||||
document.removeEventListener('click', handleClickOutside)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -236,6 +317,7 @@ onMounted(() => {
|
||||
.tag-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 12px;
|
||||
@@ -245,6 +327,7 @@ onMounted(() => {
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
@@ -262,6 +345,28 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
&.tag-affix {
|
||||
background-color: #fff7e6;
|
||||
border-color: #ffd591;
|
||||
color: #fa8c16;
|
||||
|
||||
&.active {
|
||||
background-color: #fa8c16;
|
||||
border-color: #fa8c16;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #ffe7ba;
|
||||
border-color: #ffa940;
|
||||
}
|
||||
|
||||
&.active:hover {
|
||||
background-color: #d46b08;
|
||||
border-color: #d46b08;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-tag-close-icon) {
|
||||
color: inherit;
|
||||
|
||||
@@ -289,4 +394,32 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
background: #ffffff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid #f0f0f0;
|
||||
padding: 4px 0;
|
||||
min-width: 160px;
|
||||
|
||||
:deep(.ant-menu) {
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
|
||||
.ant-menu-item {
|
||||
margin: 0;
|
||||
padding: 8px 12px;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<a-layout-content class="app-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="cachedViews">
|
||||
<component :is="Component" :key="$route.fullPath" />
|
||||
<component :is="Component" :key="refreshKey" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</a-layout-content>
|
||||
@@ -100,7 +100,7 @@
|
||||
<a-layout-content class="app-main top-content">
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :include="cachedViews">
|
||||
<component :is="Component" :key="$route.fullPath" />
|
||||
<component :is="Component" :key="refreshKey" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</a-layout-content>
|
||||
@@ -163,6 +163,9 @@ const layoutClass = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// 获取刷新 key
|
||||
const refreshKey = computed(() => layoutStore.refreshKey)
|
||||
|
||||
const openKeys = ref([])
|
||||
const selectedKeys = ref([])
|
||||
const menuList = computed(() => {
|
||||
|
||||
@@ -22,14 +22,14 @@
|
||||
<a-button type="primary" @click="handleAdd">
|
||||
<template #icon><plus-outlined /></template>
|
||||
</a-button>
|
||||
<a-button danger :disabled="selection.length === 0" @click="handleBatchDelete">
|
||||
<a-button danger :disabled="selectedRows.length === 0" @click="handleBatchDelete">
|
||||
<template #icon><delete-outlined /></template>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-content">
|
||||
<scTable ref="tableRef" :columns="columns" :data-source="tableData" :loading="loading" :pagination="false"
|
||||
:row-key="rowKey" :row-selection="rowSelection" @refresh="loadData" @select="handleSelectChange"
|
||||
:row-key="rowKey" :row-selection="rowSelection" @refresh="refreshTable" @select="handleSelectChange"
|
||||
@selectAll="handleSelectAll">
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
@@ -49,18 +49,40 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import scTable from '@/components/scTable/index.vue'
|
||||
import saveDialog from './save.vue'
|
||||
import authApi from '@/api/auth'
|
||||
import { useTable } from '@/hooks/useTable'
|
||||
|
||||
defineOptions({
|
||||
name: 'authDepartment'
|
||||
})
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref(null)
|
||||
// 使用useTable hooks
|
||||
const {
|
||||
tableRef,
|
||||
searchForm,
|
||||
tableData,
|
||||
loading,
|
||||
selectedRows,
|
||||
rowSelection,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
handleSelectChange,
|
||||
handleSelectAll,
|
||||
refreshTable
|
||||
} = useTable({
|
||||
api: authApi.department.list.get,
|
||||
searchForm: {
|
||||
keyword: ''
|
||||
},
|
||||
columns: [],
|
||||
needPagination: false,
|
||||
needSelection: true,
|
||||
immediateLoad: false
|
||||
})
|
||||
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
@@ -70,29 +92,9 @@ const dialog = reactive({
|
||||
// 弹窗引用
|
||||
const saveDialogRef = ref(null)
|
||||
|
||||
// 选中的行
|
||||
const selection = ref([])
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
keyword: ''
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
// 行key
|
||||
const rowKey = 'id'
|
||||
|
||||
// 行选择配置
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selection.value.map(item => item.id),
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
selection.value = selectedRows
|
||||
}
|
||||
}))
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: '#', dataIndex: '_index', key: '_index', width: 60, align: 'center' },
|
||||
@@ -102,69 +104,6 @@ const columns = [
|
||||
{ title: '操作', dataIndex: 'action', key: 'action', width: 220, align: 'center', slot: 'action', fixed: 'right' }
|
||||
]
|
||||
|
||||
// 加载部门列表数据
|
||||
const loadData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
is_tree: 1,
|
||||
...searchForm
|
||||
}
|
||||
const res = await authApi.department.list.get(params)
|
||||
if (res.code === 1) {
|
||||
tableData.value = res.data || []
|
||||
} else {
|
||||
message.error(res.message || '加载数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载部门列表失败:', error)
|
||||
message.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 选择变化处理
|
||||
const handleSelectChange = (record, selected, selectedRows) => {
|
||||
if (selected) {
|
||||
selection.value.push(record)
|
||||
} else {
|
||||
const index = selection.value.findIndex(item => item.id === record.id)
|
||||
if (index > -1) {
|
||||
selection.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 全选/取消全选处理
|
||||
const handleSelectAll = (selected, selectedRows, changeRows) => {
|
||||
if (selected) {
|
||||
changeRows.forEach(record => {
|
||||
if (!selection.value.find(item => item.id === record.id)) {
|
||||
selection.value.push(record)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
changeRows.forEach(record => {
|
||||
const index = selection.value.findIndex(item => item.id === record.id)
|
||||
if (index > -1) {
|
||||
selection.value.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchForm.keyword = ''
|
||||
selection.value = []
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 新增部门
|
||||
const handleAdd = () => {
|
||||
@@ -196,7 +135,7 @@ const handleDelete = async (record) => {
|
||||
const res = await authApi.department.delete.post({ id: record.id })
|
||||
if (res.code === 1) {
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
refreshTable()
|
||||
} else {
|
||||
message.error(res.message || '删除失败')
|
||||
}
|
||||
@@ -208,25 +147,25 @@ const handleDelete = async (record) => {
|
||||
|
||||
// 批量删除
|
||||
const handleBatchDelete = () => {
|
||||
if (selection.value.length === 0) {
|
||||
if (selectedRows.value.length === 0) {
|
||||
message.warning('请选择要删除的部门')
|
||||
return
|
||||
}
|
||||
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: `确定删除选中的 ${selection.value.length} 个部门吗?如果删除项中含有子集将会被一并删除`,
|
||||
content: `确定删除选中的 ${selectedRows.value.length} 个部门吗?如果删除项中含有子集将会被一并删除`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
okType: 'danger',
|
||||
onOk: async () => {
|
||||
try {
|
||||
const ids = selection.value.map(item => item.id)
|
||||
const ids = selectedRows.value.map(item => item.id)
|
||||
const res = await authApi.department.delete.post({ ids })
|
||||
if (res.code === 1) {
|
||||
message.success('删除成功')
|
||||
selection.value = []
|
||||
loadData()
|
||||
selectedRows.value = []
|
||||
refreshTable()
|
||||
} else {
|
||||
message.error(res.message || '删除失败')
|
||||
}
|
||||
@@ -238,32 +177,14 @@ const handleBatchDelete = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 根据ID获取树节点
|
||||
const filterTree = (id) => {
|
||||
let target = null
|
||||
function filter(tree) {
|
||||
for (const item of tree) {
|
||||
if (item.id === id) {
|
||||
target = item
|
||||
return
|
||||
}
|
||||
if (item.children) {
|
||||
filter(item.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
filter(tableData.value)
|
||||
return target
|
||||
}
|
||||
|
||||
// 保存成功回调
|
||||
const handleSaveSuccess = (data, mode) => {
|
||||
loadData()
|
||||
const handleSaveSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
refreshTable()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
<a-button type="primary" @click="handleAdd">
|
||||
<template #icon><plus-outlined /></template>
|
||||
</a-button>
|
||||
<a-button danger :disabled="selection.length === 0" @click="handleBatchDelete">
|
||||
<a-button danger :disabled="selectedRows.length === 0" @click="handleBatchDelete">
|
||||
<template #icon><delete-outlined /></template>
|
||||
</a-button>
|
||||
<a-button :disabled="selection.length !== 1" @click="handlePermission">
|
||||
<a-button :disabled="selectedRows.length !== 1" @click="handlePermission">
|
||||
<template #icon><key-outlined /></template>
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-content">
|
||||
<scTable ref="tableRef" :columns="columns" :data-source="tableData" :loading="loading"
|
||||
:pagination="pagination" :row-key="rowKey" :row-selection="rowSelection" @refresh="loadData"
|
||||
:pagination="pagination" :row-key="rowKey" :row-selection="rowSelection" @refresh="refreshTable"
|
||||
@paginationChange="handlePaginationChange" @select="handleSelectChange" @selectAll="handleSelectAll">
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="record.status === 1 ? 'success' : 'error'">
|
||||
@@ -62,19 +62,42 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import scTable from '@/components/scTable/index.vue'
|
||||
import saveDialog from './save.vue'
|
||||
import permissionDialog from './permission.vue'
|
||||
import authApi from '@/api/auth'
|
||||
import { useTable } from '@/hooks/useTable'
|
||||
|
||||
defineOptions({
|
||||
name: 'authRole'
|
||||
})
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref(null)
|
||||
// 使用useTable hooks
|
||||
const {
|
||||
tableRef,
|
||||
searchForm,
|
||||
tableData,
|
||||
loading,
|
||||
pagination,
|
||||
selectedRows,
|
||||
rowSelection,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
handlePaginationChange,
|
||||
handleSelectChange,
|
||||
handleSelectAll,
|
||||
refreshTable
|
||||
} = useTable({
|
||||
api: authApi.role.list.get,
|
||||
searchForm: {
|
||||
keyword: ''
|
||||
},
|
||||
columns: [],
|
||||
needPagination: true,
|
||||
needSelection: true
|
||||
})
|
||||
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
@@ -86,39 +109,9 @@ const dialog = reactive({
|
||||
const saveDialogRef = ref(null)
|
||||
const permissionDialogRef = ref(null)
|
||||
|
||||
// 选中的行
|
||||
const selection = ref([])
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
keyword: ''
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
pageSizeOptions: ['20', '50', '100', '200']
|
||||
})
|
||||
|
||||
// 行key
|
||||
const rowKey = 'id'
|
||||
|
||||
// 行选择配置
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selection.value.map(item => item.id),
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
selection.value = selectedRows
|
||||
}
|
||||
}))
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: 'ID', dataIndex: 'id', key: 'id', width: 80, align: 'center' },
|
||||
@@ -129,80 +122,6 @@ const columns = [
|
||||
{ title: '操作', dataIndex: 'action', key: 'action', width: 200, align: 'center', slot: 'action', fixed: 'right' }
|
||||
]
|
||||
|
||||
// 分页变化处理
|
||||
const handlePaginationChange = ({ page, pageSize }) => {
|
||||
pagination.current = page
|
||||
pagination.pageSize = pageSize
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 加载角色列表数据
|
||||
const loadData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
page: pagination.current,
|
||||
limit: pagination.pageSize,
|
||||
...searchForm
|
||||
}
|
||||
const res = await authApi.role.list.get(params)
|
||||
if (res.code === 1) {
|
||||
tableData.value = res.data?.data || []
|
||||
pagination.total = res.data?.total || 0
|
||||
} else {
|
||||
message.error(res.message || '加载数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载角色列表失败:', error)
|
||||
message.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 选择变化处理
|
||||
const handleSelectChange = (record, selected, selectedRows) => {
|
||||
if (selected) {
|
||||
selection.value.push(record)
|
||||
} else {
|
||||
const index = selection.value.findIndex(item => item.id === record.id)
|
||||
if (index > -1) {
|
||||
selection.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 全选/取消全选处理
|
||||
const handleSelectAll = (selected, selectedRows, changeRows) => {
|
||||
if (selected) {
|
||||
changeRows.forEach(record => {
|
||||
if (!selection.value.find(item => item.id === record.id)) {
|
||||
selection.value.push(record)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
changeRows.forEach(record => {
|
||||
const index = selection.value.findIndex(item => item.id === record.id)
|
||||
if (index > -1) {
|
||||
selection.value.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchForm.keyword = ''
|
||||
selection.value = []
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 新增角色
|
||||
const handleAdd = () => {
|
||||
@@ -234,7 +153,7 @@ const handleDelete = async (record) => {
|
||||
const res = await authApi.role.delete.post({ id: record.id })
|
||||
if (res.code === 1) {
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
refreshTable()
|
||||
} else {
|
||||
message.error(res.message || '删除失败')
|
||||
}
|
||||
@@ -246,25 +165,25 @@ const handleDelete = async (record) => {
|
||||
|
||||
// 批量删除
|
||||
const handleBatchDelete = () => {
|
||||
if (selection.value.length === 0) {
|
||||
if (selectedRows.value.length === 0) {
|
||||
message.warning('请选择要删除的角色')
|
||||
return
|
||||
}
|
||||
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: `确定删除选中的 ${selection.value.length} 个角色吗?`,
|
||||
content: `确定删除选中的 ${selectedRows.value.length} 个角色吗?`,
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
okType: 'danger',
|
||||
onOk: async () => {
|
||||
try {
|
||||
const ids = selection.value.map(item => item.id)
|
||||
const ids = selectedRows.value.map(item => item.id)
|
||||
const res = await authApi.role.delete.post({ ids })
|
||||
if (res.code === 1) {
|
||||
message.success('删除成功')
|
||||
selection.value = []
|
||||
loadData()
|
||||
selectedRows.value = []
|
||||
refreshTable()
|
||||
} else {
|
||||
message.error(res.message || '删除失败')
|
||||
}
|
||||
@@ -278,34 +197,25 @@ const handleBatchDelete = () => {
|
||||
|
||||
// 权限设置
|
||||
const handlePermission = () => {
|
||||
if (selection.value.length !== 1) {
|
||||
if (selectedRows.value.length !== 1) {
|
||||
message.error('请选择一个角色进行权限设置')
|
||||
return
|
||||
}
|
||||
dialog.permission = true
|
||||
setTimeout(() => {
|
||||
permissionDialogRef.value?.open().setData(selection.value[0])
|
||||
permissionDialogRef.value?.open().setData(selectedRows.value[0])
|
||||
}, 0)
|
||||
}
|
||||
|
||||
// 保存成功回调
|
||||
const handleSaveSuccess = (data, mode) => {
|
||||
if (mode === 'add') {
|
||||
loadData()
|
||||
} else if (mode === 'edit') {
|
||||
loadData()
|
||||
}
|
||||
const handleSaveSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 权限设置成功回调
|
||||
const permissionSuccess = () => {
|
||||
loadData()
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
<a-button type="primary" @click="handleSearch">
|
||||
<template #icon><search-outlined /></template>
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
<template #icon><redo-outlined /></template>
|
||||
</a-button>
|
||||
<a-button @click="handleUserReset">
|
||||
<template #icon><redo-outlined /></template>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -52,9 +52,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-content">
|
||||
<scTable ref="tableRef" :columns="columns" :data-source="tableData" :loading="loading"
|
||||
:pagination="pagination" :row-key="rowKey" @refresh="loadData"
|
||||
@paginationChange="handlePaginationChange">
|
||||
<scTable ref="tableRef" :columns="columns" :data-source="tableData" :loading="loading"
|
||||
:pagination="pagination" :row-key="rowKey" @refresh="refreshTable"
|
||||
@paginationChange="handlePaginationChange">
|
||||
<template #avatar="{ record }">
|
||||
<a-avatar :src="record.avatar" :size="32">
|
||||
<template #icon><user-outlined /></template>
|
||||
@@ -102,13 +102,33 @@ import scTable from '@/components/scTable/index.vue'
|
||||
import saveDialog from './save.vue'
|
||||
import roleDialog from './role.vue'
|
||||
import authApi from '@/api/auth'
|
||||
import { useTable } from '@/hooks/useTable'
|
||||
|
||||
defineOptions({
|
||||
name: 'authUser'
|
||||
})
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref(null)
|
||||
// 使用useTable hooks
|
||||
const {
|
||||
tableRef,
|
||||
searchForm,
|
||||
tableData,
|
||||
loading,
|
||||
pagination,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
handlePaginationChange,
|
||||
refreshTable
|
||||
} = useTable({
|
||||
api: authApi.users.list.get,
|
||||
searchForm: {
|
||||
username: '',
|
||||
nickname: '',
|
||||
department_id: null
|
||||
},
|
||||
columns: [],
|
||||
needPagination: true
|
||||
})
|
||||
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
@@ -126,37 +146,9 @@ const filteredDepartmentTree = ref([])
|
||||
const selectedDeptKeys = ref([])
|
||||
const departmentKeyword = ref('')
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
username: '',
|
||||
nickname: '',
|
||||
department_id: null
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
pageSizeOptions: ['20', '50', '100', '200']
|
||||
})
|
||||
|
||||
// 行key
|
||||
const rowKey = 'id'
|
||||
|
||||
// 分页变化处理
|
||||
const handlePaginationChange = ({ page, pageSize }) => {
|
||||
pagination.current = page
|
||||
pagination.pageSize = pageSize
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: '头像', dataIndex: 'avatar', key: 'avatar', width: 80, align: 'center', slot: 'avatar' },
|
||||
@@ -210,34 +202,15 @@ const handleDeptSearch = (e) => {
|
||||
filteredDepartmentTree.value = filterTree(departmentTree.value)
|
||||
}
|
||||
|
||||
// 加载用户列表数据
|
||||
const loadData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
page: pagination.current,
|
||||
limit: pagination.pageSize,
|
||||
...searchForm
|
||||
}
|
||||
const res = await authApi.users.list.get(params)
|
||||
if (res.code === 1) {
|
||||
tableData.value = res.data?.data || []
|
||||
pagination.total = res.data?.total || 0
|
||||
} else {
|
||||
message.error(res.message || '加载数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载用户列表失败:', error)
|
||||
message.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 表格变化处理(排序、筛选)
|
||||
const handleTableChange = (pagination, filters, sorter) => {
|
||||
// 如果需要处理排序或筛选,可以在这里添加逻辑
|
||||
console.log('表格变化:', { pagination, filters, sorter })
|
||||
// 重置 - 覆盖useTable的handleReset以添加额外逻辑
|
||||
const handleUserReset = () => {
|
||||
searchForm.username = ''
|
||||
searchForm.nickname = ''
|
||||
searchForm.department_id = null
|
||||
selectedDeptKeys.value = []
|
||||
departmentKeyword.value = ''
|
||||
filteredDepartmentTree.value = departmentTree.value
|
||||
handleReset()
|
||||
}
|
||||
|
||||
// 部门选择事件
|
||||
@@ -247,31 +220,7 @@ const onDeptSelect = (selectedKeys) => {
|
||||
} else {
|
||||
searchForm.department_id = null
|
||||
}
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchForm.username = ''
|
||||
searchForm.nickname = ''
|
||||
searchForm.department_id = null
|
||||
selectedDeptKeys.value = []
|
||||
departmentKeyword.value = ''
|
||||
filteredDepartmentTree.value = departmentTree.value
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 刷新表格
|
||||
const refreshTable = () => {
|
||||
loadData()
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
// 导出数据
|
||||
@@ -320,7 +269,7 @@ const handleDelete = async (record) => {
|
||||
const res = await authApi.users.delete.post({ id: record.id })
|
||||
if (res.code === 1) {
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
refreshTable()
|
||||
} else {
|
||||
message.error(res.message || '删除失败')
|
||||
}
|
||||
@@ -331,23 +280,18 @@ const handleDelete = async (record) => {
|
||||
}
|
||||
|
||||
// 保存成功回调
|
||||
const handleSaveSuccess = (data, mode) => {
|
||||
if (mode === 'add') {
|
||||
loadData()
|
||||
} else if (mode === 'edit') {
|
||||
loadData()
|
||||
}
|
||||
const handleSaveSuccess = () => {
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 角色设置成功回调
|
||||
const handleRoleSuccess = () => {
|
||||
loadData()
|
||||
refreshTable()
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadDepartmentTree()
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<a-button type="primary" @click="handleSearch">
|
||||
<template #icon><search-outlined /></template>
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
<a-button @click="handleLogReset">
|
||||
<template #icon><redo-outlined /></template>
|
||||
</a-button>
|
||||
</a-space>
|
||||
@@ -44,7 +44,7 @@
|
||||
</div>
|
||||
<div class="table-content">
|
||||
<scTable ref="tableRef" :columns="columns" :data-source="tableData" :loading="loading"
|
||||
:pagination="pagination" :row-key="rowKey" @refresh="loadData" @paginationChange="handlePaginationChange"
|
||||
:pagination="pagination" :row-key="rowKey" @refresh="refreshTable" @paginationChange="handlePaginationChange"
|
||||
:row-selection="rowSelection">
|
||||
<template #method="{ record }">
|
||||
<a-tag :color="getMethodColor(record.method)">{{ record.method }}</a-tag>
|
||||
@@ -67,19 +67,44 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import { SearchOutlined, RedoOutlined, DeleteOutlined, FolderOutlined, FileOutlined } from '@ant-design/icons-vue'
|
||||
import scTable from '@/components/scTable/index.vue'
|
||||
import logInfoDialog from './info.vue'
|
||||
import systemApi from '@/api/system'
|
||||
import { useTable } from '@/hooks/useTable'
|
||||
|
||||
defineOptions({
|
||||
name: 'systemLog'
|
||||
})
|
||||
|
||||
// 表格引用
|
||||
const tableRef = ref(null)
|
||||
// 使用useTable hooks
|
||||
const {
|
||||
tableRef,
|
||||
searchForm,
|
||||
tableData,
|
||||
loading,
|
||||
pagination,
|
||||
selectedRowKeys,
|
||||
rowSelection,
|
||||
handleSearch,
|
||||
handleReset,
|
||||
handlePaginationChange,
|
||||
refreshTable
|
||||
} = useTable({
|
||||
api: systemApi.log.list.get,
|
||||
searchForm: {
|
||||
title: '',
|
||||
method: null,
|
||||
status: null,
|
||||
created_at: []
|
||||
},
|
||||
columns: [],
|
||||
needPagination: true,
|
||||
needSelection: true,
|
||||
immediateLoad: false
|
||||
})
|
||||
|
||||
// 对话框状态
|
||||
const dialog = reactive({
|
||||
@@ -89,6 +114,7 @@ const dialog = reactive({
|
||||
// 弹窗引用
|
||||
const infoDialogRef = ref(null)
|
||||
|
||||
|
||||
// 树数据
|
||||
const treeData = ref([
|
||||
{
|
||||
@@ -116,39 +142,6 @@ const treeData = ref([
|
||||
// 选中的树节点
|
||||
const selectedKeys = ref([])
|
||||
|
||||
// 选中的行
|
||||
const selectedRowKeys = ref([])
|
||||
|
||||
// 行选择配置
|
||||
const rowSelection = computed(() => ({
|
||||
selectedRowKeys: selectedRowKeys.value,
|
||||
onChange: (selectedKeys) => {
|
||||
selectedRowKeys.value = selectedKeys
|
||||
},
|
||||
}))
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
title: '',
|
||||
method: null,
|
||||
status: null,
|
||||
created_at: []
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条`,
|
||||
pageSizeOptions: ['20', '50', '100', '200']
|
||||
})
|
||||
|
||||
// 行key
|
||||
const rowKey = 'id'
|
||||
|
||||
@@ -175,40 +168,6 @@ const columns = [
|
||||
{ title: '操作', dataIndex: 'action', key: 'action', width: 150, align: 'center', slot: 'action', fixed: 'right' }
|
||||
]
|
||||
|
||||
// 加载日志列表数据
|
||||
const loadData = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
page: pagination.current,
|
||||
limit: pagination.pageSize,
|
||||
title: searchForm.title,
|
||||
method: searchForm.method,
|
||||
status: searchForm.status,
|
||||
created_at: searchForm.created_at
|
||||
}
|
||||
|
||||
const res = await systemApi.log.list.get(params)
|
||||
if (res.code === 1) {
|
||||
tableData.value = res.data?.data || []
|
||||
pagination.total = res.data?.total || 0
|
||||
} else {
|
||||
message.error(res.message || '加载数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载日志列表失败:', error)
|
||||
message.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 分页变化处理
|
||||
const handlePaginationChange = ({ page, pageSize }) => {
|
||||
pagination.current = page
|
||||
pagination.pageSize = pageSize
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 树节点选择事件
|
||||
const onSelect = (selectedKeys, info) => {
|
||||
@@ -230,27 +189,10 @@ const onSelect = (selectedKeys, info) => {
|
||||
searchForm.status = null
|
||||
}
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
refreshTable()
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
searchForm.title = ''
|
||||
searchForm.method = null
|
||||
searchForm.status = null
|
||||
searchForm.timeRange = []
|
||||
selectedKeys.value = []
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
// 查看日志详情
|
||||
const handleView = (record) => {
|
||||
dialog.info = true
|
||||
@@ -265,7 +207,7 @@ const handleDelete = async (record) => {
|
||||
const res = await systemApi.log.delete.post({ id: record.id })
|
||||
if (res.code === 1) {
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
refreshTable()
|
||||
selectedRowKeys.value = []
|
||||
} else {
|
||||
message.error(res.message || '删除失败')
|
||||
@@ -295,7 +237,7 @@ const handleClearLog = () => {
|
||||
await Promise.all(promises)
|
||||
message.success('清空成功')
|
||||
selectedRowKeys.value = []
|
||||
loadData()
|
||||
refreshTable()
|
||||
} catch (error) {
|
||||
console.error('清空日志失败:', error)
|
||||
message.error('清空失败')
|
||||
@@ -306,7 +248,7 @@ const handleClearLog = () => {
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
refreshTable()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ function transformMenusToRoutes(menus) {
|
||||
icon: menu.meta?.icon || menu.icon,
|
||||
hidden: menu.hidden || menu.meta?.hidden,
|
||||
keepAlive: menu.meta?.keepAlive || false,
|
||||
affix: menu.meta?.affix || 0,
|
||||
role: menu.meta?.role || []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ export const useLayoutStore = defineStore(
|
||||
// 视图标签页(用于记录页面滚动位置)
|
||||
const viewTags = ref([])
|
||||
|
||||
// 刷新标签的 key,用于触发组件刷新
|
||||
const refreshKey = ref(0)
|
||||
|
||||
// 切换侧边栏折叠
|
||||
const toggleSidebar = () => {
|
||||
sidebarCollapsed.value = !sidebarCollapsed.value
|
||||
@@ -81,6 +84,11 @@ export const useLayoutStore = defineStore(
|
||||
showBreadcrumb.value = show
|
||||
}
|
||||
|
||||
// 刷新标签
|
||||
const refreshTag = () => {
|
||||
refreshKey.value++
|
||||
}
|
||||
|
||||
// 重置主题设置
|
||||
const resetTheme = () => {
|
||||
themeColor.value = '#1890ff'
|
||||
@@ -98,6 +106,7 @@ export const useLayoutStore = defineStore(
|
||||
themeColor,
|
||||
showTags,
|
||||
showBreadcrumb,
|
||||
refreshKey,
|
||||
toggleSidebar,
|
||||
setLayoutMode,
|
||||
setSelectedParentMenu,
|
||||
@@ -108,13 +117,14 @@ export const useLayoutStore = defineStore(
|
||||
setShowTags,
|
||||
setShowBreadcrumb,
|
||||
resetTheme,
|
||||
refreshTag,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: 'layout-store',
|
||||
storage: customStorage,
|
||||
pick: ['layoutMode', 'sidebarCollapsed', 'themeColor', 'showTags', 'showBreadcrumb'],
|
||||
pick: ['layoutMode', 'sidebarCollapsed', 'themeColor', 'showTags', 'showBreadcrumb', 'viewTags'],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1048,6 +1048,11 @@
|
||||
resolved "https://mirrors.huaweicloud.com/repository/npm/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31"
|
||||
integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
|
||||
|
||||
"@element-plus/icons-vue@^2.3.2":
|
||||
version "2.3.2"
|
||||
resolved "https://mirrors.huaweicloud.com/repository/npm/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz#7e9cb231fb738b2056f33e22c3a29e214b538dcf"
|
||||
integrity sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==
|
||||
|
||||
"@emotion/hash@^0.9.0":
|
||||
version "0.9.2"
|
||||
resolved "https://mirrors.huaweicloud.com/repository/npm/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b"
|
||||
|
||||
Reference in New Issue
Block a user