import { useState } from "react"; // @mui import { Button, ClickAwayListener, IconButton, Input, InputAdornment, Slide, } from "@mui/material"; import { styled } from "@mui/material/styles"; // utils import { bgBlur } from "@/utils/cssStyles"; // component import Iconify from "@/components/iconify"; import { doFetch } from "@/utils/doFetch"; import { useModel } from "@umijs/max"; import { useRequest } from "ahooks"; import { Image, List, Skeleton, Tabs, Tag } from "antd"; import { Scrollbars } from "react-custom-scrollbars"; // ---------------------------------------------------------------------- const HEADER_MOBILE = 64; const HEADER_DESKTOP = 64; const StyledSearchbar = styled("div")(({ theme }) => ({ ...bgBlur({ color: theme.palette.background.default }), top: 0, left: 0, zIndex: 99, width: "100%", display: "flex", position: "absolute", alignItems: "center", height: HEADER_MOBILE, padding: theme.spacing(0, 2), boxShadow: theme.customShadows.z8, [theme.breakpoints.up("md")]: { height: HEADER_DESKTOP, padding: theme.spacing(0, 2), }, })); const StyledSearchcontent = styled("div")(({ theme }) => ({ background: "rgba(255,255,255,1)", top: HEADER_MOBILE + 12, left: 0, right: 0, zIndex: 99, margin: "auto", width: "calc(100% - 24px)", display: "flex", position: "absolute", alignItems: "center", height: "calc(100vh - 90px)", padding: theme.spacing(0, 2), boxShadow: theme.customShadows.z8, borderRadius: 12, [theme.breakpoints.up("md")]: { height: "calc(100vh - 90px)", padding: theme.spacing(0, 2), }, })); export default function Searchbar() { const [open, setOpen] = useState(false); const [search, setsearch] = useState({ name: "", type: "0", }); const { initialState: { currentUser, curitem }, setInitialState, } = useModel("@@initialState"); const userType = currentUser?.type ?? 1; const handleOpen = () => { setOpen(!open); }; const handleClose = () => { setOpen(false); setsearch({ name: "", type: "0", }); }; let { data, loading } = useRequest( async () => { if(!open) return; let res = await doFetch({ url: "/system/searchAll", params: { ...search }, }); return res?.data?.dataList ?? []; }, { debounceWait: 400, refreshDeps: [search], } ); const items = userType === 1 ? [ { key: "0", label: `全部`, children: ( <div className="diysearch"> <List className="demo-loadmore-list" loading={loading} itemLayout="horizontal" dataSource={data} renderItem={(item) => ( <List.Item actions={[ <Tag color={ (item.type === 1 && "#f50") || (item.type === 2 && "#2db7f5") || (item.type === 3 && "#87d068") || (item.type === 4 && "#108ee9") } > {item.typeName} </Tag>, ]} > <Skeleton avatar title={false} loading={item.loading} active > <List.Item.Meta avatar={ <Image src={item?.picUrl ?? DEFAULT_HEAD_IMG} width={36} height={36} style={{ borderRadius: 6 }} /> } title={<a>{item.name} </a>} description={ <div> {item?.type === 4 && `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} {item?.label} </div> } /> <div> {item?.type === 4 && `${item?.startTime}-${item?.endTime}`} </div> </Skeleton> </List.Item> )} /> </div> ), }, { key: "1", label: `课程`, children: ( <div className="diysearch"> <List className="demo-loadmore-list" loading={loading} itemLayout="horizontal" dataSource={data} renderItem={(item) => ( <List.Item actions={[ <Tag color={ (item.type === 1 && "#f50") || (item.type === 2 && "#2db7f5") || (item.type === 3 && "#87d068") || (item.type === 4 && "#108ee9") } > {item.typeName} </Tag>, ]} > <Skeleton avatar title={false} loading={item.loading} active > <List.Item.Meta avatar={ <Image src={item?.picUrl ?? DEFAULT_HEAD_IMG} width={36} height={36} style={{ borderRadius: 6 }} /> } title={<a>{item.name} </a>} description={ <div> {item?.type === 4 && `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} {item?.label} </div> } /> <div> {item?.type === 4 && `${item?.startTime}-${item?.endTime}`} </div> </Skeleton> </List.Item> )} /> </div> ), }, { key: "2", label: `教师`, children: ( <div className="diysearch"> <List className="demo-loadmore-list" loading={loading} itemLayout="horizontal" dataSource={data} renderItem={(item) => ( <List.Item actions={[ <Tag color={ (item.type === 1 && "#f50") || (item.type === 2 && "#2db7f5") || (item.type === 3 && "#87d068") || (item.type === 4 && "#108ee9") } > {item.typeName} </Tag>, ]} > <Skeleton avatar title={false} loading={item.loading} active > <List.Item.Meta avatar={ <Image src={item?.picUrl ?? DEFAULT_HEAD_IMG} width={36} height={36} style={{ borderRadius: 6 }} /> } title={<a>{item.name} </a>} description={ <div> {item?.type === 4 && `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} {item?.label} </div> } /> <div> {item?.type === 4 && `${item?.startTime}-${item?.endTime}`} </div> </Skeleton> </List.Item> )} /> </div> ), }, { key: "3", label: `学生`, children: ( <div className="diysearch"> <List className="demo-loadmore-list" loading={loading} itemLayout="horizontal" dataSource={data} renderItem={(item) => ( <List.Item actions={[ <Tag color={ (item.type === 1 && "#f50") || (item.type === 2 && "#2db7f5") || (item.type === 3 && "#87d068") || (item.type === 4 && "#108ee9") } > {item.typeName} </Tag>, ]} > <Skeleton avatar title={false} loading={item.loading} active > <List.Item.Meta avatar={ <Image src={item?.picUrl ?? DEFAULT_HEAD_IMG} width={36} height={36} style={{ borderRadius: 6 }} /> } title={<a>{item.name} </a>} description={ <div> {item?.type === 4 && `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} {item?.label} </div> } /> <div> {item?.type === 4 && `${item?.startTime}-${item?.endTime}`} </div> </Skeleton> </List.Item> )} /> </div> ), }, ] : [ { key: "0", label: `全部`, children: ( <div className="diysearch"> <List className="demo-loadmore-list" loading={loading} itemLayout="horizontal" dataSource={data??[]} renderItem={(item) => ( <List.Item actions={[ <Tag color={ (item.type === 1 && "#f50") || (item.type === 2 && "#2db7f5") || (item.type === 3 && "#87d068") || (item.type === 4 && "#108ee9") } > {item.typeName} </Tag>, ]} > <Skeleton avatar title={false} loading={item.loading} active > <List.Item.Meta avatar={ <Image src={item?.picUrl ?? DEFAULT_HEAD_IMG} width={36} height={36} style={{ borderRadius: 6 }} /> } title={<a>{item.name} </a>} description={ <div> {item?.type === 4 && `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} {item?.label} </div> } /> <div> {item?.type === 4 && `${item?.startTime??"未开始"}-${item?.endTime}`} </div> </Skeleton> </List.Item> )} /> </div> ), }, ]; // [ // { // key: "0", // label: `全部`, // children: ( // <div className="diysearch"> // <List // className="demo-loadmore-list" // loading={loading} // itemLayout="horizontal" // dataSource={data} // renderItem={(item) => ( // <List.Item // actions={[ // <Tag // color={ // (item.type === 1 && "#f50") || // (item.type === 2 && "#2db7f5") || // (item.type === 3 && "#87d068") || // (item.type === 4 && "#108ee9") // } // > // {item.typeName} // </Tag>, // ]} // > // <Skeleton // avatar // title={false} // loading={item.loading} // active // > // <List.Item.Meta // avatar={ // <Image // src={item?.picUrl ?? DEFAULT_HEAD_IMG} // width={36} // height={36} // style={{ borderRadius: 6 }} // /> // } // title={<a>{item.name} </a>} // description={ // <div> // {item?.type === 4 && // `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} // {item?.label} // </div> // } // /> // <div> // {item?.type === 4 && // `${item?.startTime}-${item?.endTime}`} // </div> // </Skeleton> // </List.Item> // )} // /> // </div> // ), // }, // { // key: "1", // label: `课程`, // children: ( // <div className="diysearch"> // <List // className="demo-loadmore-list" // loading={loading} // itemLayout="horizontal" // dataSource={data} // renderItem={(item) => ( // <List.Item // actions={[ // <Tag // color={ // (item.type === 1 && "#f50") || // (item.type === 2 && "#2db7f5") || // (item.type === 3 && "#87d068") || // (item.type === 4 && "#108ee9") // } // > // {item.typeName} // </Tag>, // ]} // > // <Skeleton // avatar // title={false} // loading={item.loading} // active // > // <List.Item.Meta // avatar={ // <Image // src={item?.picUrl ?? DEFAULT_HEAD_IMG} // width={36} // height={36} // style={{ borderRadius: 6 }} // /> // } // title={<a>{item.name} </a>} // description={ // <div> // {item?.type === 4 && // `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} // {item?.label} // </div> // } // /> // <div> // {item?.type === 4 && // `${item?.startTime}-${item?.endTime}`} // </div> // </Skeleton> // </List.Item> // )} // /> // </div> // ), // }, // { // key: "2", // label: `教师`, // children: ( // <div className="diysearch"> // <List // className="demo-loadmore-list" // loading={loading} // itemLayout="horizontal" // dataSource={data} // renderItem={(item) => ( // <List.Item // actions={[ // <Tag // color={ // (item.type === 1 && "#f50") || // (item.type === 2 && "#2db7f5") || // (item.type === 3 && "#87d068") || // (item.type === 4 && "#108ee9") // } // > // {item.typeName} // </Tag>, // ]} // > // <Skeleton // avatar // title={false} // loading={item.loading} // active // > // <List.Item.Meta // avatar={ // <Image // src={item?.picUrl ?? DEFAULT_HEAD_IMG} // width={36} // height={36} // style={{ borderRadius: 6 }} // /> // } // title={<a>{item.name} </a>} // description={ // <div> // {item?.type === 4 && // `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} // {item?.label} // </div> // } // /> // <div> // {item?.type === 4 && // `${item?.startTime}-${item?.endTime}`} // </div> // </Skeleton> // </List.Item> // )} // /> // </div> // ), // }, // { // key: "3", // label: `学生`, // children: ( // <div className="diysearch"> // <List // className="demo-loadmore-list" // loading={loading} // itemLayout="horizontal" // dataSource={data} // renderItem={(item) => ( // <List.Item // actions={[ // <Tag // color={ // (item.type === 1 && "#f50") || // (item.type === 2 && "#2db7f5") || // (item.type === 3 && "#87d068") || // (item.type === 4 && "#108ee9") // } // > // {item.typeName} // </Tag>, // ]} // > // <Skeleton // avatar // title={false} // loading={item.loading} // active // > // <List.Item.Meta // avatar={ // <Image // src={item?.picUrl ?? DEFAULT_HEAD_IMG} // width={36} // height={36} // style={{ borderRadius: 6 }} // /> // } // title={<a>{item.name} </a>} // description={ // <div> // {item?.type === 4 && // `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} // {item?.label} // </div> // } // /> // <div> // {item?.type === 4 && // `${item?.startTime}-${item?.endTime}`} // </div> // </Skeleton> // </List.Item> // )} // /> // </div> // ), // }, // { // key: "4", // label: `实训`, // children: ( // <div className="diysearch"> // <List // className="demo-loadmore-list" // loading={loading} // itemLayout="horizontal" // dataSource={data} // renderItem={(item) => ( // <List.Item // actions={[ // <Tag // color={ // (item.type === 1 && "#f50") || // (item.type === 2 && "#2db7f5") || // (item.type === 3 && "#87d068") || // (item.type === 4 && "#108ee9") // } // > // {item.typeName} // </Tag>, // ]} // > // <Skeleton // avatar // title={false} // loading={item.loading} // active // > // <List.Item.Meta // avatar={ // <Image // src={item?.picUrl ?? DEFAULT_HEAD_IMG} // width={36} // height={36} // style={{ borderRadius: 6 }} // /> // } // title={<a>{item.name} </a>} // description={ // <div> // {item?.type === 4 && // `${item.sectionNum}课时/${item.experimentNum}实验`}{" "} // {item?.label} // </div> // } // /> // <div> // {item?.type === 4 && // `${item?.startTime}-${item?.endTime}`} // </div> // </Skeleton> // </List.Item> // )} // /> // </div> // ), // }, // ]; return ( <ClickAwayListener onClickAway={handleClose}> <div> {!open && ( <IconButton onClick={handleOpen}> <Iconify icon="eva:search-fill" /> </IconButton> )} <Slide direction="down" in={search?.name && open} mountOnEnter unmountOnExit > <StyledSearchcontent> <Scrollbars thumbMinSize={10} autoHide style={{ width: "100%", height: "100%", }} hideTracksWhenNotNeeded > <Tabs activeKey={search?.type} items={items} centered onChange={(e) => { setsearch((s) => ({ ...s, type: e, })); }} /> </Scrollbars> </StyledSearchcontent> </Slide> <Slide direction="down" in={open} mountOnEnter unmountOnExit> <StyledSearchbar> <Input autoFocus fullWidth disableUnderline placeholder="全局搜索" startAdornment={ <InputAdornment position="start"> <Iconify icon="eva:search-fill" sx={{ color: "text.disabled", width: 20, height: 20 }} /> </InputAdornment> } sx={{ mr: 1, fontWeight: "fontWeightBold" }} value={search?.name} onChange={(e) => { setsearch((s) => ({ ...s, name: e.target.value, })); }} /> <Button variant="contained" color="inherit" onClick={handleClose}> 关闭 </Button> </StyledSearchbar> </Slide> </div> </ClickAwayListener> ); }