搜索功能完成

This commit is contained in:
Pan Qiancheng 2024-10-18 17:30:37 +08:00
parent 289e739f80
commit d4d882cd65
10 changed files with 198 additions and 24 deletions

View File

@ -4,16 +4,21 @@ import { useHomeContext } from './context/homeContext';
import EssaysByLabel from './essays/byLabel';
const FrontendBody = () => {
const { selectedLabelId, selectedCategoryId } = useHomeContext();
const { selectedLabelId, selectedCategoryId, searchParam } =
useHomeContext();
return (
<div>
{!selectedLabelId ? (
<Essays oakPath='essays' categoryId={selectedCategoryId!}></Essays>
<Essays
oakPath='essays'
categoryId={selectedCategoryId!}
searchParam={searchParam}
></Essays>
) : (
<EssaysByLabel
oakPath='essaysByLabel'
oakId={selectedLabelId!}
oakId={selectedLabelId!}
></EssaysByLabel>
)}
</div>

View File

@ -1,6 +1,8 @@
import React from 'react';
import { createContext } from 'react';
type SearchType = 'title' | 'content';
type HomeContextType = {
// label selection
selectedLabelId: string | undefined;
@ -8,6 +10,15 @@ type HomeContextType = {
// category selection
selectedCategoryId: string | undefined;
setSelectedCategoryId: (categoryId: string | null) => void;
// search
searchParam: {
searchType: SearchType;
searchText: string;
};
setSearchParam: (param: {
searchType?: SearchType;
searchText?: string;
}) => void;
};
const HomeContext = createContext<HomeContextType | undefined>(undefined);
@ -17,6 +28,10 @@ export const HomeProvider: React.FC<{
}> = ({ children }) => {
const [selectedLabelId, _setSelectedLabelId] = React.useState<string>();
const setSelectedLabelId = (tagId: string | null) => {
// 清空搜索
setSearchParam({
searchText: '',
});
_setSelectedLabelId(tagId || undefined);
};
@ -24,9 +39,37 @@ export const HomeProvider: React.FC<{
React.useState<string>();
const setSelectedCategoryId = (categoryId: string | null) => {
_setSelectedLabelId(undefined);
// 清空搜索
setSearchParam({
searchText: '',
});
_setSelectedCategoryId(categoryId || undefined);
};
// search
const [searchParam, _setSearchParam] = React.useState<{
searchType: SearchType;
searchText: string;
}>({
searchType: 'title',
searchText: '',
});
const setSearchParam = (param: {
searchType?: SearchType;
searchText?: string;
}) => {
// 如果有搜索值则清空选择的label和category
if (param.searchText) {
setSelectedLabelId(null);
setSelectedCategoryId(null);
}
_setSearchParam({
searchType: param.searchType || 'title',
searchText: param.searchText || '',
});
};
return (
<HomeContext.Provider
value={{
@ -34,6 +77,8 @@ export const HomeProvider: React.FC<{
setSelectedLabelId,
selectedCategoryId,
setSelectedCategoryId,
searchParam,
setSearchParam,
}}
>
{children}

View File

@ -30,6 +30,7 @@ const EssaysByLabel = (
item={item}
navigateTo={navigateTo}
t={t}
key={item.id}
/>
);
})}

View File

@ -45,6 +45,44 @@ export default OakComponent({
},
},
],
listeners: {
searchParam(prev, next) {
// 如果searchParam变化则重新获取数据
if (prev.searchParam !== next.searchParam) {
this.setNamedFilters(
[
{
// 如果存在searchParam则按照searchParam过滤
filter() {
if (!next.searchParam.searchText) {
return {};
}
switch (next.searchParam.searchType) {
case 'title':
return {
title: {
$includes:
next.searchParam.searchText,
},
};
case 'content':
return {
$text: {
$search:
next.searchParam.searchText,
},
};
default:
return {};
}
},
'#name': 'searchParam',
},
]
);
}
},
},
formData({ data }) {
return {
list: data.map((item) => {

View File

@ -212,6 +212,26 @@ const i18ns: I18n[] = [
"categories": "分类"
}
},
{
id: "6fd812246bb915f692124fc05bb9ffd4",
namespace: "new-demo-c-frontend-home-labels-byCategory",
language: "zh-CN",
module: "new-demo",
position: "src/components/frontend/home/labels/byCategory",
data: {
"labelsByCategory": "当前分类下的标签"
}
},
{
id: "784729f3cc436498cf82829030273cdb",
namespace: "new-demo-c-frontend-home-labels",
language: "zh-CN",
module: "new-demo",
position: "src/components/frontend/home/labels",
data: {
"labelsAll": "全部标签"
}
},
{
id: "66807ab52114b7a250380d6a509aea19",
namespace: "new-demo-l-common",

View File

@ -1,24 +1,22 @@
import FrontendHeader from '@project/components/frontend/home/FrontendHeader';
import React from 'react';
import Styles from './styles.module.less';
import { HomeProvider } from '@project/components/frontend/home/context/homeContext';
import FrontendBody from '@project/components/frontend/home/FrontendBody';
const Home = () => {
return (
<HomeProvider>
<div className={Styles.body}>
<div className={Styles.header}>
<FrontendHeader />
</div>
<div className={Styles.content}>
<FrontendBody />
</div>
<div className={Styles.footer}>
<h1>Footer</h1>
</div>
<div className={Styles.body}>
<div className={Styles.header}>
<FrontendHeader />
</div>
</HomeProvider>
<div className={Styles.content}>
<FrontendBody />
</div>
<div className={Styles.footer}>
<h1>Footer</h1>
</div>
</div>
);
};

View File

@ -1,9 +1,10 @@
import React, { useEffect, useState } from 'react';
import Styles from './web.pc.module.less';
import { Button, Space, Modal } from 'antd';
import { Button, Space, Modal, Input, Select } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import useFeatures from '@project/hooks/useFeatures';
import ConsoleAvatar from '../consoleAvatar';
import { useHomeContext } from '@project/components/frontend/home/context/homeContext';
export default function render() {
const features = useFeatures();
@ -19,6 +20,27 @@ export default function render() {
});
}, []);
const { searchParam, setSearchParam } = useHomeContext();
const selectBefore = (
<Select
defaultValue='title'
className={Styles.select}
onChange={(value) => {
setSearchParam({
searchType: value as 'title' | 'content',
});
}}
>
<Select.Option value='title'>
{features.locales.t('title')}
</Select.Option>
<Select.Option value='content'>
{features.locales.t('content')}
</Select.Option>
</Select>
);
return (
<div className={Styles.header}>
<div
@ -45,7 +67,24 @@ export default function render() {
{features.locales.t('welcome')} {user?.name || user?.nickname}
</div> */}
</div>
<div style={{ flex: 1 }} />
<div className={Styles.search} >
{/* 搜索框 */}
<Space.Compact className={Styles.input}>
<Input
addonBefore={selectBefore}
placeholder={features.locales.t('searchPlaceholder')}
value={searchParam.searchText}
onChange={(e) => {
setSearchParam({
searchText: e.target.value,
});
}}
/>
<Button type='primary' className={Styles.btn}>
{features.locales.t('search')}
</Button>
</Space.Compact>
</div>
<div className={Styles.right}>
{user ? (
<>

View File

@ -3,5 +3,9 @@
"console": "控制台",
"logout": "退出",
"close": "关闭",
"login": "登录"
"login": "登录",
"searchPlaceholder": "搜索文章",
"title": "标题",
"content": "内容",
"search": "搜索"
}

View File

@ -55,4 +55,25 @@
.right {
margin-right: 16px;
}
.search {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
.input {
width: 30%;
min-width: 300px;
}
.btn {
background-color: #6661f5;
}
}
}
.select {
width: 100px;
}

View File

@ -1,15 +1,18 @@
import React from 'react';
import { Outlet, Route } from 'react-router-dom';
import FrontendHeader from '../../components/frontendHeader';
import Styles from './styles.module.less'
import Styles from './styles.module.less';
import { HomeProvider } from '@project/components/frontend/home/context/homeContext';
function Frontend() {
return (
<div>
<FrontendHeader />
<div className={Styles.body}>
<Outlet />
</div>
<HomeProvider>
<FrontendHeader />
<div className={Styles.body}>
<Outlet />
</div>
</HomeProvider>
</div>
);
}