更新
This commit is contained in:
parent
2cba7c7e2a
commit
388eb142a6
2
kinit-admin/.vscode/settings.json
vendored
2
kinit-admin/.vscode/settings.json
vendored
@ -5,7 +5,7 @@
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"[vue]": {
|
||||
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
|
||||
"editor.defaultFormatter": "Vue.volar"
|
||||
},
|
||||
"i18n-ally.localesPaths": ["src/locales"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
|
@ -41,7 +41,7 @@ for (let i = 0; i < count; i++) {
|
||||
export default [
|
||||
// 列表接口
|
||||
{
|
||||
url: '/example/list',
|
||||
url: '/api/example/list',
|
||||
method: 'get',
|
||||
timeout,
|
||||
response: ({ query }) => {
|
||||
|
5
kinit-admin/src/api/vadmin/auth/menu.ts
Normal file
5
kinit-admin/src/api/vadmin/auth/menu.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export const getMenuListApi = (params: any): Promise<IResponse> => {
|
||||
return request.get({ url: '/vadmin/auth/menus/', params })
|
||||
}
|
5
kinit-admin/src/api/vadmin/auth/role.ts
Normal file
5
kinit-admin/src/api/vadmin/auth/role.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export const getRoleListApi = (params: any): Promise<IResponse> => {
|
||||
return request.get({ url: '/vadmin/auth/roles/', params })
|
||||
}
|
@ -10,8 +10,8 @@ import { set } from 'lodash-es'
|
||||
export default defineComponent({
|
||||
name: 'Table',
|
||||
props: {
|
||||
pageSize: propTypes.number.def(10),
|
||||
currentPage: propTypes.number.def(1),
|
||||
limit: propTypes.number.def(10),
|
||||
page: propTypes.number.def(1),
|
||||
// 是否多选
|
||||
selection: propTypes.bool.def(true),
|
||||
// 是否所有的超出隐藏,优先级低于schema中的showOverflowTooltip,
|
||||
@ -47,7 +47,7 @@ export default defineComponent({
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
emits: ['update:pageSize', 'update:currentPage', 'register'],
|
||||
emits: ['update:limit', 'update:page', 'register'],
|
||||
setup(props, { attrs, slots, emit, expose }) {
|
||||
const elTableRef = ref<ComponentRef<typeof ElTable>>()
|
||||
|
||||
@ -57,9 +57,9 @@ export default defineComponent({
|
||||
emit('register', tableRef?.$parent, elTableRef)
|
||||
})
|
||||
|
||||
const pageSizeRef = ref(props.pageSize)
|
||||
const limitRef = ref(props.limit)
|
||||
|
||||
const currentPageRef = ref(props.currentPage)
|
||||
const pageRef = ref(props.page)
|
||||
|
||||
// useTable传入的props
|
||||
const outsideProps = ref<TableProps>({})
|
||||
@ -110,7 +110,7 @@ export default defineComponent({
|
||||
background: false,
|
||||
pagerCount: 7,
|
||||
layout: 'sizes, prev, pager, next, jumper, ->, total',
|
||||
pageSizes: [10, 20, 30, 40, 50, 100],
|
||||
limits: [10, 20, 30, 40, 50, 100],
|
||||
disabled: false,
|
||||
hideOnSinglePage: false,
|
||||
total: 10
|
||||
@ -120,30 +120,30 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
watch(
|
||||
() => unref(getProps).pageSize,
|
||||
() => unref(getProps).limit,
|
||||
(val: number) => {
|
||||
pageSizeRef.value = val
|
||||
limitRef.value = val
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => unref(getProps).currentPage,
|
||||
() => unref(getProps).page,
|
||||
(val: number) => {
|
||||
currentPageRef.value = val
|
||||
pageRef.value = val
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => pageSizeRef.value,
|
||||
() => limitRef.value,
|
||||
(val: number) => {
|
||||
emit('update:pageSize', val)
|
||||
emit('update:limit', val)
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => currentPageRef.value,
|
||||
() => pageRef.value,
|
||||
(val: number) => {
|
||||
emit('update:currentPage', val)
|
||||
emit('update:page', val)
|
||||
}
|
||||
)
|
||||
|
||||
@ -211,15 +211,8 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const rnderTableColumn = (columnsChildren?: TableColumn[]) => {
|
||||
const {
|
||||
columns,
|
||||
reserveIndex,
|
||||
pageSize,
|
||||
currentPage,
|
||||
align,
|
||||
headerAlign,
|
||||
showOverflowTooltip
|
||||
} = unref(getProps)
|
||||
const { columns, reserveIndex, limit, page, align, headerAlign, showOverflowTooltip } =
|
||||
unref(getProps)
|
||||
return [...[renderTableExpand()], ...[renderTableSelection()]].concat(
|
||||
(columnsChildren || columns).map((v) => {
|
||||
// 自定生成序号
|
||||
@ -227,11 +220,7 @@ export default defineComponent({
|
||||
return (
|
||||
<ElTableColumn
|
||||
type="index"
|
||||
index={
|
||||
v.index
|
||||
? v.index
|
||||
: (index) => setIndex(reserveIndex, index, pageSize, currentPage)
|
||||
}
|
||||
index={v.index ? v.index : (index) => setIndex(reserveIndex, index, limit, page)}
|
||||
align={v.align || align}
|
||||
headerAlign={v.headerAlign || headerAlign}
|
||||
label={v.label}
|
||||
@ -275,6 +264,7 @@ export default defineComponent({
|
||||
data={unref(getProps).data}
|
||||
onSelection-change={selectionChange}
|
||||
{...unref(getBindValue)}
|
||||
header-row-style="color: #000;background-color: #000;"
|
||||
>
|
||||
{{
|
||||
default: () => rnderTableColumn(),
|
||||
@ -284,8 +274,8 @@ export default defineComponent({
|
||||
</ElTable>
|
||||
{unref(getProps).pagination ? (
|
||||
<ElPagination
|
||||
v-model:pageSize={pageSizeRef.value}
|
||||
v-model:currentPage={currentPageRef.value}
|
||||
v-model:limit={limitRef.value}
|
||||
v-model:page={pageRef.value}
|
||||
class="mt-10px"
|
||||
{...unref(pagination)}
|
||||
></ElPagination>
|
||||
|
@ -1,6 +1,6 @@
|
||||
export type TableProps = {
|
||||
pageSize?: number
|
||||
currentPage?: number
|
||||
limit?: number
|
||||
page?: number
|
||||
// 是否多选
|
||||
selection?: boolean
|
||||
// 是否所有的超出隐藏,优先级低于schema中的showOverflowTooltip,
|
||||
|
@ -59,7 +59,7 @@ export const appModules: AppState = {
|
||||
breadcrumb: true, // 面包屑
|
||||
breadcrumbIcon: true, // 面包屑图标
|
||||
collapse: false, // 折叠菜单
|
||||
uniqueOpened: false, // 是否只保持一个子菜单的展开
|
||||
uniqueOpened: true, // 是否只保持一个子菜单的展开
|
||||
hamburger: true, // 折叠图标
|
||||
screenfull: true, // 全屏图标
|
||||
size: true, // 尺寸图标
|
||||
|
@ -26,7 +26,6 @@ const service: AxiosInstance = axios.create({
|
||||
service.interceptors.request.use(
|
||||
(config: AxiosRequestConfig) => {
|
||||
const token = wsCache.get(appStore.getToken)
|
||||
console.log('token', token)
|
||||
if (token !== '') {
|
||||
;(config.headers as any)['Authorization'] = token // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
|
@ -8,10 +8,8 @@ import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
interface TableResponse<T = any> {
|
||||
total: number
|
||||
list: T[]
|
||||
pageNumber: number
|
||||
pageSize: number
|
||||
count: number
|
||||
data: T[]
|
||||
}
|
||||
|
||||
interface UseTableConfig<T = any> {
|
||||
@ -19,17 +17,17 @@ interface UseTableConfig<T = any> {
|
||||
delListApi?: (option: any) => Promise<IResponse>
|
||||
// 返回数据格式配置
|
||||
response: {
|
||||
list: string
|
||||
total?: string
|
||||
data: string
|
||||
count?: string
|
||||
}
|
||||
props?: TableProps
|
||||
}
|
||||
|
||||
interface TableObject<T = any> {
|
||||
pageSize: number
|
||||
currentPage: number
|
||||
total: number
|
||||
tableList: T[]
|
||||
limit: number
|
||||
page: number
|
||||
count: number
|
||||
tableData: T[]
|
||||
params: any
|
||||
loading: boolean
|
||||
currentRow: Nullable<T>
|
||||
@ -38,13 +36,13 @@ interface TableObject<T = any> {
|
||||
export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
||||
const tableObject = reactive<TableObject<T>>({
|
||||
// 页数
|
||||
pageSize: 10,
|
||||
limit: 10,
|
||||
// 当前页
|
||||
currentPage: 1,
|
||||
page: 1,
|
||||
// 总条数
|
||||
total: 10,
|
||||
count: 10,
|
||||
// 表格数据
|
||||
tableList: [],
|
||||
tableData: [],
|
||||
// AxiosConfig 配置
|
||||
params: {},
|
||||
// 加载中
|
||||
@ -56,26 +54,26 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
||||
const paramsObj = computed(() => {
|
||||
return {
|
||||
...tableObject.params,
|
||||
pageSize: tableObject.pageSize,
|
||||
pageIndex: tableObject.currentPage
|
||||
limit: tableObject.limit,
|
||||
page: tableObject.page
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => tableObject.currentPage,
|
||||
() => tableObject.page,
|
||||
() => {
|
||||
methods.getList()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => tableObject.pageSize,
|
||||
() => tableObject.limit,
|
||||
() => {
|
||||
// 当前页不为1时,修改页数后会导致多次调用getList方法
|
||||
if (tableObject.currentPage === 1) {
|
||||
// 当前页不为1时,修改页数后会导致多次调用getdata方法
|
||||
if (tableObject.page === 1) {
|
||||
methods.getList()
|
||||
} else {
|
||||
tableObject.currentPage = 1
|
||||
tableObject.page = 1
|
||||
methods.getList()
|
||||
}
|
||||
}
|
||||
@ -102,20 +100,14 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
||||
}
|
||||
|
||||
const delData = async (ids: string[] | number[]) => {
|
||||
const res = await (config?.delListApi && config?.delListApi(ids))
|
||||
if (res) {
|
||||
ElMessage.success(t('common.delSuccess'))
|
||||
|
||||
// 计算出临界点
|
||||
const currentPage =
|
||||
tableObject.total % tableObject.pageSize === ids.length || tableObject.pageSize === 1
|
||||
? tableObject.currentPage > 1
|
||||
? tableObject.currentPage - 1
|
||||
: tableObject.currentPage
|
||||
: tableObject.currentPage
|
||||
|
||||
tableObject.currentPage = currentPage
|
||||
methods.getList()
|
||||
if (config?.delListApi) {
|
||||
const res = await config.delListApi(ids)
|
||||
if (res) {
|
||||
ElMessage.success(t('common.delSuccess'))
|
||||
methods.getList()
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('删除失败,请配置删除接口!')
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,8 +118,8 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
||||
tableObject.loading = false
|
||||
})
|
||||
if (res) {
|
||||
tableObject.tableList = get(res.data || {}, config?.response.list as string)
|
||||
tableObject.total = get(res.data || {}, config?.response?.total as string) || 0
|
||||
tableObject.tableData = get(res || {}, config?.response.data as string)
|
||||
tableObject.count = get(res || {}, config?.response.count as string) || 0
|
||||
}
|
||||
},
|
||||
setProps: async (props: TableProps = {}) => {
|
||||
@ -144,16 +136,16 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
|
||||
},
|
||||
// 与Search组件结合
|
||||
setSearchParams: (data: Recordable) => {
|
||||
tableObject.currentPage = 1
|
||||
tableObject.page = 1
|
||||
tableObject.params = Object.assign(tableObject.params, {
|
||||
pageSize: tableObject.pageSize,
|
||||
pageIndex: tableObject.currentPage,
|
||||
limit: tableObject.limit,
|
||||
pageIndex: tableObject.page,
|
||||
...data
|
||||
})
|
||||
methods.getList()
|
||||
},
|
||||
// 删除数据
|
||||
delList: async (ids: string[] | number[], multiple: boolean, message = true) => {
|
||||
deldata: async (ids: string[] | number[], multiple: boolean, message = true) => {
|
||||
const tableRef = await getTable()
|
||||
if (multiple) {
|
||||
if (!tableRef?.selections.length) {
|
||||
|
@ -57,7 +57,6 @@ router.beforeEach(async (to, from, next) => {
|
||||
const redirect = decodeURIComponent(redirectPath as string)
|
||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
|
||||
permissionStore.setIsAddRouters(true)
|
||||
console.log('nextData', nextData)
|
||||
next(nextData)
|
||||
}
|
||||
} else {
|
||||
|
@ -1,7 +1,88 @@
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { Table } from '@/components/Table'
|
||||
import { getMenuListApi } from '@/api/vadmin/auth/menu'
|
||||
import { TableData } from '@/api/table/types'
|
||||
import { reactive } from 'vue'
|
||||
import { useTable } from '@/hooks/web/useTable'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElButton } from 'element-plus'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const columns = reactive<TableColumn[]>([
|
||||
{
|
||||
field: 'title',
|
||||
label: '菜单名称'
|
||||
},
|
||||
{
|
||||
field: 'icon',
|
||||
label: '图标'
|
||||
},
|
||||
{
|
||||
field: 'order',
|
||||
label: '排序'
|
||||
},
|
||||
{
|
||||
field: 'menu_type',
|
||||
label: '菜单类型'
|
||||
},
|
||||
{
|
||||
field: 'perms',
|
||||
label: '权限标识'
|
||||
},
|
||||
{
|
||||
field: 'component',
|
||||
label: '组件路径'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
width: '260px',
|
||||
label: t('tableDemo.action'),
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
detail: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
const { register, tableObject, methods } = useTable<TableData>({
|
||||
getListApi: getMenuListApi,
|
||||
response: {
|
||||
data: 'data'
|
||||
},
|
||||
props: {
|
||||
columns
|
||||
}
|
||||
})
|
||||
|
||||
const { getList } = methods
|
||||
|
||||
getList()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div></div>
|
||||
<ContentWrap>
|
||||
<Table
|
||||
:data="tableObject.tableData"
|
||||
:loading="tableObject.loading"
|
||||
:selection="false"
|
||||
row-key="id"
|
||||
@register="register"
|
||||
>
|
||||
<template #action="{}">
|
||||
<ElButton type="primary" text>
|
||||
{{ t('exampleDemo.edit') }}
|
||||
</ElButton>
|
||||
<ElButton type="success" text>
|
||||
{{ t('exampleDemo.detail') }}
|
||||
</ElButton>
|
||||
<ElButton type="danger" text>
|
||||
{{ t('exampleDemo.del') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</Table>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
|
97
kinit-admin/src/views/vadmin/auth/role/index.vue
Normal file
97
kinit-admin/src/views/vadmin/auth/role/index.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { Table } from '@/components/Table'
|
||||
import { getRoleListApi } from '@/api/vadmin/auth/role'
|
||||
import { TableData } from '@/api/table/types'
|
||||
import { reactive } from 'vue'
|
||||
import { useTable } from '@/hooks/web/useTable'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElButton } from 'element-plus'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const columns = reactive<TableColumn[]>([
|
||||
{
|
||||
field: 'id',
|
||||
label: '角色编号'
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: '角色名称'
|
||||
},
|
||||
{
|
||||
field: 'role_key',
|
||||
label: '权限字符'
|
||||
},
|
||||
{
|
||||
field: 'index',
|
||||
label: '显示顺序'
|
||||
},
|
||||
{
|
||||
field: 'is_active',
|
||||
label: '状态'
|
||||
},
|
||||
{
|
||||
field: 'is_admin',
|
||||
label: '最高权限'
|
||||
},
|
||||
{
|
||||
field: 'create_datetime',
|
||||
label: '创建时间'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
width: '260px',
|
||||
label: t('tableDemo.action'),
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
detail: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
const { register, tableObject, methods } = useTable<TableData>({
|
||||
getListApi: getRoleListApi,
|
||||
response: {
|
||||
data: 'data',
|
||||
count: 'count'
|
||||
},
|
||||
props: {
|
||||
columns
|
||||
}
|
||||
})
|
||||
|
||||
const { getList } = methods
|
||||
|
||||
getList()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<Table
|
||||
v-model:limit="tableObject.limit"
|
||||
v-model:page="tableObject.page"
|
||||
:data="tableObject.tableData"
|
||||
:loading="tableObject.loading"
|
||||
:selection="false"
|
||||
:pagination="{
|
||||
total: tableObject.count
|
||||
}"
|
||||
@register="register"
|
||||
>
|
||||
<template #action="{}">
|
||||
<ElButton type="primary" text>
|
||||
{{ t('exampleDemo.edit') }}
|
||||
</ElButton>
|
||||
<ElButton type="success" text>
|
||||
{{ t('exampleDemo.detail') }}
|
||||
</ElButton>
|
||||
<ElButton type="danger" text>
|
||||
{{ t('exampleDemo.del') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</Table>
|
||||
</ContentWrap>
|
||||
</template>
|
66
kinit-admin/src/views/vadmin/auth/user/index.vue
Normal file
66
kinit-admin/src/views/vadmin/auth/user/index.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { Table } from '@/components/Table'
|
||||
import { getTableListApi } from '@/api/table'
|
||||
import { TableData } from '@/api/table/types'
|
||||
import { reactive } from 'vue'
|
||||
import { useTable } from '@/hooks/web/useTable'
|
||||
|
||||
const columns = reactive<TableColumn[]>([
|
||||
{
|
||||
field: 'index',
|
||||
label: 'index',
|
||||
type: 'index'
|
||||
},
|
||||
{
|
||||
field: 'title',
|
||||
label: 'title'
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: 'author'
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: 'displayTime'
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: 'pageviews'
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
label: 'action'
|
||||
}
|
||||
])
|
||||
|
||||
const { register, tableObject, methods } = useTable<TableData>({
|
||||
getListApi: getTableListApi,
|
||||
response: {
|
||||
list: 'list',
|
||||
total: 'total'
|
||||
},
|
||||
props: {
|
||||
columns
|
||||
}
|
||||
})
|
||||
|
||||
const { getList } = methods
|
||||
|
||||
getList()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<Table
|
||||
v-model:pageSize="tableObject.pageSize"
|
||||
v-model:currentPage="tableObject.currentPage"
|
||||
:data="tableObject.tableList"
|
||||
:loading="tableObject.loading"
|
||||
:pagination="{
|
||||
total: tableObject.total
|
||||
}"
|
||||
@register="register"
|
||||
/>
|
||||
</ContentWrap>
|
||||
</template>
|
1
kinit-admin/types/global.d.ts
vendored
1
kinit-admin/types/global.d.ts
vendored
@ -35,6 +35,7 @@ declare interface AxiosConfig {
|
||||
}
|
||||
|
||||
declare interface IResponse<T = any> {
|
||||
count: {}
|
||||
code: string
|
||||
data: T extends any ? T : T & any
|
||||
message: string
|
||||
|
@ -16,7 +16,6 @@ from core.validator import ValiDatetime
|
||||
|
||||
class Menu(BaseModel):
|
||||
title: str
|
||||
title_zh: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
component: str
|
||||
path: str
|
||||
|
Loading…
x
Reference in New Issue
Block a user