const menuList = [] | const menuList = [] | ||||
const userList = [] | const userList = [] | ||||
// const deptList = [] | |||||
const count = 100 | const count = 100 | ||||
for (let i = 0; i < count; i++) { | for (let i = 0; i < count; i++) { | ||||
createTime: '@datetime', | createTime: '@datetime', | ||||
updateTime: '@datetime' | updateTime: '@datetime' | ||||
})) | })) | ||||
// deptList.push(Mock.mock({ | |||||
// code: '', | |||||
// id: 1, | |||||
// name: '@name', | |||||
// fullname: '@cname', | |||||
// 'pid|1': [1, 2, 3, 4, 5], | |||||
// 'sort|+1': 0, | |||||
// type: 1, | |||||
// 'note|1-8': '好', | |||||
// createTime: '@datetime', | |||||
// updateTime: '@datetime' | |||||
// })) | |||||
} | } | ||||
const deptList = Mock.mock({ | |||||
code: 0, | |||||
message: '获取成功', | |||||
type: 'success', | |||||
data: [{ | |||||
code: 'XH212313', | |||||
id: 1, | |||||
name: '@name', | |||||
fullname: '@cname', | |||||
pid: 0, | |||||
sort: 0, | |||||
type: 1, | |||||
'note|1-8': '好', | |||||
createTime: '@datetime', | |||||
updateTime: '@datetime' | |||||
}, | |||||
{ | |||||
code: 'XH212312', | |||||
id: 2, | |||||
name: '@name', | |||||
fullname: '@cname', | |||||
pid: 1, | |||||
sort: 0, | |||||
type: 2, | |||||
'note|1-8': '好', | |||||
createTime: '@datetime', | |||||
updateTime: '@datetime' | |||||
}, | |||||
{ | |||||
code: 'XH212323', | |||||
id: 3, | |||||
name: '@name', | |||||
fullname: '@cname', | |||||
pid: 2, | |||||
sort: 0, | |||||
type: 2, | |||||
'note|1-8': '好', | |||||
createTime: '@datetime', | |||||
updateTime: '@datetime' | |||||
}, | |||||
{ | |||||
code: 'XH212319', | |||||
id: 4, | |||||
name: '@name', | |||||
fullname: '@cname', | |||||
pid: 0, | |||||
sort: 1, | |||||
type: 1, | |||||
'note|1-8': '好', | |||||
createTime: '@datetime', | |||||
updateTime: '@datetime' | |||||
}, | |||||
{ | |||||
code: 'XH212398', | |||||
id: 5, | |||||
name: '@name', | |||||
fullname: '@cname', | |||||
pid: 0, | |||||
sort: 2, | |||||
type: 2, | |||||
'note|1-8': '好', | |||||
createTime: '@datetime', | |||||
updateTime: '@datetime' | |||||
}] | |||||
}) | |||||
export default [ | export default [ | ||||
{ | { | ||||
const List = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) | const List = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) | ||||
return resultSuccess(List) | return resultSuccess(List) | ||||
} | } | ||||
}, | |||||
{ | |||||
url: '/api-mock/dept/apiIndex', | |||||
timeout: 1000, | |||||
method: 'get', | |||||
response: config => { | |||||
// const { page = 1, limit = 10 } = config.query | |||||
// const mockList = deptList.filter(item => { | |||||
// return true | |||||
// }) | |||||
// const List = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) | |||||
return deptList | |||||
} | |||||
} | } | ||||
] | ] |
meta: { | meta: { | ||||
title: '角色管理' | title: '角色管理' | ||||
} | } | ||||
}, | |||||
{ | |||||
path: 'dept', | |||||
component: 'views/system/dept/index', | |||||
name: 'SystemDept', | |||||
meta: { | |||||
title: '部门管理' | |||||
} | |||||
} | } | ||||
] | ] | ||||
} | } |
import { mockAxios as request } from '@/utils/http' | |||||
/** | |||||
* 获取部门分页数据接口 | |||||
* @returns 部门分页 | |||||
*/ | |||||
export function getDeptList(params) { | |||||
return request({ | |||||
url: '/dept/index', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* 获取部门全部数据接口 | |||||
* @returns 部门全部数据 | |||||
*/ | |||||
export function getDeptAll(params) { | |||||
return request({ | |||||
url: '/dept/getDeptList', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* 添加部门 | |||||
* params | |||||
*/ | |||||
export function addDept(data) { | |||||
return request({ | |||||
url: '/dept/add', | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* 编辑部门 | |||||
* params | |||||
*/ | |||||
export function editDept(data) { | |||||
return request({ | |||||
url: '/dept/edit', | |||||
method: 'PUT', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* 删除部门 | |||||
* params | |||||
*/ | |||||
export function deleteDept(id) { | |||||
return request({ | |||||
url: `/dept/delete${[id]}`, | |||||
method: 'DELETE' | |||||
}) | |||||
} |
params | params | ||||
}) | }) | ||||
} | } | ||||
export function getDeptList(params) { | |||||
return request({ | |||||
url: '/dept/apiIndex', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} |
import { mockAxios as request } from '@/utils/http' | |||||
/** | |||||
* 获取用户分页数据接口 | |||||
* @returns 用户分页 | |||||
*/ | |||||
export function getUserList(params) { | |||||
return request({ | |||||
url: '/user/index', | |||||
method: 'GET', | |||||
params | |||||
}) | |||||
} | |||||
/** | |||||
* 添加用户 | |||||
* params | |||||
*/ | |||||
export function addUser(data) { | |||||
return request({ | |||||
url: '/user/add', | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* 编辑部门 | |||||
* params | |||||
*/ | |||||
export function editUser(data) { | |||||
return request({ | |||||
url: '/user/edit', | |||||
method: 'PUT', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* 删除用户 | |||||
* params | |||||
*/ | |||||
export function deleteUser(id) { | |||||
return request({ | |||||
url: `/user/delete${[id]}`, | |||||
method: 'DELETE' | |||||
}) | |||||
} | |||||
/** | |||||
* 设置用户状态 | |||||
* params | |||||
*/ | |||||
export function setUserStatus(data) { | |||||
return request({ | |||||
url: '/user/status', | |||||
method: 'PUT', | |||||
data | |||||
}) | |||||
} |
...unref(props) | ...unref(props) | ||||
} | } | ||||
}) | }) | ||||
console.log(getBindProps) | |||||
return { | return { | ||||
getBindProps | getBindProps | ||||
} | } |
/** | |||||
* pid形式数据转children形式 | |||||
* @param data 需要转换的数组 | |||||
* @param idKey id字段名 | |||||
* @param pidKey pid字段名 | |||||
* @param childKey 生成的children字段名 | |||||
* @param pid 顶级的pid | |||||
* @param addPIds 是否添加所有父级id的字段 | |||||
* @param parentsKey 所有父级id的字段名称,默认parentIds | |||||
* @param parentIds 所有父级id | |||||
* @returns {[]} | |||||
*/ | |||||
export function toTreeData(data, idKey, pidKey, childKey, pid, addPIds, parentsKey, parentIds) { | |||||
if (typeof data === 'object' && !Array.isArray(data)) { | |||||
idKey = data.idKey | |||||
pidKey = data.pidKey | |||||
childKey = data.childKey | |||||
pid = data.pid | |||||
addPIds = data.addPIds | |||||
parentsKey = data.parentsKey | |||||
parentIds = data.parentIds | |||||
data = data.data | |||||
} | |||||
if (!childKey) { | |||||
childKey = 'children' | |||||
} | |||||
if (typeof pid === 'undefined') { | |||||
pid = [] | |||||
data.forEach((d) => { | |||||
let flag = true | |||||
for (let i = 0; i < data.length; i++) { | |||||
if (d[pidKey] === data[i][idKey]) { | |||||
flag = false | |||||
break | |||||
} | |||||
} | |||||
if (flag) { | |||||
pid.push(d[pidKey]) | |||||
} | |||||
}) | |||||
} | |||||
const result = [] | |||||
data.forEach((d) => { | |||||
if (d[idKey] === d[pidKey]) { | |||||
console.error('data error: ', d) | |||||
return | |||||
} | |||||
if (Array.isArray(pid) ? (pid.indexOf(d[pidKey]) !== -1) : (d[pidKey] === pid)) { | |||||
const children = toTreeData({ | |||||
data: data, | |||||
idKey: idKey, | |||||
pidKey: pidKey, | |||||
childKey: childKey, | |||||
pid: d[idKey], | |||||
addPIds: addPIds, | |||||
parentsKey: parentsKey, | |||||
parentIds: (parentIds || []).concat([d[idKey]]) | |||||
}) | |||||
if (children.length > 0) { | |||||
d[childKey] = children | |||||
} | |||||
if (addPIds) { | |||||
d[parentsKey || 'parentIds'] = parentIds || [] | |||||
} | |||||
result.push(d) | |||||
} | |||||
}) | |||||
return result | |||||
} | |||||
/** | |||||
* 遍历children形式数据 | |||||
* @param data 需要遍历的数组 | |||||
* @param callback 回调 | |||||
* @param childKey children字段名 | |||||
*/ | |||||
export function eachTreeData(data, callback, childKey = 'children') { | |||||
if (!data || !data.length) { | |||||
return | |||||
} | |||||
data.forEach((d) => { | |||||
if (callback(d) !== false && d[childKey]) { | |||||
eachTreeData(d[childKey], callback, childKey) | |||||
} | |||||
}) | |||||
} | |||||
/** | |||||
* 处理树形数据 | |||||
* @param data 需要处理的数据 | |||||
* @param formatter 处理器 | |||||
* @param childKey children字段名 | |||||
* @returns {[]} 处理后的数据 | |||||
*/ | |||||
export function formatTreeData(data, formatter, childKey = 'children') { | |||||
const result = [] | |||||
if (data && data.length) { | |||||
data.forEach((d) => { | |||||
const item = formatter(d) | |||||
if (item !== false) { | |||||
if (item[childKey]) { | |||||
item[childKey] = formatTreeData(item[childKey], formatter, childKey) | |||||
} | |||||
result.push(item) | |||||
} | |||||
}) | |||||
} | |||||
return result | |||||
} |
import { router } from '@/router' | import { router } from '@/router' | ||||
import { getToken, removeToken } from '@/utils/token' | |||||
import { getToken } from '@/utils/token' | |||||
import { isWithoutToken } from './help' | import { isWithoutToken } from './help' | ||||
export function setupInterceptor(service) { | export function setupInterceptor(service) { | ||||
/** | /** | ||||
* TODO 此处可以根据后端返回的错误码自定义框架层面的错误处理 | * TODO 此处可以根据后端返回的错误码自定义框架层面的错误处理 | ||||
*/ | */ | ||||
switch (code) { | |||||
case 401: | |||||
// 未登录(可能是token过期或者无效了) | |||||
console.error(message) | |||||
removeToken() | |||||
const { currentRoute } = router | |||||
router.replace({ | |||||
path: '/login', | |||||
query: { ...currentRoute.query, redirect: currentRoute.path } | |||||
}) | |||||
break | |||||
case 403: | |||||
// 没有权限 | |||||
console.error(message) | |||||
break | |||||
case 404: | |||||
// 资源不存在 | |||||
console.error(message) | |||||
break | |||||
default: | |||||
break | |||||
} | |||||
// 已知错误resolve,在业务代码中作提醒,未知错误reject,捕获错误统一提示接口异常(9000以上为业务类型错误,需要跟后端确定好) | |||||
if ([401, 403, 404].includes(code) || code >= 9000) { | |||||
return Promise.resolve({ code, message }) | |||||
} else { | |||||
console.error('【err】' + error) | |||||
return Promise.reject({ message: '接口异常,请稍后重试!' }) | |||||
} | |||||
// switch (code) { | |||||
// case 401: | |||||
// // 未登录(可能是token过期或者无效了) | |||||
// console.error(message) | |||||
// removeToken() | |||||
// const { currentRoute } = router | |||||
// router.replace({ | |||||
// path: '/login', | |||||
// query: { ...currentRoute.query, redirect: currentRoute.path } | |||||
// }) | |||||
// break | |||||
// case 403: | |||||
// // 没有权限 | |||||
// console.error(message) | |||||
// break | |||||
// case 404: | |||||
// // 资源不存在 | |||||
// console.error(message) | |||||
// break | |||||
// default: | |||||
// break | |||||
// } | |||||
// // 已知错误resolve,在业务代码中作提醒,未知错误reject,捕获错误统一提示接口异常(9000以上为业务类型错误,需要跟后端确定好) | |||||
// if ([401, 403, 404].includes(code) || code >= 9000) { | |||||
// return Promise.resolve({ code, message }) | |||||
// } else { | |||||
// console.error('【err】' + error) | |||||
// return Promise.reject({ message: '接口异常,请稍后重试!' }) | |||||
// } | |||||
} | } | ||||
) | ) | ||||
} | } |
<template> | |||||
<div> | |||||
<data-table :columns="data.columns" :data="data.data" :pagination="data.pagination" size="large" scroll-x="1200"> | |||||
<template #tableTitle> | |||||
<n-button type="primary"> | |||||
新建 | |||||
</n-button> | |||||
<n-button type="primary"> | |||||
删除 | |||||
</n-button> | |||||
</template> | |||||
</data-table> | |||||
</div> | |||||
</template> | |||||
<script> | |||||
import dataTable from '@/components/DataTable/index.vue' | |||||
import TableAction from '@/components/DataTable/tools/Action.vue' | |||||
import { getDeptList } from '@/api/system/index.js' | |||||
import { h, onMounted } from 'vue' | |||||
import { reactive } from 'vue' | |||||
import { toTreeData } from '@/utils/handleData.js' | |||||
export default { | |||||
name: 'MenuPage', | |||||
components: { dataTable }, | |||||
setup() { | |||||
const data = reactive({ | |||||
columns: [ | |||||
{ | |||||
title: '部门编号', | |||||
key: 'code', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '部门名称', | |||||
key: 'name', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '部门全称', | |||||
key: 'fullname', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '部门类型', | |||||
key: 'type', | |||||
align: 'center', | |||||
width: 100 | |||||
}, | |||||
{ | |||||
title: '排序', | |||||
key: 'sort', | |||||
align: 'center' | |||||
}, | |||||
{ | |||||
title: '备注', | |||||
key: 'note', | |||||
align: 'center', | |||||
width: 100 | |||||
}, | |||||
{ | |||||
title: '创建时间', | |||||
key: 'createTime', | |||||
align: 'center', | |||||
width: 160 | |||||
}, | |||||
{ | |||||
title: '更新时间', | |||||
key: 'updateTime', | |||||
align: 'center', | |||||
width: 160 | |||||
}, | |||||
{ | |||||
title: '操作', | |||||
align: 'center', | |||||
width: 150, | |||||
fixed: 'right', | |||||
render(row) { | |||||
return h(TableAction, { | |||||
actions: [ | |||||
{ | |||||
label: '添加', | |||||
type: 'button', | |||||
props: { | |||||
type: 'primary', | |||||
onClick: play.bind(null, row) | |||||
}, | |||||
auth: 'basic_list' | |||||
}, | |||||
{ | |||||
label: '修改', | |||||
auth: 'basic_list' | |||||
}, | |||||
{ | |||||
label: '删除', | |||||
type: 'popconfirm', | |||||
auth: 'basic_list' | |||||
} | |||||
], | |||||
align: 'center' | |||||
}) | |||||
} | |||||
} | |||||
], | |||||
data: [], | |||||
pagination: { | |||||
pageSize: 10 | |||||
} | |||||
}) | |||||
function play(row) { | |||||
console.log(row) | |||||
} | |||||
/** | |||||
* @description: 获取部门数据并做树形结构处理 | |||||
* @return {*} | |||||
*/ | |||||
async function fetchList() { | |||||
const params = { | |||||
page: 1, | |||||
limit: 10 | |||||
} | |||||
const res = await getDeptList(params) | |||||
const dataList = toTreeData(res.data.map(d => { | |||||
d.index = d.id | |||||
return d | |||||
}), 'id', 'pid') | |||||
data.data = dataList | |||||
} | |||||
onMounted(() => { | |||||
fetchList() | |||||
}) | |||||
return { data } | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang='scss'> | |||||
.n-button+.n-button{ | |||||
margin-left: 10px; | |||||
} | |||||
</style> |