dark
7 months ago
12 changed files with 337 additions and 124 deletions
-
15src/locales/lang/en-US.ts
-
3src/locales/lang/pages/system/menus/en-US.ts
-
24src/locales/lang/pages/system/menus/zh-CN.ts
-
14src/locales/lang/zh-CN.ts
-
45src/pages/system/menus/index.tsx
-
13src/pages/system/menus/store.ts
-
100src/pages/system/roles/index.tsx
-
25src/pages/system/roles/store.ts
-
22src/pages/system/roles/style.ts
-
4src/service/base.ts
-
4src/service/system.ts
-
2vite.config.ts
@ -0,0 +1,3 @@ |
|||
export default { |
|||
|
|||
} |
@ -0,0 +1,24 @@ |
|||
export default { |
|||
title: '菜单', |
|||
setting: '配置', |
|||
saveSuccess: '保存成功', |
|||
form:{ |
|||
title: '菜单名称', |
|||
parent: '上级菜单', |
|||
type:'类型', |
|||
typeOptions: { |
|||
menu: '菜单', |
|||
iframe: 'iframe', |
|||
link: '外链', |
|||
button: '按钮', |
|||
}, |
|||
name: '别名', |
|||
icon: '图标', |
|||
sort: '排序', |
|||
path: '路由', |
|||
component: '视图', |
|||
componentHelp: '视图路径,相对于src/pages,菜单组可以不填', |
|||
save: '保存', |
|||
}, |
|||
button: '按钮' |
|||
} |
@ -1,15 +1,109 @@ |
|||
import { PageContainer } from '@ant-design/pro-components' |
|||
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components' |
|||
import { createLazyFileRoute } from '@tanstack/react-router' |
|||
import { useStyle } from './style.ts' |
|||
import { useMemo, useRef } from 'react' |
|||
import { useAtomValue } from 'jotai' |
|||
import { rolesAtom } from './store.ts' |
|||
import { useTranslation } from '@/i18n.ts' |
|||
import { Button, Space, Table } from 'antd' |
|||
import { PlusOutlined } from '@ant-design/icons' |
|||
|
|||
const Roles = () => { |
|||
|
|||
const { t } = useTranslation() |
|||
const { styles } = useStyle() |
|||
const actionRef = useRef<ActionType>() |
|||
const { data, isLoading } = useAtomValue(rolesAtom) |
|||
|
|||
const columns = useMemo(() => { |
|||
|
|||
return [ |
|||
{ title: 'id', dataIndex: 'id', hideInTable: true, hideInSearch: true, }, |
|||
{ title: '名称', dataIndex: 'name' }, |
|||
{ title: '别名', dataIndex: 'code' }, |
|||
{ title: '状态', dataIndex: 'status' }, |
|||
{ title: '排序', dataIndex: 'sort', valueType: 'indexBorder', }, |
|||
{ title: '备注', dataIndex: 'remark' }, |
|||
{ |
|||
title: '操作', valueType: 'option', |
|||
key: 'option', |
|||
render: (text, record, _, action) => [ |
|||
<a |
|||
key="editable" |
|||
onClick={() => { |
|||
action?.startEditable?.(record.id) |
|||
}} |
|||
> |
|||
编辑 |
|||
</a>, |
|||
<a href={record.url} target="_blank" rel="noopener noreferrer" key="view"> |
|||
查看 |
|||
</a>, |
|||
<a href={record.url} target="_blank" rel="noopener noreferrer" key="del"> |
|||
删除 |
|||
</a>, |
|||
], |
|||
}, |
|||
] as ProColumns[] |
|||
}, []) |
|||
|
|||
return ( |
|||
<PageContainer breadcrumbRender={false} title={false} className={styles.container}> |
|||
<ProTable |
|||
rowKey={'id'} |
|||
actionRef={actionRef} |
|||
headerTitle={t('system.roles.title', '角色管理')} |
|||
columns={columns} |
|||
loading={isLoading} |
|||
dataSource={data?.rows} |
|||
search={false} |
|||
rowSelection={{ |
|||
selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT], |
|||
}} |
|||
tableAlertOptionRender={() => { |
|||
return ( |
|||
<PageContainer breadcrumbRender={false}> |
|||
<Space size={16}> |
|||
<a>批量删除</a> |
|||
</Space> |
|||
); |
|||
}} |
|||
toolbar={{ |
|||
search: { |
|||
onSearch: (value: string) => { |
|||
alert(value) |
|||
}, |
|||
}, |
|||
onSearch: (value) => { |
|||
console.log('value', value) |
|||
}, |
|||
actions: [ |
|||
|
|||
<Button |
|||
key="button" |
|||
icon={<PlusOutlined/>} |
|||
onClick={() => { |
|||
actionRef.current?.reload() |
|||
}} |
|||
type="primary" |
|||
> |
|||
新建 |
|||
</Button>, |
|||
] |
|||
}} |
|||
pagination={{ |
|||
total: data?.total, |
|||
current: data?.page, |
|||
pageSize: data?.pageSize, |
|||
onChange: (page) => { |
|||
console.log('page', page) |
|||
} |
|||
}} |
|||
/> |
|||
</PageContainer> |
|||
) |
|||
} |
|||
|
|||
export const Route = createLazyFileRoute("/system/roles")({ |
|||
export const Route = createLazyFileRoute('/system/roles')({ |
|||
component: Roles |
|||
}) |
|||
|
@ -0,0 +1,25 @@ |
|||
import { atom } from 'jotai/index' |
|||
import { IRole } from '@/types/roles' |
|||
import { atomWithQuery } from 'jotai-tanstack-query' |
|||
import { IPage, IPageResult } from '@/types' |
|||
import systemServ from '@/service/system.ts' |
|||
|
|||
type SearchParams = IPage & IRole |
|||
|
|||
export const idAtom = atom(0) |
|||
|
|||
export const IdsAtom = atom([]) |
|||
|
|||
export const roleAtom = atom<IRole>(undefined as unknown as IRole) |
|||
|
|||
export const searchAtom = atom<SearchParams>({} as SearchParams) |
|||
|
|||
|
|||
export const rolesAtom = atomWithQuery<any, IPageResult<IRole>>((get) => { |
|||
return { |
|||
queryKey: [ 'roles', get(searchAtom) ], |
|||
queryFn: async ({ queryKey: [ , params ] }) => { |
|||
return await systemServ.role.list(params as SearchParams) |
|||
}, |
|||
} |
|||
}) |
@ -0,0 +1,22 @@ |
|||
import { createStyles } from '@/theme' |
|||
|
|||
export const useStyle = createStyles(({ token, css, cx, prefixCls }) => { |
|||
const prefix = `${prefixCls}-${token?.proPrefix}-role-page`; |
|||
|
|||
|
|||
const box = css`
|
|||
flex: 1; |
|||
background: ${token.colorBgContainer}; |
|||
`
|
|||
const form = css`
|
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
min-width: 500px; |
|||
`
|
|||
|
|||
return { |
|||
container: cx(prefix), |
|||
box, |
|||
form, |
|||
} |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue