启用正式接口

This commit is contained in:
余菲 2022-05-23 10:52:21 +08:00
parent 27310d0324
commit 1340da6853
20 changed files with 410 additions and 145 deletions

View File

@ -5,7 +5,7 @@ VITE_PUBLIC_PATH = '/'
VITE_APP_USE_MOCK = false VITE_APP_USE_MOCK = false
# proxy # proxy
VITE_PROXY = [["/api-dev","http://127.0.0.1:8002/api"]] VITE_PROXY = [["/api-dev","http://192.168.11.11:9070/api"]]
# base api # base api
VITE_APP_GLOB_BASE_API = '/api-dev' VITE_APP_GLOB_BASE_API = '/api-dev'

View File

@ -2,7 +2,7 @@
VITE_PUBLIC_PATH = '/' VITE_PUBLIC_PATH = '/'
# 是否启用MOCK # 是否启用MOCK
VITE_APP_USE_MOCK = true VITE_APP_USE_MOCK = false
# proxy # proxy
VITE_PROXY = [["/api-local","http://127.0.0.1:8002/api"],["/api-mock","http://127.0.0.1:8003"]] VITE_PROXY = [["/api-local","http://127.0.0.1:8002/api"],["/api-mock","http://127.0.0.1:8003"]]

View File

@ -174,12 +174,14 @@ export default [
timeout: 1000, timeout: 1000,
method: 'get', method: 'get',
response: config => { response: config => {
// const { page = 1, limit = 10 } = config.query const { page = 1, limit = 10 } = config.query
// const mockList = deptList.filter(item => { const data = {
// return true list: deptList,
// }) page: Number(page),
// const List = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1)) limit: Number(limit),
return deptList total: 5
}
return resultSuccess(data)
} }
} }
] ]

11
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@vicons/antd": "^0.10.0", "@vicons/antd": "^0.10.0",
"@vicons/ionicons5": "^0.10.0", "@vicons/ionicons5": "^0.10.0",
"axios": "^0.26.1", "axios": "^0.26.1",
"dayjs": "^1.11.2",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"pinia": "^2.0.13", "pinia": "^2.0.13",
"vue": "^3.2.16", "vue": "^3.2.16",
@ -3533,6 +3534,11 @@
"date-fns": ">=2.0.0" "date-fns": ">=2.0.0"
} }
}, },
"node_modules/dayjs": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz",
"integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw=="
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -14042,6 +14048,11 @@
"dev": true, "dev": true,
"requires": {} "requires": {}
}, },
"dayjs": {
"version": "1.11.2",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.2.tgz",
"integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw=="
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",

View File

@ -12,7 +12,7 @@
"@vicons/antd": "^0.10.0", "@vicons/antd": "^0.10.0",
"@vicons/ionicons5": "^0.10.0", "@vicons/ionicons5": "^0.10.0",
"axios": "^0.26.1", "axios": "^0.26.1",
"dayjs": "^1.11.0", "dayjs": "^1.11.2",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"pinia": "^2.0.13", "pinia": "^2.0.13",
"vue": "^3.2.16", "vue": "^3.2.16",

View File

@ -4,13 +4,13 @@ export const login = (data) => {
return request({ return request({
url: '/auth/login', url: '/auth/login',
method: 'post', method: 'post',
data, data
}) })
} }
export const refreshToken = () => { export const refreshToken = () => {
return request({ return request({
url: '/auth/refreshToken', url: '/auth/refreshToken',
method: 'post', method: 'post'
}) })
} }

View File

@ -1,5 +1,10 @@
import { mockAxios as request } from '@/utils/http' import { defAxios as request } from '@/utils/http'
/**
* 登录接口
* @param {Object} 用户名以及密码
* @returns 返回token信息
*/
export function userLogin(data = {}) { export function userLogin(data = {}) {
return request({ return request({
url: '/login/login', url: '/login/login',
@ -7,9 +12,25 @@ export function userLogin(data = {}) {
data data
}) })
} }
/**
* 获取验证码
* @returns 验证码图片
*/
export function userCaptcha() { export function userCaptcha() {
return request({ return request({
url: '/login/captcha', url: '/login/captcha',
method: 'get' method: 'get'
}) })
} }
/**
* 退出登录
* @returns
*/
export function loginOut() {
return request({
url: '/login/logout',
method: 'GET'
})
}

View File

@ -1,39 +0,0 @@
import { defAxios as request } from '@/utils/http'
export function getPosts(data = {}) {
return request({
url: '/posts',
method: 'get',
data,
})
}
export function getPostById({ id }) {
return request({
url: `/post/${id}`,
method: 'get',
})
}
export function savePost(id, data = {}) {
if (id) {
return request({
url: `/post/${id}`,
method: 'put',
data,
})
}
return request({
url: '/post',
method: 'post',
data,
})
}
export function deletePost(id) {
return request({
url: `/post/${id}`,
method: 'delete',
})
}

View File

@ -1,4 +1,4 @@
import { mockAxios as request } from '@/utils/http' import { defAxios as request } from '@/utils/http'
/** /**
* 获取部门分页数据接口 * 获取部门分页数据接口
* @returns 部门分页 * @returns 部门分页

View File

@ -1,4 +1,4 @@
import { mockAxios as request } from '@/utils/http' import { defAxios as request } from '@/utils/http'
export function getMenu() { export function getMenu() {
return request({ return request({

View File

@ -0,0 +1,59 @@
import { defAxios as request } from '@/utils/http'
/**
* 获取菜单分页数据接口
* @returns 菜单分页数据
*/
export function getMenuList(params) {
return request({
url: '/menu/index',
method: 'GET',
params
})
}
/**
* 获取菜单全部数据接口
* @returns 菜单全部数据
*/
export function getMenu(params) {
return request({
url: '/menu/getMenuAll',
method: 'GET',
params
})
}
/**
* 添加菜单
* params
*/
export function addMenu(data) {
return request({
url: '/menu/add',
method: 'POST',
data
})
}
/**
* 编辑菜单
* params
*/
export function editMenu(data) {
return request({
url: '/menu/edit',
method: 'PUT',
data
})
}
/**
* 删除菜单
* params
*/
export function deleteMenu(id) {
return request({
url: `/menu/delete${[id]}`,
method: 'DELETE'
})
}

View File

@ -0,0 +1,95 @@
import { defAxios as request } from '@/utils/http'
/**
* 获取角色分页数据接口
* @returns 角色分页数据
*/
export function getRoleList(params) {
return request({
url: '/role/index',
method: 'GET',
params
})
}
/**
* 获取角色全部数据接口
* @returns 角色全部数据
*/
export function getRoleAll(params) {
return request({
url: '/role/getRoleList',
method: 'GET',
params
})
}
/**
* 添加角色
* params
*/
export function addRole(data) {
return request({
url: '/role/add',
method: 'POST',
data
})
}
/**
* 编辑角色
* params
*/
export function editRole(data) {
return request({
url: '/role/edit',
method: 'PUT',
data
})
}
/**
* 设置角色状态
* params
*/
export function setRoleStatus(data) {
return request({
url: '/role/status',
method: 'PUT',
data
})
}
/**
* 删除角色
* params
*/
export function deleteRole(id) {
return request({
url: `/role/delete${[id]}`,
method: 'DELETE'
})
}
/**
* 获取角色权限数据
* @param 角色id
* @returns 角色全部权限数据
*/
export function getRolePermission(id) {
return request({
url: `/role/getPermissionList/${id}`,
method: 'GET'
})
}
/**
* 保存角色权限信息
* params
*/
export function savePermission(data) {
return request({
url: '/role/savePermission',
method: 'POST',
data
})
}

View File

@ -1,4 +1,4 @@
import { mockAxios as request } from '@/utils/http' import { defAxios as request } from '@/utils/http'
/** /**
* 获取用户分页数据接口 * 获取用户分页数据接口
* @returns 用户分页 * @returns 用户分页
@ -57,3 +57,15 @@ export function setUserStatus(data) {
data data
}) })
} }
/**
* 重置用户密码
* params
*/
export function resetPassword(data) {
return request({
url: '/user/resetPwd',
method: 'PUT',
data
})
}

View File

@ -4,7 +4,7 @@ export function getUsers(data = {}) {
return request({ return request({
url: '/users', url: '/users',
method: 'get', method: 'get',
data, data
}) })
} }
@ -12,12 +12,12 @@ export function getUser(id) {
if (id) { if (id) {
return request({ return request({
url: `/user/${id}`, url: `/user/${id}`,
method: 'get', method: 'get'
}) })
} }
return request({ return request({
url: '/user', url: '/user',
method: 'get', method: 'get'
}) })
} }
@ -26,13 +26,13 @@ export function saveUser(data = {}, id) {
return request({ return request({
url: '/user', url: '/user',
method: 'put', method: 'put',
data, data
}) })
} }
return request({ return request({
url: `/user/${id}`, url: `/user/${id}`,
method: 'put', method: 'put',
data, data
}) })
} }

View File

@ -0,0 +1,69 @@
/**
* 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
}

View File

@ -1,5 +1,6 @@
import { ref, unref, computed, onMounted } from 'vue' import { ref, unref, computed, onMounted } from 'vue'
import { isBoolean } from '@/utils/is' import { isBoolean } from '@/utils/is'
import { toTreeData } from './toTree'
export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) { export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) {
const dataSourceRef = ref([]) const dataSourceRef = ref([])
@ -42,6 +43,7 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
fetch(opt) fetch(opt)
} }
} }
// 处理数据结构
const resultInfo = res[listField] ? res[listField] : [] const resultInfo = res[listField] ? res[listField] : []
dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo) : resultInfo dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo) : resultInfo
setPagination({ setPagination({
@ -67,8 +69,12 @@ export function useDataSource(propsRef, { getPaginationInfo, setPagination, setL
} }
} }
function dealTree() { /**
const tree = [] * 递归遍历数据处理成树形结构
* @returns 返回树形结构数据
*/
function dealTree(info) {
const tree = toTreeData(info.data, 'id', 'pid', 'children')
return tree return tree
} }

View File

@ -1,5 +1,5 @@
import { router } from '@/router' import { router } from '@/router'
import { getToken } from '@/utils/token' import { getToken, removeToken } from '@/utils/token'
import { isWithoutToken } from './help' import { isWithoutToken } from './help'
export function setupInterceptor(service) { export function setupInterceptor(service) {
@ -21,7 +21,7 @@ export function setupInterceptor(service) {
* * jwt token * * jwt token
* ! 认证方案: Bearer * ! 认证方案: Bearer
*/ */
config.headers.Authorization = 'Bearer ' + token config.headers.Authorization = token
return config return config
} }
@ -43,40 +43,40 @@ export function setupInterceptor(service) {
(response) => response?.data, (response) => response?.data,
(error) => { (error) => {
const { code, message } = error.response?.data const { code, message } = error.response?.data
return Promise.reject({ code, message }) // return Promise.reject({ code, message })
/** /**
* TODO 此处可以根据后端返回的错误码自定义框架层面的错误处理 * TODO 此处可以根据后端返回的错误码自定义框架层面的错误处理
*/ */
// switch (code) { // const { currentRoute } = router
// case 401: switch (code) {
// // 未登录可能是token过期或者无效了 case 401:
// console.error(message) // 未登录可能是token过期或者无效了
// removeToken() console.error(message)
// const { currentRoute } = router removeToken()
// router.replace({ router.replace({
// path: '/login', path: '/login'
// query: { ...currentRoute.query, redirect: currentRoute.path } // query: { ...currentRoute.query, redirect: currentRoute.path }
// }) })
// break break
// case 403: case 403:
// // 没有权限 // 没有权限
// console.error(message) console.error(message)
// break break
// case 404: case 404:
// // 资源不存在 // 资源不存在
// console.error(message) console.error(message)
// break break
// default: default:
// break break
// } }
// // 已知错误resolve在业务代码中作提醒未知错误reject捕获错误统一提示接口异常9000以上为业务类型错误需要跟后端确定好 // 已知错误resolve在业务代码中作提醒未知错误reject捕获错误统一提示接口异常9000以上为业务类型错误需要跟后端确定好
// if ([401, 403, 404].includes(code) || code >= 9000) { if ([401, 403, 404].includes(code) || code >= 9000) {
// return Promise.resolve({ code, message }) return Promise.resolve({ code, message })
// } else { } else {
// console.error('【err】' + error) console.error('【err】' + error)
// return Promise.reject({ message: '接口异常,请稍后重试!' }) return Promise.reject({ message: '接口异常,请稍后重试!' })
// } }
} }
) )
} }

View File

@ -1,16 +1,22 @@
<template> <template>
<div> <div>
<data-table :columns="data.columns" :data="data.data" :pagination="data.pagination" size="large" scroll-x="1200"> <n-card>
<template #tableTitle> <data-table
<n-button type="primary"> :columns="data.columns"
新建 :data="data.data"
</n-button> :pagination="data.pagination"
<n-button type="primary"> :request="loadDataTable"
删除 :row-key="(row) => row.id"
</n-button> data-type="tree"
</template> size="large"
</data-table> scroll-x="1200"
>
<template #tableTitle>
<n-button type="primary"> 新建 </n-button>
<n-button type="primary"> 删除 </n-button>
</template>
</data-table>
</n-card>
</div> </div>
</template> </template>
@ -18,9 +24,8 @@
import dataTable from '@/components/DataTable/index.vue' import dataTable from '@/components/DataTable/index.vue'
import TableAction from '@/components/DataTable/tools/Action.vue' import TableAction from '@/components/DataTable/tools/Action.vue'
import { getDeptList } from '@/api/system/index.js' import { getDeptList } from '@/api/system/index.js'
import { h, onMounted } from 'vue' import { h, onMounted, unref } from 'vue'
import { reactive } from 'vue' import { reactive } from 'vue'
import { toTreeData } from '@/utils/handleData.js'
export default { export default {
name: 'MenuPage', name: 'MenuPage',
components: { dataTable }, components: { dataTable },
@ -52,7 +57,6 @@ export default {
title: '排序', title: '排序',
key: 'sort', key: 'sort',
align: 'center' align: 'center'
}, },
{ {
title: '备注', title: '备注',
@ -124,24 +128,30 @@ export default {
limit: 10 limit: 10
} }
const res = await getDeptList(params) const res = await getDeptList(params)
const dataList = toTreeData(res.data.map(d => { data.data = res.data
d.index = d.id }
return d const params = reactive({
}), 'id', 'pid') name: 'xiaoMa'
data.data = dataList })
const loadDataTable = async(res) => {
const _params = {
...unref(params),
...res
}
return await getDeptList(_params)
} }
onMounted(() => { onMounted(() => {
fetchList() fetchList()
}) })
return { data } return { data, loadDataTable }
} }
} }
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>
.n-button+.n-button{ .n-button + .n-button {
margin-left: 10px; margin-left: 10px;
} }
</style> </style>

View File

@ -37,7 +37,8 @@ export default {
{ {
title: '用户编号', title: '用户编号',
key: 'code', key: 'code',
align: 'center' align: 'center',
minWidth: 80
}, },
{ {
title: '头像', title: '头像',
@ -51,52 +52,56 @@ export default {
src: row.avatar src: row.avatar
} }
}) })
} },
minWidth: 80
}, },
{ {
title: '用户账号', title: '用户账号',
key: 'username', key: 'username',
align: 'center' align: 'center',
minWidth: 80
}, },
{ {
title: '用户姓名', title: '用户姓名',
key: 'realname', key: 'realname',
align: 'center' align: 'center',
minWidth: 80
}, },
{ {
title: '用户类型', title: '用户类型',
key: 'type', key: 'type',
align: 'center', align: 'center',
width: 100 minWidth: 80
}, },
{ {
title: '角色', title: '角色',
key: 'roles', key: 'roles',
align: 'center' align: 'center',
minWidth: 100
}, },
{ {
title: '状态', title: '状态',
key: 'status', key: 'status',
align: 'center', align: 'center',
width: 100 minWidth: 80
}, },
{ {
title: '部门', title: '部门',
key: 'deptName', key: 'deptName',
align: 'center' align: 'center',
minWidth: 120
}, },
{ {
title: '创建时间', title: '创建时间',
key: 'createTime', key: 'createTime',
align: 'center', align: 'center',
width: 160 minWidth: 160
}, },
{ {
title: '更新时间', title: '更新时间',
key: 'updateTime', key: 'updateTime',
align: 'center', align: 'center',
width: 160 minWidth: 160
}, },
{ {
title: '操作', title: '操作',

View File

@ -1,16 +1,21 @@
<template> <template>
<div> <div>
<data-table :columns="data.columns" :data="data.data" :pagination="data.pagination" size="large" scroll-x="1200"> <n-card>
<template #tableTitle> <data-table
<n-button type="primary"> :columns="data.columns"
新建 :data="data.data"
</n-button> :pagination="data.pagination"
<n-button type="primary"> :row-key="(row) => row.id"
删除 :request="loadDataTable"
</n-button> size="large"
</template> scroll-x="1200"
</data-table> >
<template #tableTitle>
<n-button type="primary"> 新建 </n-button>
<n-button type="primary"> 删除 </n-button>
</template>
</data-table>
</n-card>
</div> </div>
</template> </template>
@ -18,8 +23,8 @@
import dataTable from '@/components/DataTable/index.vue' import dataTable from '@/components/DataTable/index.vue'
import TableAction from '@/components/DataTable/tools/Action.vue' import TableAction from '@/components/DataTable/tools/Action.vue'
import TableImage from '@/components/DataTable/tools/Image.vue' import TableImage from '@/components/DataTable/tools/Image.vue'
import { getUserList } from '@/api/system/index.js' import { getUserList } from '@/api/system/user/index.js'
import { h, onMounted } from 'vue' import { h, onMounted, unref } from 'vue'
import { reactive } from 'vue' import { reactive } from 'vue'
export default { export default {
name: 'MenuPage', name: 'MenuPage',
@ -66,7 +71,6 @@ export default {
title: '角色', title: '角色',
key: 'roles', key: 'roles',
align: 'center' align: 'center'
}, },
{ {
title: '状态', title: '状态',
@ -146,17 +150,27 @@ export default {
data.data = res.data data.data = res.data
} }
const params = reactive({
name: 'xiaoMa'
})
const loadDataTable = async(res) => {
const _params = {
...unref(params),
...res
}
return await getUserList(_params)
}
onMounted(() => { onMounted(() => {
fetchList() fetchList()
}) })
return { data } return { data, loadDataTable }
} }
} }
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>
.n-button+.n-button{ .n-button + .n-button {
margin-left: 10px; margin-left: 10px;
} }
</style> </style>