Skip to content

Commit 9d9c413

Browse files
committed
优化组织选择框
1 parent c77bb29 commit 9d9c413

7 files changed

Lines changed: 67 additions & 88 deletions

File tree

src/components/group-tree-select-popver.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,20 @@
22
import axios from "@/lib/axios";
33
import { useUserStore } from '@/store';
44
import { useEffect, useState } from "react";
5-
import { NodeApi } from "react-arborist";
65
import { TreeNode, TreeSelectPopover } from './tree-select';
7-
export function GroupTreeSelectPopover(props: { onSelect: (node: NodeApi<TreeNode>[]) => void }) {
8-
const { onSelect } = props
9-
const [arrayData, setArrayData] = useState<TreeNode[]>([{id:'00',name:'00',parentId:'',level:0,order:0}]);
10-
const [choose, setChoose] = useState<{id:string,name:string}>({id:'00',name:'00'});
6+
export function GroupTreeSelectPopover( props: {onChange:(node:TreeNode[])=>void}) {
7+
const [arrayData, setArrayData] = useState<TreeNode[]>([{id:'',name:'...',parentId:'',level:0,order:0}]);
118
const {userInfo}=useUserStore();
9+
const {onChange}=props;
1210
const groupId=userInfo?.group;
11+
const [choose, setChoose] = useState<TreeNode>(arrayData[0]);
1312
useEffect(()=>{
1413
axios.get('/common/groups/'+groupId).then(res=>{
15-
setArrayData(res.data);
16-
setChoose({id:res.data[0].id,name:res.data[0].name});
14+
setArrayData(res.data.data);
15+
setChoose(res.data.data[0]);
1716
})
1817
},[groupId])
1918

2019
return (
21-
<TreeSelectPopover data={arrayData} choose={choose}
22-
onSelect={(node) => {
23-
if (node.length > 0) {
24-
onSelect(node);
25-
}
26-
}} />)
20+
<TreeSelectPopover onChange={onChange} data={arrayData} choose={choose} setChoose={setChoose} />)
2721
}

src/components/tree-select.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from "@/components/ui/popover";
77
import { ChevronDown, ChevronRight } from "lucide-react";
88
import { useEffect, useRef, useState } from "react";
9-
import { NodeApi, NodeRendererProps, Tree, TreeApi } from "react-arborist";
9+
import { NodeRendererProps, Tree, TreeApi } from "react-arborist";
1010
import { MdRadioButtonChecked, MdRadioButtonUnchecked } from "react-icons/md";
1111
export type TreeNode = {
1212
id: string;
@@ -77,8 +77,8 @@ function Node({ node, style, dragHandle }: NodeRendererProps<any>) {
7777
);
7878
}
7979

80-
export function TreeSelect(props: { onSelect: (node: NodeApi<TreeNode>[]) => void,choose:{id:string,name:string},data:TreeNode[] }) {
81-
const { onSelect,choose,data } = props;
80+
export function TreeSelect(props: {choose:TreeNode, setChoose: (choose:TreeNode) => void,data:TreeNode[],onChange:(node:TreeNode[])=>void }) {
81+
const {choose,setChoose, data,onChange } = props;
8282
const treeData: TreeNode[] = buildTree(data);
8383
const rowHeight = 36;
8484
const [height, setHeight] = useState(100);
@@ -94,14 +94,12 @@ export function TreeSelect(props: { onSelect: (node: NodeApi<TreeNode>[]) => voi
9494
changeHeight();
9595
return () => cancelAnimationFrame(animationFrame);
9696
}, [treeRef]);
97-
98-
9997
return (
10098
<Tree
10199
ref={treeRef}
102100
initialData={treeData}
103101
openByDefault={true}
104-
selection={choose.id}
102+
selection={choose?.id}
105103
indent={24}
106104
height={height}
107105
width={300}
@@ -110,21 +108,25 @@ export function TreeSelect(props: { onSelect: (node: NodeApi<TreeNode>[]) => voi
110108
paddingBottom={10}
111109
children={Node}
112110
onSelect={(node) => {
113-
onSelect(node);
111+
if(node.length>0){
112+
setChoose(node[0].data);
113+
onChange(treeRef.current?.selectedNodes.map((item)=>item.data)||[]);
114+
}
114115
}}
115116
/>
116117
);
117118
}
118119

119-
export function TreeSelectPopover(props: { onSelect: (node: NodeApi<TreeNode>[]) => void,data:TreeNode[] ,choose:{id:string,name:string}}) {
120-
const {data,choose}=props
120+
export function TreeSelectPopover(props: {data:TreeNode[],onChange:(node:TreeNode[])=>void,choose:TreeNode,setChoose: (choose:TreeNode) => void }) {
121+
const {data,onChange,choose,setChoose}=props
122+
// const [choose, setChoose] = useState<TreeNode>(data[0]);
121123
return (
122124
<Popover>
123125
<PopoverTrigger asChild>
124-
<Button variant="outline" className="w-[300px]">{choose.name}</Button>
126+
<Button variant="outline" className="w-[200px]">{choose?.name}</Button>
125127
</PopoverTrigger>
126128
<PopoverContent className="w-auto">
127-
<TreeSelect {...props} choose={choose} data={data} />
129+
<TreeSelect choose={choose} data={data} setChoose={setChoose} onChange={onChange}/>
128130
</PopoverContent>
129131
</Popover>
130132
);

src/lib/axios.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ instance.interceptors.request.use(
3030
);
3131
instance.interceptors.response.use(
3232
(response) => {
33-
const { data } = response;
33+
const data = response.data;
3434
if (data.code !== 200) {
3535
notify.error(data.message || "请求错误");
3636
return Promise.reject(data);
3737
}
38-
return data;
38+
return response;
3939
},
4040
(error:AxiosError) => {
4141
notify.error(error.message || "网络异常");

src/mock/system/user.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const handlers = [
8080
}}
8181
)
8282
}),
83-
http.delete<{ id: string }>('/api/system/users/:id', async ({ request,params}) => {
83+
http.delete<{ id: string },never>('/api/system/users/:id', async ({ request,params}) => {
8484
const locale = request.headers.get("locale") || "zh";
8585
const id = params.id;
8686
console.log(id);

src/pages/login/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default function Login({
5656
axios
5757
.post('user/login', values)
5858
.then((res) => {
59-
const { status, msg, field, token } = res.data;
59+
const { status, msg, field, token } = res.data.data;
6060
if (status === 'ok') {
6161
login(token);
6262
navigate('/');

src/pages/system/user/index.tsx

Lines changed: 41 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ import {
77
DropdownMenuContent,
88
DropdownMenuItem,
99
DropdownMenuLabel,
10-
DropdownMenuRadioGroup,
11-
DropdownMenuRadioItem,
1210
DropdownMenuSeparator,
13-
DropdownMenuTrigger,
11+
DropdownMenuTrigger
1412
} from "@/components/ui/dropdown-menu";
1513
import { Input } from "@/components/ui/input";
14+
import {
15+
Select,
16+
SelectContent,
17+
SelectItem,
18+
SelectTrigger,
19+
SelectValue,
20+
} from "@/components/ui/select";
1621
import {
1722
Table,
1823
TableBody,
@@ -40,7 +45,6 @@ import { useEffect, useState } from "react";
4045
import { useIntl } from "react-intl";
4146
import { toast } from "sonner";
4247

43-
4448
export default function User() {
4549
const intl = useIntl();
4650
const statusEnum = new Map([["0", "停用"], ["1", "启用"]]);
@@ -50,21 +54,21 @@ export default function User() {
5054
filterField: string
5155
filterValue: string
5256
group: string
53-
groupName:string
57+
groupName: string
5458
}
5559
const [params, setParams] = useState({
5660
page: 1,
5761
size: 10,
5862
filterField: 'name',
5963
filterValue: '',
6064
group: '',
61-
groupName:''
65+
groupName: ''
6266
} as TableParams);
6367

6468
useEffect(() => {
6569
function fetchData(params: TableParams) {
6670
axios.post("/system/users", params).then(res => {
67-
setData(res.data);
71+
setData(res.data.data);
6872
})
6973
}
7074
fetchData(params); // 初次加载
@@ -89,10 +93,8 @@ export default function User() {
8993
}
9094
function handleDelete(row: User) {
9195
axios.delete("/system/users/" + row.id).then(res => {
92-
if (res.data.code === "S") {
93-
setParams({ ...params, page: 1 });
94-
toast.success(res.data.message);
95-
}
96+
setParams({ ...params, page: 1 });
97+
toast.success(res.data.message);
9698
})
9799

98100
}
@@ -249,56 +251,37 @@ export default function User() {
249251
rowSelection,
250252
},
251253
})
252-
253254
return (
254255
<div className="w-full">
255-
<div className="flex items-center py-3">
256+
<div className="flex items-center py-3 gap-4">
256257
<GroupTreeSelectPopover
257-
onSelect={(node) => {
258-
if(node.length>0){
259-
setParams({ ...params, group: node[0].data.id,groupName:node[0].data.name })
260-
}
261-
}} />
262-
<DropdownMenu>
263-
<DropdownMenuTrigger asChild>
264-
<Button variant="outline" className="ml-auto">
265-
{table
266-
.getAllColumns().filter((column) => column.id == params.filterField).map((column) => {
267-
const header = column.columnDef.header;
268-
const meta = column.columnDef.meta as { title: string };
269-
const headerText = typeof header === 'string' || typeof header === 'number' ? header : meta.title;
270-
return (
271-
<div key={column.id}>
272-
{headerText}
273-
</div>
274-
)
275-
})}<ChevronDown />
276-
</Button>
277-
</DropdownMenuTrigger>
278-
<DropdownMenuContent align="start">
279-
<DropdownMenuRadioGroup value={params.filterField} onValueChange={(value) =>
280-
setParams({ ...params, filterField: value })
281-
}>
282-
{table
283-
.getAllColumns()
284-
.filter((column) => !['select', 'actions','groupName'].includes(column.id))
285-
.map((column) => {
286-
const header = column.columnDef.header;
287-
const meta = column.columnDef.meta as { title: string };
288-
const headerText = typeof header === 'string' || typeof header === 'number' ? header : meta.title;
289-
return (
290-
<DropdownMenuRadioItem
291-
key={column.id}
292-
className="capitalize"
293-
value={column.id}
294-
>
295-
{headerText}
296-
</DropdownMenuRadioItem >
297-
)
298-
})}
299-
</DropdownMenuRadioGroup>
300-
</DropdownMenuContent>
301-
</DropdownMenu>
258+
onChange={(node) => {
259+
if (node.length > 0) {
260+
setParams({ ...params, group: node[0].id, groupName: node[0].name })
261+
}
262+
}}
263+
/>
264+
<Select
265+
onValueChange={(value) =>
266+
setParams({ ...params, filterField: value })
267+
} defaultValue={params.filterField}>
268+
<SelectTrigger className="flex items-center">
269+
<SelectValue placeholder="FilterField" />
270+
</SelectTrigger>
271+
<SelectContent>
272+
{table
273+
.getAllColumns()
274+
.filter((column) => ['name', 'username', 'email', 'phone'].includes(column.id))
275+
.map((column) => {
276+
const header = column.columnDef.header;
277+
const meta = column.columnDef.meta as { title: string };
278+
const headerText = typeof header === 'string' || typeof header === 'number' ? header : meta.title;
279+
return (
280+
<SelectItem key={column.id} value={column.id}>{headerText}</SelectItem>
281+
)
282+
})}
283+
</SelectContent>
284+
</Select>
302285
<Input
303286
placeholder={intl.formatMessage({ id: 'table.filterField' })}
304287
value={params.filterValue}

src/store/user.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const useUserStore = create<GlobalInfo>()((set, get) => ({
4848
try {
4949
// 模拟获取用户信息
5050
const res = await axios.get("/user/userInfo");
51-
if (res.data) {
52-
const userInfo: UserInfo = res.data;
51+
if (res.data.data) {
52+
const userInfo: UserInfo = res.data.data;
5353
userInfo.currentRole = userInfo.defaultRole;
5454
const currentPermission = [
5555
...(userInfo.userPermissions||[]),

0 commit comments

Comments
 (0)