diff --git a/src/i18n.ts b/src/i18n.ts index d7ca59d..93e2c61 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1,7 +1,7 @@ import { changeLanguage } from '@/store/system.ts' -import i18n, { InitOptions } from 'i18next' +import i18n, { InitOptions, t } from 'i18next' import LanguageDetector from 'i18next-browser-languagedetector' -import { initReactI18next, useTranslation } from 'react-i18next' +import { initReactI18next, useTranslation, } from 'react-i18next' import { zh, en } from './locales' const detectionOptions = { @@ -43,10 +43,9 @@ export const initI18n = (options?: InitOptions) => { ...options, }) - } export { - useTranslation + useTranslation, t } export default i18n \ No newline at end of file diff --git a/src/locales/lang/en-US.ts b/src/locales/lang/en-US.ts index fe3de35..1c8a386 100644 --- a/src/locales/lang/en-US.ts +++ b/src/locales/lang/en-US.ts @@ -60,7 +60,8 @@ export default { warningTitle: 'Warning', batchDelete: 'Are you sure to delete the selected data?', deleteConfirm: 'Are you sure to delete it?', - success: 'Submission successful', + success: 'Submission successfully', + deleteSuccess: 'Delete successfully', fail: 'Submission failed', saveSuccess: 'Save successfully', saveFail: 'Save failed', diff --git a/src/locales/lang/zh-CN.ts b/src/locales/lang/zh-CN.ts index 1d4f455..3e5ec17 100644 --- a/src/locales/lang/zh-CN.ts +++ b/src/locales/lang/zh-CN.ts @@ -63,6 +63,7 @@ export default { success: '提交成功', fail: '提交失败', saveSuccess: '保存成功', + deleteSuccess: '删除成功', saveFail: '保存失败', emptyData: '暂无数据', emptyDataAdd: '暂无数据,点击添加', diff --git a/src/pages/system/menus/components/BatchButton.tsx b/src/pages/system/menus/components/BatchButton.tsx index ec15cfd..8e5a45c 100644 --- a/src/pages/system/menus/components/BatchButton.tsx +++ b/src/pages/system/menus/components/BatchButton.tsx @@ -5,28 +5,30 @@ import { useTranslation } from '@/i18n.ts' const BatchButton = () => { - const { t } = useTranslation() - const { isPending, mutate, } = useAtomValue(deleteMenuAtom) - const ids = useAtomValue(batchIdsAtom) - if (ids.length === 0) { - return null - } + const { t } = useTranslation() + const { isPending, mutate, } = useAtomValue(deleteMenuAtom) + const ids = useAtomValue(batchIdsAtom) - return ( - { - mutate(ids as number[]) - }} - title={t('message.batchDelete', '确定要删除所选数据吗?')}> - - - ) + + if (ids.length === 0) { + return null + } + + return ( + { + mutate(ids as number[]) + }} + title={t('message.batchDelete', '确定要删除所选数据吗?')}> + + + ) } export default BatchButton \ No newline at end of file diff --git a/src/pages/system/menus/components/TreeNodeRender.tsx b/src/pages/system/menus/components/TreeNodeRender.tsx index 8091ae6..4d479b6 100644 --- a/src/pages/system/menus/components/TreeNodeRender.tsx +++ b/src/pages/system/menus/components/TreeNodeRender.tsx @@ -10,49 +10,49 @@ import { PlusOutlined } from '@ant-design/icons' import ActionIcon, { DeleteAction } from '@/components/icon/action' export const TreeNodeRender = memo(({ node, form }: { node: MenuItem & TreeDataNode, form: FormInstance }) => { - const { title } = node - const { t } = useTranslation() - const { styles } = useStyle() - const { mutate, } = useAtomValue(deleteMenuAtom) + const { title } = node + const { t } = useTranslation() + const { styles } = useStyle() + const { mutate } = useAtomValue(deleteMenuAtom) - const setMenuData = useSetAtom(selectedMenuAtom) + const setMenuData = useSetAtom(selectedMenuAtom) - return ( -
- {title as any} - + return ( +
+ {title as any} + } - title={t('actions.add', '添加')} - onClick={(e) => { - // console.log('add') - e.stopPropagation() - e.preventDefault() - const menu = { - ...defaultMenu, - parent_id: node.id, - } - setMenuData(menu) - form.setFieldsValue(menu) + size={12} + icon={} + title={t('actions.add', '添加')} + onClick={(e) => { + // console.log('add') + e.stopPropagation() + e.preventDefault() + const menu = { + ...defaultMenu, + parent_id: node.id, + } + setMenuData(menu) + form.setFieldsValue(menu) - }}/> + }}/> { - mutate([ (node as any).id ]) - }} + title={t('message.deleteConfirm', '确定要删除吗?')} + onConfirm={() => { + mutate([ (node as any).id ]) + }} > { - e.stopPropagation() - e.stopPropagation() - }}/> + size={12} + onClick={(e) => { + e.stopPropagation() + e.stopPropagation() + }}/> -
- ) +
+ ) }) \ No newline at end of file diff --git a/src/pages/system/menus/index.tsx b/src/pages/system/menus/index.tsx index 5478a56..534ae77 100644 --- a/src/pages/system/menus/index.tsx +++ b/src/pages/system/menus/index.tsx @@ -1,7 +1,7 @@ import Glass from '@/components/glass' import { useTranslation } from '@/i18n.ts' 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 { menuDataAtom, saveOrUpdateMenuAtom, selectedMenuAtom } from './store.ts' import IconPicker from '@/components/icon/picker' @@ -26,9 +26,6 @@ const Menus = () => { const currentMenu = useAtomValue(selectedMenuAtom) ?? {} useEffect(() => { - if (isSuccess) { - message.success(t('message.saveSuccess', '保存成功')) - } if (isError) { notification.error({ diff --git a/src/pages/system/menus/store.ts b/src/pages/system/menus/store.ts index e1582d8..c06c7ea 100644 --- a/src/pages/system/menus/store.ts +++ b/src/pages/system/menus/store.ts @@ -1,23 +1,24 @@ import systemServ from '@/service/system.ts' import { IApiResult, IPage, IPageResult, MenuItem } from '@/types' import { IMenu } from '@/types/menus' -import { AxiosResponse } from 'axios' import { atomWithMutation, atomWithQuery, queryClientAtom } from 'jotai-tanstack-query' import { atom, createStore } from 'jotai' +import { message } from 'antd' +import { t } from '@/i18n.ts' export const defaultMenu = { - parent_id: 0, - type: 'menu', - name: '', - title: '', - icon: '', - path: '', - component: '', - sort: 0, - id: 0, - button: [], -} as MenuItem + parent_id: 0, + type: 'menu', + name: '', + title: '', + icon: '', + path: '', + component: '', + sort: 0, + id: 0, + button: [], +} as unknown as MenuItem export const menuPageAtom = atom({}) @@ -25,68 +26,66 @@ const store = createStore() export const menuDataAtom = atomWithQuery>((get) => { - return { - queryKey: [ 'menus', get(menuPageAtom) ], - queryFn: async ({ queryKey: [ , page ] }) => { - return await systemServ.menus.list(page) - }, - select: (data) => { - return data.rows ?? [] + return { + queryKey: [ 'menus', get(menuPageAtom) ], + queryFn: async ({ queryKey: [ , page ] }) => { + return await systemServ.menus.list(page) + }, + select: (data) => { + return data.rows ?? [] + } } - } }) export const selectedMenuIdAtom = atom(0) export const selectedMenuAtom = atom({} as MenuItem) export const byIdMenuAtom = atomWithQuery((get) => ({ - queryKey: [ 'selectedMenu', get(selectedMenuIdAtom) ], - queryFn: async ({ queryKey: [ , id ] }) => { - return await systemServ.menus.info(id as number) - }, - select: data => data.data, + queryKey: [ 'selectedMenu', get(selectedMenuIdAtom) ], + queryFn: async ({ queryKey: [ , id ] }) => { + return await systemServ.menus.info(id as number) + }, + select: data => data.data, })) export const saveOrUpdateMenuAtom = atomWithMutation>((get) => { - return { - mutationKey: [ 'updateMenu', get(selectedMenuIdAtom) ], - mutationFn: async (data: IMenu) => { - if (data.id === 0) { - return await systemServ.menus.add(data) - } - return await systemServ.menus.update(data) - }, - onSuccess: (res) => { - const menu = get(selectedMenuAtom) - console.log({ - ...menu, - id: res.data?.id - }) - store.set(selectedMenuAtom, { - ...menu, - id: res.data?.id - }) - //更新列表 - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore fix - get(queryClientAtom).refetchQueries([ 'menus', get(menuPageAtom) ]).then() + return { + mutationKey: [ 'updateMenu', get(selectedMenuIdAtom) ], + mutationFn: async (data: IMenu) => { + if (data.id === 0) { + return await systemServ.menus.add(data) + } + return await systemServ.menus.update(data) + }, + onSuccess: (res) => { + message.success(t('message.saveSuccess', '保存成功')) + const menu = get(selectedMenuAtom) + store.set(selectedMenuAtom, { + ...menu, + id: res.data?.id + }) + //更新列表 + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore fix + get(queryClientAtom).refetchQueries([ 'menus', get(menuPageAtom) ]).then() + } } - } }) export const batchIdsAtom = atom([]) export const deleteMenuAtom = atomWithMutation((get) => { - return { - mutationKey: [ 'deleteMenu', get(batchIdsAtom) ], - mutationFn: async (ids?: number[]) => { - return await systemServ.menus.batchDelete(ids ?? get(batchIdsAtom)) - }, - onSuccess: () => { - store.set(batchIdsAtom, []) - get(queryClientAtom).refetchQueries([ 'menus', get(menuPageAtom) ]).then() + return { + mutationKey: [ 'deleteMenu', get(batchIdsAtom) ], + mutationFn: async (ids?: number[]) => { + return await systemServ.menus.batchDelete(ids ?? get(batchIdsAtom)) + }, + onSuccess: () => { + message.success(t('message.deleteSuccess', '删除成功')) + store.set(batchIdsAtom, []) + get(queryClientAtom).refetchQueries([ 'menus', get(menuPageAtom) ]).then() + } } - } }) \ No newline at end of file diff --git a/src/pages/system/roles/index.tsx b/src/pages/system/roles/index.tsx index 3178631..0344fe8 100644 --- a/src/pages/system/roles/index.tsx +++ b/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 { 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 { Button, Space, Table } from 'antd' +import { Button, Form, Space, Table } from 'antd' import { PlusOutlined } from '@ant-design/icons' const Roles = () => { const { t } = useTranslation() const { styles } = useStyle() + const [form] = Form.useForm() const actionRef = useRef() const { data, isLoading } = useAtomValue(rolesAtom) + const [ role, setRole ] = useAtom(roleAtom) + const [ open, setOpen] = useState(false) const columns = useMemo(() => { 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: 'remark' }, + { title: '备注', dataIndex: 'remark' ,valueType: 'textarea' }, + { title: '权限', dataIndex: 'permissions', valueType: 'treeSelect', }, { title: '操作', valueType: 'option', key: 'option', @@ -31,14 +35,14 @@ const Roles = () => { { - action?.startEditable?.(record.id) + // action?.startEditable?.(record.id) + setRole(record) + setOpen(true) + form.setFieldsValue(record) }} > 编辑 , - - 查看 - , 删除 , @@ -99,6 +103,24 @@ const Roles = () => { } }} /> + { + console.log('open', open) + setOpen(open) + }} + columns={columns} /> ) } diff --git a/src/service/base.ts b/src/service/base.ts index 31a413c..ebabceb 100644 --- a/src/service/base.ts +++ b/src/service/base.ts @@ -15,10 +15,10 @@ export const createCURD = (api: string, options?: AxiosRequest return request.post(`${api}/edit`, data, options) }, delete: (id: number) => { - return request.delete(`${api}/delete`, { ...options, params: { id } }) + return request.post(`${api}/delete`, { id }, options) }, batchDelete: (ids: number[]) => { - return request.delete(`${api}/deletes`, { ...options, params: { ids } }) + return request.post(`${api}/deletes`, { ids }, options ) }, info: (id: number) => { return request.get(`${api}/${id}`, options) diff --git a/src/store/user.ts b/src/store/user.ts index 280d7a9..d2901eb 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -4,7 +4,7 @@ import { AxiosResponse } from 'axios' import { atom } from 'jotai/index' import { IApiResult, IAuth, MenuItem } from '@/types' 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 { formatMenuData, isDev } from '@/utils' @@ -54,9 +54,5 @@ export const userMenuDataAtom = atomWithQuery((get) => ({ select: (data: AxiosResponse) => { return formatMenuData(data.data.rows as any ?? []) }, - initialData: () => { - const queryClient = get(queryClientAtom) - return queryClient.getQueryData([ 'user_menus', get(appAtom).token ]) - }, retry: false, }))