27 changed files with 2504 additions and 15 deletions
File diff suppressed because it is too large
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 122 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 122 KiB |
@ -0,0 +1,45 @@ |
|||||
|
import type { MenuModule } from '/@/router/types'; |
||||
|
import { t } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
const identityServer: MenuModule = { |
||||
|
orderNo: 20, |
||||
|
menu: { |
||||
|
path: '/identityServer', |
||||
|
name: 'IdentityServer', |
||||
|
children: [ |
||||
|
{ |
||||
|
path: 'clients', |
||||
|
name: 'Clients', |
||||
|
tag: { |
||||
|
type: 'warn', |
||||
|
dot: true, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'apiResources', |
||||
|
name: 'ApiResources', |
||||
|
tag: { |
||||
|
type: 'warn', |
||||
|
dot: true, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'apiScopes', |
||||
|
name: 'ApiScopes', |
||||
|
tag: { |
||||
|
type: 'warn', |
||||
|
dot: true, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'identityResources', |
||||
|
name: 'IdentityResources', |
||||
|
tag: { |
||||
|
type: 'warn', |
||||
|
dot: true, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
}; |
||||
|
export default identityServer; |
||||
@ -0,0 +1,54 @@ |
|||||
|
import type { AppRouteModule } from '/@/router/types'; |
||||
|
import { LAYOUT } from '/@/router/constant'; |
||||
|
import { t } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
const identityServer: AppRouteModule = { |
||||
|
path: '/identityServer', |
||||
|
name: 'IentityServer', |
||||
|
component: LAYOUT, |
||||
|
//redirect: '/admin/abpUser',
|
||||
|
meta: { |
||||
|
icon: 'ion:grid-outline', |
||||
|
title: 'IdentityServer', |
||||
|
}, |
||||
|
children: [ |
||||
|
{ |
||||
|
path: 'clients', |
||||
|
name: 'Clients', |
||||
|
component: () => import('/@/views/identityServers/clients/Clients.vue'), |
||||
|
meta: { |
||||
|
title: 'Clients', |
||||
|
icon: 'ant-design:skin-outlined', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'apiResources', |
||||
|
name: 'ApiResources', |
||||
|
component: () => import('/@/views/identityServers/apiResources/ApiResources.vue'), |
||||
|
meta: { |
||||
|
title: 'ApiResources', |
||||
|
icon: 'ant-design:skin-outlined', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'apiScopes', |
||||
|
name: 'ApiScopes', |
||||
|
component: () => import('/@/views/identityServers/apiScopes/ApiScopes.vue'), |
||||
|
meta: { |
||||
|
title: 'ApiResources', |
||||
|
icon: 'ant-design:skin-outlined', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
path: 'identityResources', |
||||
|
name: 'IdentityResources', |
||||
|
component: () => import('/@/views/identityServers/identityResources/IdentityResources.vue'), |
||||
|
meta: { |
||||
|
title: 'ApiResources', |
||||
|
icon: 'ant-design:skin-outlined', |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
|
export default identityServer; |
||||
@ -0,0 +1,49 @@ |
|||||
|
import { FormSchema } from '/@/components/Table'; |
||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
import { ClientServiceProxy, PagingClientListInput } from '/@/services/ServiceProxies'; |
||||
|
|
||||
|
export const searchFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'filter', |
||||
|
label: '关键字', |
||||
|
component: 'Input', |
||||
|
colProps: { span: 8 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const tableColumns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: 'ClientId', |
||||
|
dataIndex: 'clientId', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ClientName', |
||||
|
dataIndex: 'clientName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '是否启用', |
||||
|
dataIndex: 'enabled', |
||||
|
slots: { customRender: 'enabled' }, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AccessTokenLifetime', |
||||
|
dataIndex: 'accessTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AbsoluteRefreshTokenLifetime', |
||||
|
dataIndex: 'absoluteRefreshTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'Description', |
||||
|
dataIndex: 'description', |
||||
|
}, |
||||
|
]; |
||||
|
/** |
||||
|
* 分页列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function getTableListAsync(params: PagingClientListInput) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
return _clientServiceProxy.page(params); |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable" size="small"> |
||||
|
<template #enabled="{ record }"> |
||||
|
<Tag :color="record.enabled ? 'green' : 'red'"> |
||||
|
{{ record.enabled ? '是' : '否' }} |
||||
|
</Tag> |
||||
|
</template> |
||||
|
</BasicTable></div |
||||
|
> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||
|
import { tableColumns, searchFormSchema, getTableListAsync } from './ApiResources'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
import { Tag } from 'ant-design-vue'; |
||||
|
export default defineComponent({ |
||||
|
name: 'ApiResources', |
||||
|
components: { |
||||
|
BasicTable, |
||||
|
TableAction, |
||||
|
Tag, |
||||
|
}, |
||||
|
setup() { |
||||
|
const { t } = useI18n(); |
||||
|
// table配置 |
||||
|
const [registerTable] = useTable({ |
||||
|
columns: tableColumns, |
||||
|
formConfig: { |
||||
|
labelWidth: 70, |
||||
|
schemas: searchFormSchema, |
||||
|
}, |
||||
|
api: getTableListAsync, |
||||
|
showTableSetting: true, |
||||
|
useSearchForm: true, |
||||
|
bordered: true, |
||||
|
canResize: true, |
||||
|
showIndexColumn: true, |
||||
|
actionColumn: { |
||||
|
width: 150, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
slots: { |
||||
|
customRender: 'action', |
||||
|
}, |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
return { |
||||
|
registerTable, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,49 @@ |
|||||
|
import { FormSchema } from '/@/components/Table'; |
||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
import { ClientServiceProxy, PagingClientListInput } from '/@/services/ServiceProxies'; |
||||
|
|
||||
|
export const searchFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'filter', |
||||
|
label: '关键字', |
||||
|
component: 'Input', |
||||
|
colProps: { span: 8 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const tableColumns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: 'ClientId', |
||||
|
dataIndex: 'clientId', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ClientName', |
||||
|
dataIndex: 'clientName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '是否启用', |
||||
|
dataIndex: 'enabled', |
||||
|
slots: { customRender: 'enabled' }, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AccessTokenLifetime', |
||||
|
dataIndex: 'accessTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AbsoluteRefreshTokenLifetime', |
||||
|
dataIndex: 'absoluteRefreshTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'Description', |
||||
|
dataIndex: 'description', |
||||
|
}, |
||||
|
]; |
||||
|
/** |
||||
|
* 分页列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function getTableListAsync(params: PagingClientListInput) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
return _clientServiceProxy.page(params); |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable" size="small"> |
||||
|
<template #enabled="{ record }"> |
||||
|
<Tag :color="record.enabled ? 'green' : 'red'"> |
||||
|
{{ record.enabled ? '是' : '否' }} |
||||
|
</Tag> |
||||
|
</template> |
||||
|
</BasicTable></div |
||||
|
> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||
|
import { tableColumns, searchFormSchema, getTableListAsync } from './ApiScopes'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
import { Tag } from 'ant-design-vue'; |
||||
|
export default defineComponent({ |
||||
|
name: 'ApiScopes', |
||||
|
components: { |
||||
|
BasicTable, |
||||
|
TableAction, |
||||
|
Tag, |
||||
|
}, |
||||
|
setup() { |
||||
|
const { t } = useI18n(); |
||||
|
// table配置 |
||||
|
const [registerTable] = useTable({ |
||||
|
columns: tableColumns, |
||||
|
formConfig: { |
||||
|
labelWidth: 70, |
||||
|
schemas: searchFormSchema, |
||||
|
}, |
||||
|
api: getTableListAsync, |
||||
|
showTableSetting: true, |
||||
|
useSearchForm: true, |
||||
|
bordered: true, |
||||
|
canResize: true, |
||||
|
showIndexColumn: true, |
||||
|
actionColumn: { |
||||
|
width: 150, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
slots: { |
||||
|
customRender: 'action', |
||||
|
}, |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
return { |
||||
|
registerTable, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,88 @@ |
|||||
|
import { FormSchema } from '/@/components/Table'; |
||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
import { ClientServiceProxy, PagingClientListInput } from '/@/services/ServiceProxies'; |
||||
|
|
||||
|
export const searchFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'filter', |
||||
|
label: '关键字', |
||||
|
component: 'Input', |
||||
|
colProps: { span: 8 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const tableColumns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: 'ClientId', |
||||
|
dataIndex: 'clientId', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ClientName', |
||||
|
dataIndex: 'clientName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '是否启用', |
||||
|
dataIndex: 'enabled', |
||||
|
slots: { customRender: 'enabled' }, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AccessTokenLifetime', |
||||
|
dataIndex: 'accessTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AbsoluteRefreshTokenLifetime', |
||||
|
dataIndex: 'absoluteRefreshTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'Description', |
||||
|
dataIndex: 'description', |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const createFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'clientId', |
||||
|
label: 'ClientId', |
||||
|
component: 'Input', |
||||
|
required: true, |
||||
|
colProps: { span: 18 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'clientName', |
||||
|
label: 'ClientName', |
||||
|
component: 'Input', |
||||
|
required: true, |
||||
|
colProps: { span: 18 }, |
||||
|
}, |
||||
|
{ |
||||
|
field: 'description', |
||||
|
label: 'Description', |
||||
|
component: 'Input', |
||||
|
required: true, |
||||
|
colProps: { span: 18 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
/** |
||||
|
* 分页列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function getTableListAsync(params: PagingClientListInput) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
return _clientServiceProxy.page(params); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 创建client |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function createClientAsync({ request, changeOkLoading, validate, closeModal }) { |
||||
|
changeOkLoading(true); |
||||
|
await validate(); |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
await _clientServiceProxy.create(request); |
||||
|
changeOkLoading(false); |
||||
|
closeModal(); |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable" size="small"> |
||||
|
<template #toolbar> |
||||
|
<a-button type="primary" @click="openCreateClientModal"> |
||||
|
{{ t('common.createText') }} |
||||
|
</a-button> |
||||
|
</template> |
||||
|
<template #enabled="{ record }"> |
||||
|
<Tag :color="record.enabled ? 'green' : 'red'"> |
||||
|
{{ record.enabled ? '是' : '否' }} |
||||
|
</Tag> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<CreateClient @register="registerCreateClientModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||
|
import { tableColumns, searchFormSchema, getTableListAsync } from './Clients'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
import { Tag } from 'ant-design-vue'; |
||||
|
import CreateClient from './CreateClient.vue'; |
||||
|
import { useModal } from '/@/components/Modal'; |
||||
|
export default defineComponent({ |
||||
|
name: 'Clients', |
||||
|
components: { |
||||
|
BasicTable, |
||||
|
TableAction, |
||||
|
Tag, |
||||
|
CreateClient, |
||||
|
}, |
||||
|
setup() { |
||||
|
const { t } = useI18n(); |
||||
|
// table配置 |
||||
|
const [registerTable] = useTable({ |
||||
|
columns: tableColumns, |
||||
|
formConfig: { |
||||
|
labelWidth: 70, |
||||
|
schemas: searchFormSchema, |
||||
|
}, |
||||
|
api: getTableListAsync, |
||||
|
showTableSetting: true, |
||||
|
useSearchForm: true, |
||||
|
bordered: true, |
||||
|
canResize: true, |
||||
|
showIndexColumn: true, |
||||
|
actionColumn: { |
||||
|
width: 150, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
slots: { |
||||
|
customRender: 'action', |
||||
|
}, |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const [registerCreateClientModal, { openModal: openCreateClientModal }] = useModal(); |
||||
|
return { |
||||
|
registerTable, |
||||
|
registerCreateClientModal, |
||||
|
openCreateClientModal, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,61 @@ |
|||||
|
<template> |
||||
|
<BasicModal :title="创建Client" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal"> |
||||
|
<BasicForm @register="registerUserForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, useContext, defineEmit } from 'vue'; |
||||
|
import { BasicModal, useModalInner } from '/@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '/@/components/Form/index'; |
||||
|
import { createFormSchema, createClientAsync } from './Clients'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'CreateAbpRole', |
||||
|
components: { |
||||
|
BasicModal, |
||||
|
BasicForm, |
||||
|
}, |
||||
|
setup() { |
||||
|
// 加载父组件方法 |
||||
|
defineEmit(['reload']); |
||||
|
const ctx = useContext(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
const [registerUserForm, { getFieldsValue, validate, resetFields }] = useForm({ |
||||
|
labelWidth: 120, |
||||
|
schemas: createFormSchema, |
||||
|
showActionButtonGroup: false, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(); |
||||
|
|
||||
|
// 保存角色 |
||||
|
const submit = async () => { |
||||
|
try { |
||||
|
const request = getFieldsValue(); |
||||
|
await createClientAsync({ request, changeOkLoading, validate, closeModal }); |
||||
|
resetFields(); |
||||
|
ctx.emit('reload'); |
||||
|
} catch (error) { |
||||
|
changeOkLoading(false); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const cancel = () => { |
||||
|
resetFields(); |
||||
|
closeModal(); |
||||
|
}; |
||||
|
return { |
||||
|
t, |
||||
|
registerModal, |
||||
|
registerUserForm, |
||||
|
submit, |
||||
|
cancel, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
@ -0,0 +1,49 @@ |
|||||
|
import { FormSchema } from '/@/components/Table'; |
||||
|
import { BasicColumn } from '/@/components/Table'; |
||||
|
import { ClientServiceProxy, PagingClientListInput } from '/@/services/ServiceProxies'; |
||||
|
|
||||
|
export const searchFormSchema: FormSchema[] = [ |
||||
|
{ |
||||
|
field: 'filter', |
||||
|
label: '关键字', |
||||
|
component: 'Input', |
||||
|
colProps: { span: 8 }, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const tableColumns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: 'ClientId', |
||||
|
dataIndex: 'clientId', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'ClientName', |
||||
|
dataIndex: 'clientName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '是否启用', |
||||
|
dataIndex: 'enabled', |
||||
|
slots: { customRender: 'enabled' }, |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AccessTokenLifetime', |
||||
|
dataIndex: 'accessTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'AbsoluteRefreshTokenLifetime', |
||||
|
dataIndex: 'absoluteRefreshTokenLifetime', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'Description', |
||||
|
dataIndex: 'description', |
||||
|
}, |
||||
|
]; |
||||
|
/** |
||||
|
* 分页列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export async function getTableListAsync(params: PagingClientListInput) { |
||||
|
const _clientServiceProxy = new ClientServiceProxy(); |
||||
|
return _clientServiceProxy.page(params); |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<BasicTable @register="registerTable" size="small"> |
||||
|
<template #enabled="{ record }"> |
||||
|
<Tag :color="record.enabled ? 'green' : 'red'"> |
||||
|
{{ record.enabled ? '是' : '否' }} |
||||
|
</Tag> |
||||
|
</template> |
||||
|
</BasicTable></div |
||||
|
> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent } from 'vue'; |
||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'; |
||||
|
import { tableColumns, searchFormSchema, getTableListAsync } from './IdentityResources'; |
||||
|
import { useI18n } from '/@/hooks/web/useI18n'; |
||||
|
import { Tag } from 'ant-design-vue'; |
||||
|
export default defineComponent({ |
||||
|
name: 'IdentityResources', |
||||
|
components: { |
||||
|
BasicTable, |
||||
|
TableAction, |
||||
|
Tag, |
||||
|
}, |
||||
|
setup() { |
||||
|
const { t } = useI18n(); |
||||
|
// table配置 |
||||
|
const [registerTable] = useTable({ |
||||
|
columns: tableColumns, |
||||
|
formConfig: { |
||||
|
labelWidth: 70, |
||||
|
schemas: searchFormSchema, |
||||
|
}, |
||||
|
api: getTableListAsync, |
||||
|
showTableSetting: true, |
||||
|
useSearchForm: true, |
||||
|
bordered: true, |
||||
|
canResize: true, |
||||
|
showIndexColumn: true, |
||||
|
actionColumn: { |
||||
|
width: 150, |
||||
|
title: t('common.action'), |
||||
|
dataIndex: 'action', |
||||
|
slots: { |
||||
|
customRender: 'action', |
||||
|
}, |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
return { |
||||
|
registerTable, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
||||
Loading…
Reference in new issue