Browse Source

完善角色页

main
dark 5 months ago
parent
commit
de211b9924
  1. 7
      src/i18n.ts
  2. 3
      src/locales/lang/en-US.ts
  3. 1
      src/locales/lang/zh-CN.ts
  4. 2
      src/pages/system/menus/components/BatchButton.tsx
  5. 2
      src/pages/system/menus/components/TreeNodeRender.tsx
  6. 5
      src/pages/system/menus/index.tsx
  7. 11
      src/pages/system/menus/store.ts
  8. 50
      src/pages/system/roles/index.tsx
  9. 4
      src/service/base.ts
  10. 6
      src/store/user.ts

7
src/i18n.ts

@ -1,7 +1,7 @@
import { changeLanguage } from '@/store/system.ts' import { changeLanguage } from '@/store/system.ts'
import i18n, { InitOptions } from 'i18next'
import i18n, { InitOptions, t } from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector' import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next, useTranslation } from 'react-i18next'
import { initReactI18next, useTranslation, } from 'react-i18next'
import { zh, en } from './locales' import { zh, en } from './locales'
const detectionOptions = { const detectionOptions = {
@ -43,10 +43,9 @@ export const initI18n = (options?: InitOptions) => {
...options, ...options,
}) })
} }
export { export {
useTranslation
useTranslation, t
} }
export default i18n export default i18n

3
src/locales/lang/en-US.ts

@ -60,7 +60,8 @@ export default {
warningTitle: 'Warning', warningTitle: 'Warning',
batchDelete: 'Are you sure to delete the selected data?', batchDelete: 'Are you sure to delete the selected data?',
deleteConfirm: 'Are you sure to delete it?', deleteConfirm: 'Are you sure to delete it?',
success: 'Submission successful',
success: 'Submission successfully',
deleteSuccess: 'Delete successfully',
fail: 'Submission failed', fail: 'Submission failed',
saveSuccess: 'Save successfully', saveSuccess: 'Save successfully',
saveFail: 'Save failed', saveFail: 'Save failed',

1
src/locales/lang/zh-CN.ts

@ -63,6 +63,7 @@ export default {
success: '提交成功', success: '提交成功',
fail: '提交失败', fail: '提交失败',
saveSuccess: '保存成功', saveSuccess: '保存成功',
deleteSuccess: '删除成功',
saveFail: '保存失败', saveFail: '保存失败',
emptyData: '暂无数据', emptyData: '暂无数据',
emptyDataAdd: '暂无数据,点击添加', emptyDataAdd: '暂无数据,点击添加',

2
src/pages/system/menus/components/BatchButton.tsx

@ -8,6 +8,8 @@ const BatchButton = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { isPending, mutate, } = useAtomValue(deleteMenuAtom) const { isPending, mutate, } = useAtomValue(deleteMenuAtom)
const ids = useAtomValue(batchIdsAtom) const ids = useAtomValue(batchIdsAtom)
if (ids.length === 0) { if (ids.length === 0) {
return null return null
} }

2
src/pages/system/menus/components/TreeNodeRender.tsx

@ -13,7 +13,7 @@ export const TreeNodeRender = memo(({ node, form }: { node: MenuItem & TreeDataN
const { title } = node const { title } = node
const { t } = useTranslation() const { t } = useTranslation()
const { styles } = useStyle() const { styles } = useStyle()
const { mutate, } = useAtomValue(deleteMenuAtom)
const { mutate } = useAtomValue(deleteMenuAtom)
const setMenuData = useSetAtom(selectedMenuAtom) const setMenuData = useSetAtom(selectedMenuAtom)

5
src/pages/system/menus/index.tsx

@ -1,7 +1,7 @@
import Glass from '@/components/glass' import Glass from '@/components/glass'
import { useTranslation } from '@/i18n.ts' import { useTranslation } from '@/i18n.ts'
import { PageContainer, ProCard } from '@ant-design/pro-components' import { PageContainer, ProCard } from '@ant-design/pro-components'
import { Button, Form, Input, message, Radio, TreeSelect, InputNumber, notification, Alert } from 'antd'
import { Button, Form, Input, Radio, TreeSelect, InputNumber, notification, Alert } from 'antd'
import { useAtomValue } from 'jotai' import { useAtomValue } from 'jotai'
import { menuDataAtom, saveOrUpdateMenuAtom, selectedMenuAtom } from './store.ts' import { menuDataAtom, saveOrUpdateMenuAtom, selectedMenuAtom } from './store.ts'
import IconPicker from '@/components/icon/picker' import IconPicker from '@/components/icon/picker'
@ -26,9 +26,6 @@ const Menus = () => {
const currentMenu = useAtomValue<MenuItem>(selectedMenuAtom) ?? {} const currentMenu = useAtomValue<MenuItem>(selectedMenuAtom) ?? {}
useEffect(() => { useEffect(() => {
if (isSuccess) {
message.success(t('message.saveSuccess', '保存成功'))
}
if (isError) { if (isError) {
notification.error({ notification.error({

11
src/pages/system/menus/store.ts

@ -1,9 +1,10 @@
import systemServ from '@/service/system.ts' import systemServ from '@/service/system.ts'
import { IApiResult, IPage, IPageResult, MenuItem } from '@/types' import { IApiResult, IPage, IPageResult, MenuItem } from '@/types'
import { IMenu } from '@/types/menus' import { IMenu } from '@/types/menus'
import { AxiosResponse } from 'axios'
import { atomWithMutation, atomWithQuery, queryClientAtom } from 'jotai-tanstack-query' import { atomWithMutation, atomWithQuery, queryClientAtom } from 'jotai-tanstack-query'
import { atom, createStore } from 'jotai' import { atom, createStore } from 'jotai'
import { message } from 'antd'
import { t } from '@/i18n.ts'
export const defaultMenu = { export const defaultMenu = {
@ -17,7 +18,7 @@ export const defaultMenu = {
sort: 0, sort: 0,
id: 0, id: 0,
button: [], button: [],
} as MenuItem
} as unknown as MenuItem
export const menuPageAtom = atom<IPage>({}) export const menuPageAtom = atom<IPage>({})
@ -59,11 +60,8 @@ export const saveOrUpdateMenuAtom = atomWithMutation<IApiResult<IMenu>>((get) =>
return await systemServ.menus.update(data) return await systemServ.menus.update(data)
}, },
onSuccess: (res) => { onSuccess: (res) => {
message.success(t('message.saveSuccess', '保存成功'))
const menu = get(selectedMenuAtom) const menu = get(selectedMenuAtom)
console.log({
...menu,
id: res.data?.id
})
store.set(selectedMenuAtom, { store.set(selectedMenuAtom, {
...menu, ...menu,
id: res.data?.id id: res.data?.id
@ -85,6 +83,7 @@ export const deleteMenuAtom = atomWithMutation((get) => {
return await systemServ.menus.batchDelete(ids ?? get(batchIdsAtom)) return await systemServ.menus.batchDelete(ids ?? get(batchIdsAtom))
}, },
onSuccess: () => { onSuccess: () => {
message.success(t('message.deleteSuccess', '删除成功'))
store.set(batchIdsAtom, []) store.set(batchIdsAtom, [])
get(queryClientAtom).refetchQueries([ 'menus', get(menuPageAtom) ]).then() get(queryClientAtom).refetchQueries([ 'menus', get(menuPageAtom) ]).then()
} }

50
src/pages/system/roles/index.tsx

@ -1,29 +1,33 @@
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components'
import { ActionType, PageContainer, ProColumns, ProTable,BetaSchemaForm } from '@ant-design/pro-components'
import { createLazyFileRoute } from '@tanstack/react-router' import { createLazyFileRoute } from '@tanstack/react-router'
import { useStyle } from './style.ts' import { useStyle } from './style.ts'
import { useMemo, useRef } from 'react'
import { useAtomValue } from 'jotai'
import { rolesAtom } from './store.ts'
import { useMemo, useRef, useState } from 'react'
import { useAtom, useAtomValue } from 'jotai'
import { roleAtom, rolesAtom } from './store.ts'
import { useTranslation } from '@/i18n.ts' import { useTranslation } from '@/i18n.ts'
import { Button, Space, Table } from 'antd'
import { Button, Form, Space, Table } from 'antd'
import { PlusOutlined } from '@ant-design/icons' import { PlusOutlined } from '@ant-design/icons'
const Roles = () => { const Roles = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { styles } = useStyle() const { styles } = useStyle()
const [form] = Form.useForm()
const actionRef = useRef<ActionType>() const actionRef = useRef<ActionType>()
const { data, isLoading } = useAtomValue(rolesAtom) const { data, isLoading } = useAtomValue(rolesAtom)
const [ role, setRole ] = useAtom(roleAtom)
const [ open, setOpen] = useState(false)
const columns = useMemo(() => { const columns = useMemo(() => {
return [ return [
{ title: 'id', dataIndex: 'id', hideInTable: true, hideInSearch: true, },
{ title: '名称', dataIndex: 'name' },
{ title: '别名', dataIndex: 'code' },
{ title: '状态', dataIndex: 'status' },
{ title: 'id', dataIndex: 'id', hideInTable: true, hideInSearch: true, hideInForm: true,},
{ title: '名称', dataIndex: 'name', valueType: 'text',},
{ title: '别名', dataIndex: 'code', valueType: 'text', },
{ title: '状态', dataIndex: 'status', valueType: 'switch', },
{ title: '排序', dataIndex: 'sort', valueType: 'indexBorder', }, { title: '排序', dataIndex: 'sort', valueType: 'indexBorder', },
{ title: '备注', dataIndex: 'remark' },
{ title: '备注', dataIndex: 'remark' ,valueType: 'textarea' },
{ title: '权限', dataIndex: 'permissions', valueType: 'treeSelect', },
{ {
title: '操作', valueType: 'option', title: '操作', valueType: 'option',
key: 'option', key: 'option',
@ -31,14 +35,14 @@ const Roles = () => {
<a <a
key="editable" key="editable"
onClick={() => { onClick={() => {
action?.startEditable?.(record.id)
// action?.startEditable?.(record.id)
setRole(record)
setOpen(true)
form.setFieldsValue(record)
}} }}
> >
</a>, </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 href={record.url} target="_blank" rel="noopener noreferrer" key="del">
</a>, </a>,
@ -99,6 +103,24 @@ const Roles = () => {
} }
}} }}
/> />
<BetaSchemaForm
width={600}
form={form}
layout={'horizontal'}
title={t('system.roles.edit.title', '角色编辑')}
colProps={{ span: 24 }}
labelCol={{ span: 6 }}
wrapperCol={{ span: 16 }}
layoutType={'ModalForm'}
open={open}
modalProps={{
maskClosable: false,
}}
onOpenChange={(open) => {
console.log('open', open)
setOpen(open)
}}
columns={columns} />
</PageContainer> </PageContainer>
) )
} }

4
src/service/base.ts

@ -15,10 +15,10 @@ export const createCURD = <TParams, TResult>(api: string, options?: AxiosRequest
return request.post(`${api}/edit`, data, options) return request.post(`${api}/edit`, data, options)
}, },
delete: (id: number) => { delete: (id: number) => {
return request.delete(`${api}/delete`, { ...options, params: { id } })
return request.post(`${api}/delete`, { id }, options)
}, },
batchDelete: (ids: number[]) => { batchDelete: (ids: number[]) => {
return request.delete(`${api}/deletes`, { ...options, params: { ids } })
return request.post(`${api}/deletes`, { ids }, options )
}, },
info: (id: number) => { info: (id: number) => {
return request.get<TResult>(`${api}/${id}`, options) return request.get<TResult>(`${api}/${id}`, options)

6
src/store/user.ts

@ -4,7 +4,7 @@ import { AxiosResponse } from 'axios'
import { atom } from 'jotai/index' import { atom } from 'jotai/index'
import { IApiResult, IAuth, MenuItem } from '@/types' import { IApiResult, IAuth, MenuItem } from '@/types'
import { LoginRequest } from '@/types/login' import { LoginRequest } from '@/types/login'
import { atomWithMutation, atomWithQuery, queryClientAtom } from 'jotai-tanstack-query'
import { atomWithMutation, atomWithQuery } from 'jotai-tanstack-query'
import systemServ from '@/service/system.ts' import systemServ from '@/service/system.ts'
import { formatMenuData, isDev } from '@/utils' import { formatMenuData, isDev } from '@/utils'
@ -54,9 +54,5 @@ export const userMenuDataAtom = atomWithQuery<any, MenuItem[]>((get) => ({
select: (data: AxiosResponse) => { select: (data: AxiosResponse) => {
return formatMenuData(data.data.rows as any ?? []) return formatMenuData(data.data.rows as any ?? [])
}, },
initialData: () => {
const queryClient = get(queryClientAtom)
return queryClient.getQueryData([ 'user_menus', get(appAtom).token ])
},
retry: false, retry: false,
})) }))
Loading…
Cancel
Save