Browse Source

完善部门页面

main
dark 5 months ago
parent
commit
3c873be51c
  1. 13
      src/pages/system/departments/components/DepartmentTree.tsx
  2. 3
      src/pages/system/departments/components/TreeNodeRender.tsx
  3. 3
      src/pages/system/departments/index.tsx
  4. 41
      src/pages/system/departments/store.ts
  5. 116
      src/pages/system/menus/components/MenuTree.tsx
  6. 13
      src/pages/system/menus/store.ts

13
src/pages/system/departments/components/DepartmentTree.tsx

@ -2,18 +2,17 @@ import { Empty, Spin, Tree } from 'antd'
import { useStyle } from '../style.ts' import { useStyle } from '../style.ts'
import { useTranslation } from '@/i18n.ts' import { useTranslation } from '@/i18n.ts'
import { useSetAtom } from 'jotai' import { useSetAtom } from 'jotai'
import { useDepartStore } from '../store.ts'
import { selectedDepartAtom, departTreeAtom, batchIdsAtom } from '../store.ts'
import { FormInstance } from 'antd/lib' import { FormInstance } from 'antd/lib'
import { useAtomValue } from 'jotai/index' import { useAtomValue } from 'jotai/index'
import { TreeNodeRender } from './TreeNodeRender.tsx' import { TreeNodeRender } from './TreeNodeRender.tsx'
import { useRef } from 'react'
import { useEffect, useRef } from 'react'
import { flattenTree } from '@/utils' import { flattenTree } from '@/utils'
import { useDeepCompareEffect } from 'react-use' import { useDeepCompareEffect } from 'react-use'
import { IDepartment } from '@/types/department' import { IDepartment } from '@/types/department'
export const DepartmentTree = ({ form }: { form: FormInstance }) => { export const DepartmentTree = ({ form }: { form: FormInstance }) => {
const { selectedDepartAtom, departTreeAtom, batchIdsAtom } = useDepartStore()
const { styles } = useStyle() const { styles } = useStyle()
const { t } = useTranslation() const { t } = useTranslation()
const setIds = useSetAtom(batchIdsAtom) const setIds = useSetAtom(batchIdsAtom)
@ -30,14 +29,16 @@ export const DepartmentTree = ({ form }: { form: FormInstance }) => {
if (data.length) { if (data.length) {
// @ts-ignore flattenTree // @ts-ignore flattenTree
flattenMenusRef.current = flattenTree<IDepartment[]>(data as any) flattenMenusRef.current = flattenTree<IDepartment[]>(data as any)
// console.log(flattenMenusRef.current)
} }
}, [ data, isLoading ])
useEffect(() => {
return () => { return () => {
setCurrent({} as IDepartment) setCurrent({} as IDepartment)
} }
}, [ data, isLoading ])
}, [])
const renderEmpty = () => { const renderEmpty = () => {
if ((data as any).length > 0 || isLoading) return null if ((data as any).length > 0 || isLoading) return null

3
src/pages/system/departments/components/TreeNodeRender.tsx

@ -5,7 +5,7 @@ import { FormInstance } from 'antd/lib'
import { useTranslation } from '@/i18n.ts' import { useTranslation } from '@/i18n.ts'
import { useStyle } from '../style.ts' import { useStyle } from '../style.ts'
import { useAtomValue, useSetAtom } from 'jotai/index' import { useAtomValue, useSetAtom } from 'jotai/index'
import { useDepartStore } from '../store.ts'
import { selectedDepartAtom, deleteDepartAtom, defaultDepart } from '../store.ts'
import { PlusOutlined } from '@ant-design/icons' import { PlusOutlined } from '@ant-design/icons'
import ActionIcon, { DeleteAction } from '@/components/icon/action' import ActionIcon, { DeleteAction } from '@/components/icon/action'
@ -13,7 +13,6 @@ export const TreeNodeRender = memo(({ node, form }: { node: MenuItem & TreeDataN
const { name } = node const { name } = node
const { t } = useTranslation() const { t } = useTranslation()
const { styles } = useStyle() const { styles } = useStyle()
const { selectedDepartAtom, deleteDepartAtom, defaultDepart } = useDepartStore()
const { mutate } = useAtomValue(deleteDepartAtom) const { mutate } = useAtomValue(deleteDepartAtom)
const setCurrent = useSetAtom(selectedDepartAtom) const setCurrent = useSetAtom(selectedDepartAtom)

3
src/pages/system/departments/index.tsx

@ -6,7 +6,7 @@ import { useStyle } from './style.ts'
import DepartmentTree from './components/DepartmentTree.tsx' import DepartmentTree from './components/DepartmentTree.tsx'
import { Alert, Button, Divider, Form, Input, InputNumber, InputRef, notification, TreeSelect } from 'antd' import { Alert, Button, Divider, Form, Input, InputNumber, InputRef, notification, TreeSelect } from 'antd'
import { PlusOutlined } from '@ant-design/icons' import { PlusOutlined } from '@ant-design/icons'
import { useDepartStore } from './store.ts'
import { defaultDepart, selectedDepartAtom, departTreeAtom, saveOrUpdateDepartAtom } from './store.ts'
import { useAtom, useAtomValue, } from 'jotai' import { useAtom, useAtomValue, } from 'jotai'
import Glass from '@/components/glass' import Glass from '@/components/glass'
import { useEffect, useRef } from 'react' import { useEffect, useRef } from 'react'
@ -17,7 +17,6 @@ const Departments = () => {
const { styles, cx } = useStyle() const { styles, cx } = useStyle()
const [ form ] = Form.useForm() const [ form ] = Form.useForm()
const inputRef = useRef<InputRef>() const inputRef = useRef<InputRef>()
const { defaultDepart, selectedDepartAtom, departTreeAtom, saveOrUpdateDepartAtom } = useDepartStore()
const { data } = useAtomValue(departTreeAtom) const { data } = useAtomValue(departTreeAtom)
const { mutate, isPending, isError, error } = useAtomValue(saveOrUpdateDepartAtom) const { mutate, isPending, isError, error } = useAtomValue(saveOrUpdateDepartAtom)
const [ current, setCurrent ] = useAtom(selectedDepartAtom) const [ current, setCurrent ] = useAtom(selectedDepartAtom)

41
src/pages/system/departments/store.ts

@ -9,9 +9,9 @@ import { message } from 'antd'
const store = createStore() const store = createStore()
const departPageAtom = atom<IPage>({})
export const departPageAtom = atom<IPage>({})
const defaultDepart = {
export const defaultDepart = {
id: 0, id: 0,
parent_id: 0, parent_id: 0,
name: '', name: '',
@ -20,11 +20,11 @@ const defaultDepart = {
sort: 0, sort: 0,
} as IDepartment } as IDepartment
const batchIdsAtom = atom<number[]>([])
export const batchIdsAtom = atom<number[]>([])
const selectedDepartAtom = atom<IDepartment>({} as IDepartment)
export const selectedDepartAtom = atom<IDepartment>({} as IDepartment)
const departTreeAtom = atomWithQuery(() => {
export const departTreeAtom = atomWithQuery(() => {
return { return {
queryKey: [ 'departTree' ], queryKey: [ 'departTree' ],
@ -37,10 +37,10 @@ const departTreeAtom = atomWithQuery(() => {
} }
}) })
const saveOrUpdateDepartAtom = atomWithMutation<IApiResult, IDepartment>((get) => {
export const saveOrUpdateDepartAtom = atomWithMutation<IApiResult, IDepartment>((get) => {
return { return {
mutationKey: [ 'saveOrUpdateDepart', get(selectedDepartAtom) ],
mutationKey: [ 'saveOrUpdateDepart' ],
mutationFn: async (data: IDepartment) => { mutationFn: async (data: IDepartment) => {
if (data.id) { if (data.id) {
return await systemServ.dept.update(data) return await systemServ.dept.update(data)
@ -50,18 +50,22 @@ const saveOrUpdateDepartAtom = atomWithMutation<IApiResult, IDepartment>((get) =
onSuccess: (res) => { onSuccess: (res) => {
const isAdd = !!res.data?.id const isAdd = !!res.data?.id
message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功')) message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功'))
store.set(selectedDepartAtom, prev => ({
...prev,
...(isAdd ? res.data : {})
}))
get(queryClientAtom).invalidateQueries({ queryKey: [ 'departTree', get(departPageAtom) ] }).then()
if (isAdd) {
store.set(selectedDepartAtom, prev => ({
...prev,
id: res.data.id
}))
}
get(queryClientAtom).invalidateQueries({ queryKey: [ 'departTree' ] }).then()
} }
} }
}) })
const deleteDepartAtom = atomWithMutation<IApiResult, number[]>((get) => {
export const deleteDepartAtom = atomWithMutation<IApiResult, number[]>((get) => {
return { return {
mutationKey: [ 'deleteDepart', get(batchIdsAtom) ], mutationKey: [ 'deleteDepart', get(batchIdsAtom) ],
@ -71,19 +75,10 @@ const deleteDepartAtom = atomWithMutation<IApiResult, number[]>((get) => {
onSuccess: () => { onSuccess: () => {
message.success(t('message.deleteSuccess', '删除成功')) message.success(t('message.deleteSuccess', '删除成功'))
store.set(batchIdsAtom, []) store.set(batchIdsAtom, [])
get(queryClientAtom).invalidateQueries({ queryKey: [ 'departTree', get(departPageAtom) ] }).then()
get(queryClientAtom).invalidateQueries({ queryKey: [ 'departTree' ] }).then()
} }
} }
}) })
export const useDepartStore = () => ({
defaultDepart,
departPageAtom,
selectedDepartAtom,
departTreeAtom,
deleteDepartAtom,
batchIdsAtom,
saveOrUpdateDepartAtom,
})

116
src/pages/system/menus/components/MenuTree.tsx

@ -7,76 +7,78 @@ import { batchIdsAtom, menuDataAtom, selectedMenuAtom } from '../store.ts'
import { FormInstance } from 'antd/lib' import { FormInstance } from 'antd/lib'
import { useAtomValue } from 'jotai/index' import { useAtomValue } from 'jotai/index'
import { TreeNodeRender } from './TreeNodeRender.tsx' import { TreeNodeRender } from './TreeNodeRender.tsx'
import { useRef } from 'react'
import { useEffect, useRef } from 'react'
import { flattenTree } from '@/utils' import { flattenTree } from '@/utils'
import { useDeepCompareEffect } from 'react-use' import { useDeepCompareEffect } from 'react-use'
const MenuTree = ({ form }: { form: FormInstance }) => { const MenuTree = ({ form }: { form: FormInstance }) => {
const { styles } = useStyle()
const { t } = useTranslation()
const setCurrentMenu = useSetAtom(selectedMenuAtom)
const setIds = useSetAtom(batchIdsAtom)
const { data = [], isLoading } = useAtomValue(menuDataAtom)
const flattenMenusRef = useRef<MenuItem[]>([])
const { styles } = useStyle()
const { t } = useTranslation()
const setCurrentMenu = useSetAtom(selectedMenuAtom)
const setIds = useSetAtom(batchIdsAtom)
const { data = [], isLoading } = useAtomValue(menuDataAtom)
const flattenMenusRef = useRef<MenuItem[]>([])
useDeepCompareEffect(() => {
useDeepCompareEffect(() => {
if (isLoading) return
if (isLoading) return
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore array
if (data.length) {
// @ts-ignore flattenTree
flattenMenusRef.current = flattenTree<MenuItem[]>(data as any)
// console.log(flattenMenusRef.current)
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore array
if (data.length) {
// @ts-ignore flattenTree
flattenMenusRef.current = flattenTree<MenuItem[]>(data as any)
// console.log(flattenMenusRef.current)
}
return () => {
setCurrentMenu({} as MenuItem)
setIds([])
}
}, [ data, isLoading ])
}, [ data, isLoading ])
useEffect(() => {
return () => {
setCurrentMenu({} as MenuItem)
setIds([])
}
}, [])
const renderEmpty = () => {
if ((data as any).length > 0 || isLoading) return null
return <Empty description={t('message.emptyDataAdd', '暂无数据,点击添加')}/>
}
const renderEmpty = () => {
if ((data as any).length > 0 || isLoading) return null
return <Empty description={t('message.emptyDataAdd', '暂无数据,点击添加')}/>
}
return (
<>
<Spin spinning={isLoading} style={{ minHeight: 200 }}>
{
renderEmpty()
}
<Tree.DirectoryTree
className={styles.tree}
treeData={data as any}
defaultExpandAll={true}
// draggable={true}
titleRender={(node) => {
return (<TreeNodeRender node={node as any} form={form}/>)
}}
fieldNames={{
title: 'title',
key: 'id'
}}
onSelect={(item) => {
const current = flattenMenusRef.current?.find((menu) => menu.id === item[0])
setCurrentMenu(current as MenuItem)
form.setFieldsValue({ ...current })
}}
onCheck={(item) => {
setIds(item as number[])
}}
checkable={true}
showIcon={false}
/>
</Spin>
</>
)
return (
<>
<Spin spinning={isLoading} style={{ minHeight: 200 }}>
{
renderEmpty()
}
<Tree.DirectoryTree
className={styles.tree}
treeData={data as any}
defaultExpandAll={true}
// draggable={true}
titleRender={(node) => {
return (<TreeNodeRender node={node as any} form={form}/>)
}}
fieldNames={{
title: 'title',
key: 'id'
}}
onSelect={(item) => {
const current = flattenMenusRef.current?.find((menu) => menu.id === item[0])
setCurrentMenu(current as MenuItem)
form.setFieldsValue({ ...current })
}}
onCheck={(item) => {
setIds(item as number[])
}}
checkable={true}
showIcon={false}
/>
</Spin>
</>
)
} }
export default MenuTree export default MenuTree

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

@ -62,11 +62,14 @@ export const saveOrUpdateMenuAtom = atomWithMutation<IApiResult, IMenu>((get) =>
onSuccess: (res) => { onSuccess: (res) => {
const isAdd = !!res.data?.id const isAdd = !!res.data?.id
message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功')) message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功'))
const menu = get(selectedMenuAtom)
store.set(selectedMenuAtom, {
...menu,
id: res.data?.id
})
if(isAdd) {
const menu = get(selectedMenuAtom)
store.set(selectedMenuAtom, {
...menu,
id: res.data?.id
})
}
//更新列表 //更新列表
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore fix // @ts-ignore fix

Loading…
Cancel
Save