access: 'talenthome' | access: 'talenthome' | ||||
}, | }, | ||||
{ | { | ||||
name: '搜索·职位·企业', | |||||
path: '/talent/search', | |||||
component: './Talent/Search', | |||||
access: 'talentsearch' | |||||
name: '搜索·职位', | |||||
path: '/talent/search/job', | |||||
component: './Talent/Search/Job', | |||||
access: 'talentsearchjob' | |||||
}, | |||||
{ | |||||
name: '搜索·企业', | |||||
path: '/talent/search/company', | |||||
component: './Talent/Search/Company', | |||||
access: 'talentsearchcompany' | |||||
}, | }, | ||||
{ | { | ||||
name: '招聘会', | name: '招聘会', |
</head> | </head> | ||||
<body> | <body> | ||||
<div id="root"></div> | <div id="root"></div> | ||||
<script src="/umi.ebceb906.js"></script> | |||||
<script src="/umi.85104365.js"></script> | |||||
</body> | </body> | ||||
</html> | </html> |
permissions = { | permissions = { | ||||
talent: true, | talent: true, | ||||
talenthome: true, | talenthome: true, | ||||
talentsearch: true, | |||||
talentsearchjob: true, | |||||
talentsearchcompany: true, | |||||
talentfair: true, | talentfair: true, | ||||
talentinformation: true, | talentinformation: true, | ||||
talentdownload: true, | talentdownload: true, |
import { useState, useEffect, useRef } from 'react'; | |||||
import { Link } from '@umijs/max'; | |||||
import { ProList, ProConfigProvider, ProFormCaptcha, ProFormCheckbox, ProFormText, setAlpha, ProForm, ProFormDependency } from '@ant-design/pro-components'; | |||||
import { PhoneOutlined, MailOutlined, EnvironmentOutlined, ArrowRightOutlined, FireOutlined, StarOutlined, PayCircleOutlined } from '@ant-design/icons'; | |||||
import { Space, Tabs, Avatar, Row, Col, Image, message, Card, ConfigProvider, Affix, Tag, Tooltip, Pagination, Flex, Descriptions, Button, Divider } from 'antd'; | |||||
import { Imageprefix } from '@/constants/index' | |||||
import { PostCompanySearch } from '@/services/apis/company'; | |||||
import { GetAdvertscheduleList } from '@/services/apis/advertschedule'; | |||||
import EmptyResult from '@/components/Common/EmptyResult' | |||||
import CommonJob from '@/components/Common/Job' | |||||
interface SearchJobProps { | |||||
getTotal: (value: number) => void, | |||||
searchParams: any, | |||||
} | |||||
const SearchJob: React.FC<SearchJobProps> = ({ searchParams, getTotal }: any) => { | |||||
const [list, setList] = useState<object[]>([]) | |||||
const [advertscheduleList, setAdvertscheduleList] = useState<object[]>([]) | |||||
useEffect(() => { | |||||
GetAdvertscheduleList({ page: 1, pagesize: 4, code: 'wzsylbt' }).then(res => { | |||||
setAdvertscheduleList(res.data.advertschedules) | |||||
}) | |||||
}, []); | |||||
useEffect(() => { | |||||
PostCompanySearch(searchParams).then(res => { | |||||
setList(res.data.jobs) | |||||
getTotal(res.data.total) | |||||
}) | |||||
}, [searchParams]); | |||||
return ( | |||||
<> | |||||
<ConfigProvider theme={{ | |||||
token: { | |||||
colorPrimary: '#19be6e', | |||||
}, components: { | |||||
List: { | |||||
headerBg: '#ffffff', | |||||
} | |||||
}, | |||||
}}> | |||||
<Row gutter={[16, 16]}> | |||||
<Col span={18}> | |||||
{ | |||||
list.length > 0 && list.map((item: any, index: number) => ( | |||||
<> | |||||
<CommonJob item={item}></CommonJob> | |||||
</> | |||||
)) | |||||
} | |||||
{ | |||||
!list || list.length == 0 && <EmptyResult description="没有找到符合条件的职位" /> | |||||
} | |||||
</Col> | |||||
<Col span={6}> | |||||
{ | |||||
advertscheduleList && advertscheduleList.length && advertscheduleList.map((item, index) => ( | |||||
<div style={{ borderRadius: 8, marginBottom: 20 }}> | |||||
<div style={{ | |||||
width: '100%', | |||||
position: 'relative', | |||||
paddingTop: '56.25%', /* 16:9 的比例 */ | |||||
overflow: 'hidden' | |||||
}}> | |||||
<Link to={{ pathname: item.target_url }} target='_blank'> | |||||
<img src={Imageprefix + item.image_url} style={{ | |||||
position: 'absolute', | |||||
top: 0, | |||||
left: 0, | |||||
width: '100%', | |||||
height: '100%', | |||||
borderRadius: 8 | |||||
}} /> | |||||
</Link> | |||||
</div> | |||||
</div> | |||||
)) | |||||
} | |||||
</Col> | |||||
</Row> | |||||
{/* <Flex justify='center' align='center' style={{ margin: '40px 0' }}> | |||||
<Pagination | |||||
hideOnSinglePage | |||||
total={total} | |||||
showTotal={(total) => `总共${total}条`} | |||||
current={page} | |||||
pageSize={pageSize} | |||||
pageSizeOptions={['12', '24', '36']} | |||||
onChange={(page, pageSize) => { | |||||
setPage(page) | |||||
setPageSize(pageSize) | |||||
GetJobseekerRecommendJob({ page: page, pagesize: pageSize, sortby: 'desc' }).then((res: any) => { | |||||
setList(res.data.jobs ? res.data.jobs : [{}, {}]) | |||||
setTotal(res.data.total) | |||||
}) | |||||
}} | |||||
/> | |||||
</Flex> */} | |||||
</ConfigProvider> | |||||
</> | |||||
); | |||||
}; | |||||
export default SearchJob; | |||||
import { useState, useEffect, useRef, Children } from 'react'; | |||||
import { Segmented, ConfigProvider, Flex, Space, Select, Input, Tag, Tabs, Row, Col, Descriptions, InputNumber, Cascader, Popconfirm, Button, Divider, Typography } from 'antd'; | |||||
import { SearchOutlined, CloseOutlined, EnvironmentOutlined, CaretUpOutlined, MenuOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; | |||||
import { LoginForm, ProFormCaptcha, ProFormText, ProFormDependency, PageContainer } from '@ant-design/pro-components'; | |||||
import { useModel, useSearchParams, connect, Link } from 'umi'; | |||||
const cascaderfieldNames = { label: 'name', value: 'id', children: 'children' }; | |||||
interface SearchFilterProps { | |||||
getSearchParams: (value: any) => void, | |||||
keyword: any | |||||
} | |||||
const SearchFilter: React.FC<SearchFilterProps> = ({ dispatch, dictModel, getSearchParams, keyword }: any) => { | |||||
const [showSearch, setShowSearch] = useState<boolean>(false); | |||||
const [openMore, setOpenMore] = useState<boolean>(false); | |||||
const [keywordName, setKeywordName] = useState<string>(keyword ? keyword : ''); | |||||
const [searchJobParams, setSearchJobParams] = useState<object>({ | |||||
keyword: keyword ? keyword : '', | |||||
"location": 0, | |||||
"probation": 0, | |||||
"famous": 0, | |||||
"industry": 0, | |||||
"nature": 0, | |||||
"scale": 0, | |||||
"page": 1, | |||||
"pagesize": 18, | |||||
"sort": "id", | |||||
"sortby": "desc" | |||||
}); | |||||
const isFirstRender = useRef(true); | |||||
useEffect(() => { | |||||
dispatch({ type: 'dictModel/getList', payload: { code: 2009, type: 'setAreaList' } }) | |||||
dispatch({ type: 'dictModel/getList', payload: { code: "2009000100030002", type: 'setXiaolanzhenList' } }) | |||||
dispatch({ type: 'dictModel/getList', payload: { code: "200900010003", type: 'setZhongshanList' } }) | |||||
dispatch({ type: 'dictModel/getList', payload: { code: 2027, type: 'setIndustryPostList' } }) | |||||
dispatch({ type: 'dictModel/getList', payload: { code: 2002, type: 'setNatureList' } }) | |||||
dispatch({ type: 'dictModel/getList', payload: { code: 2003, type: 'setScaleList' } }) | |||||
}, []) | |||||
useEffect(() => { | |||||
dictModel.natureList.unshift({ id: 0, name: '不限', checked: true }); | |||||
}, [dictModel.natureList]) | |||||
useEffect(() => { | |||||
dictModel.scaleList.unshift({ id: 0, name: '不限', checked: true }); | |||||
}, [dictModel.scaleList]) | |||||
// 地区 | |||||
const xiaolanzhenHasUnlimited = dictModel.xiaolanzhenList.some(item => item.name === '不限'); | |||||
const xiaolanzhenHasXiaolan = dictModel.xiaolanzhenList.some(item => item.name === '小榄镇'); | |||||
if (!xiaolanzhenHasXiaolan) { | |||||
dictModel.xiaolanzhenList.unshift({ id: 100004, name: '小榄镇', checked: false }); | |||||
} | |||||
if (!xiaolanzhenHasUnlimited) { | |||||
dictModel.xiaolanzhenList.unshift({ id: 0, name: '不限', checked: true }); | |||||
} | |||||
const zhongshanHasXiaolan = dictModel.zhongshanList.some(item => item.name === '中山市'); | |||||
if (!zhongshanHasXiaolan) { | |||||
dictModel.zhongshanList.unshift({ id: 1000037, name: '中山市', checked: false }); | |||||
dictModel.zhongshanList = dictModel.zhongshanList.filter(item => item.id !== 100004); | |||||
} | |||||
const [areaName, setAreaName] = useState<string>(''); | |||||
const [areaItem, setAreaItem] = useState(null) | |||||
const cityChange = (item, idx) => { | |||||
dictModel.xiaolanzhenList.forEach((i) => { | |||||
i.checked = i.value === item.value; | |||||
}); | |||||
dictModel.zhongshanList.forEach((i) => { | |||||
i.checked = i.value === item.value; | |||||
}); | |||||
if (item.id == 0) { | |||||
dictModel.xiaolanzhenList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
dictModel.zhongshanList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
} | |||||
if (item.id == 100004) { | |||||
dictModel.xiaolanzhenList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
dictModel.zhongshanList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
} else { | |||||
if (dictModel.xiaolanzhenList.some(i => i.id === item.id)) { | |||||
dictModel.xiaolanzhenList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
} | |||||
} | |||||
if (item.id == 1000037) { | |||||
dictModel.xiaolanzhenList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
dictModel.zhongshanList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
} else { | |||||
if (dictModel.zhongshanList.some(i => i.id === item.id)) { | |||||
dictModel.zhongshanList.forEach((i) => { | |||||
i.checked = i.id === item.id; | |||||
}); | |||||
} | |||||
} | |||||
setAreaName(item.name) | |||||
isFirstRender.current = false; | |||||
} | |||||
const searchCityChange = (item, idx) => { | |||||
if (item.id == 0) { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
location: 0 | |||||
})); | |||||
} | |||||
if (item.id == 100004) { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
location: item.id | |||||
})); | |||||
} else { | |||||
if (dictModel.xiaolanzhenList.some(i => i.id === item.id)) { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
location: item.id | |||||
})); | |||||
} | |||||
} | |||||
if (item.id == 1000037) { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
location: item.id | |||||
})); | |||||
} else { | |||||
if (dictModel.zhongshanList.some(i => i.id === item.id)) { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
location: item.id | |||||
})); | |||||
} | |||||
} | |||||
} | |||||
// 行业 | |||||
const [industryTags, setIndustryTags] = useState<string[]>([]); | |||||
const [industryItem, setIndustryItem] = useState<object>(null); | |||||
const industryChange = (tag: object, checked: boolean) => { | |||||
setIndustryItem(tag); | |||||
const nextSelectedTags = checked | |||||
? [tag.name] | |||||
: industryTags.filter((t) => t !== tag.name); | |||||
setIndustryTags(nextSelectedTags); | |||||
}; | |||||
// 企业规模 | |||||
const [natureTags, setNatureTags] = useState<string[]>(['不限']); | |||||
const [natureItem, setNatureItem] = useState<object>(null); | |||||
const natureChange = (tag: object, checked: boolean) => { | |||||
setNatureItem(tag); | |||||
const nextSelectedTags = checked | |||||
? [tag.name] | |||||
: natureTags.filter((t) => t !== tag.name); | |||||
setNatureTags(nextSelectedTags); | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
nature: tag.id | |||||
})); | |||||
}; | |||||
// 规模 | |||||
const [scaleTags, setScaleTags] = useState<string[]>(['不限']); | |||||
const [scaleItem, setScaleItem] = useState<object>(null); | |||||
const scaleChange = (tag: object, checked: boolean) => { | |||||
setScaleItem(tag); | |||||
const nextSelectedTags = checked | |||||
? [tag.name] | |||||
: scaleTags.filter((t) => t !== tag.name); | |||||
setScaleTags(nextSelectedTags); | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
scale: tag.id | |||||
})); | |||||
}; | |||||
// 见习基地 | |||||
const [probationTags, setProbationTags] = useState<string[]>(['不限']); | |||||
const [probationItem, setProbationItem] = useState<object>(null); | |||||
const probationChange = (tag: object, checked: boolean) => { | |||||
setProbationItem(tag); | |||||
const nextSelectedTags = checked | |||||
? [tag.name] | |||||
: probationTags.filter((t) => t !== tag.name); | |||||
setProbationTags(nextSelectedTags); | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
urgent: tag.id | |||||
})); | |||||
}; | |||||
// 知名企业 | |||||
const [famousTags, setFamousTags] = useState<string[]>(['不限']); | |||||
const [famousItem, setFamousItem] = useState<object>(null); | |||||
const famousChange = (tag: object, checked: boolean) => { | |||||
setFamousItem(tag); | |||||
const nextSelectedTags = checked | |||||
? [tag.name] | |||||
: famousTags.filter((t) => t !== tag.name); | |||||
setFamousTags(nextSelectedTags); | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
urgent: tag.id | |||||
})); | |||||
}; | |||||
useEffect(() => { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
keyword: keywordName | |||||
})); | |||||
}, [keywordName]); | |||||
useEffect(() => { | |||||
getSearchParams(searchJobParams) | |||||
}, [searchJobParams]) | |||||
return ( | |||||
<> | |||||
<ConfigProvider | |||||
theme={{ | |||||
components: { | |||||
Segmented: { | |||||
colorText: '#19be6e' | |||||
}, | |||||
Button: { | |||||
colorText: '' | |||||
}, | |||||
Tabs: { | |||||
verticalItemPadding: '0 24px' | |||||
} | |||||
} | |||||
}} | |||||
> | |||||
<Space direction='vertical' size={20} style={{ width: '100%' }}> | |||||
<Flex justify='center' align='center'> | |||||
<Space.Compact style={{ width: '80%' }}> | |||||
<Input | |||||
size='large' | |||||
prefix={<SearchOutlined style={{ color: '#19be6e' }} />} | |||||
placeholder="请输入关键词" | |||||
allowClear | |||||
value={keywordName} | |||||
onBlur={(e) => { | |||||
setKeywordName(e.target.value) | |||||
}} | |||||
onClear={() => { | |||||
setKeywordName('') | |||||
}} | |||||
// defaultValue={searchParams.keyword} | |||||
/> | |||||
<Button size='large' type='primary' style={{ width: 200 }} onClick={() => { | |||||
setKeywordName(searchJobParams.keyword) | |||||
}}>搜索</Button> | |||||
</Space.Compact> | |||||
</Flex> | |||||
{/* 筛选 */} | |||||
<Space direction='vertical' style={{ background: '#ffffff', padding: 20, borderRadius: 4 }}> | |||||
<Descriptions> | |||||
<Descriptions.Item span={24} label="见习基地"> | |||||
<Flex gap={4} wrap align="center"> | |||||
{dictModel.probationList.map((item, index) => ( | |||||
<Tag.CheckableTag | |||||
key={item.id} | |||||
checked={probationTags.includes(item.name)} | |||||
onChange={(checked) => { | |||||
probationChange(item, checked) | |||||
}} | |||||
> | |||||
{item.name} | |||||
</Tag.CheckableTag> | |||||
))} | |||||
</Flex> | |||||
</Descriptions.Item> | |||||
<Descriptions.Item span={24} label="知名企业"> | |||||
<Flex gap={4} wrap align="center"> | |||||
{dictModel.famousList.map((item, index) => ( | |||||
<Tag.CheckableTag | |||||
key={item.id} | |||||
checked={famousTags.includes(item.name)} | |||||
onChange={(checked) => { | |||||
famousChange(item, checked) | |||||
}} | |||||
> | |||||
{item.name} | |||||
</Tag.CheckableTag> | |||||
))} | |||||
</Flex> | |||||
</Descriptions.Item> | |||||
{/* 企业性质 */} | |||||
<Descriptions.Item span={24} label="企业性质"> | |||||
<Flex gap={4} wrap align="center"> | |||||
{dictModel.natureList.map((item, index) => ( | |||||
<Tag.CheckableTag | |||||
key={item.id} | |||||
checked={natureTags.includes(item.name)} | |||||
onChange={(checked) => { | |||||
natureChange(item, checked) | |||||
}} | |||||
> | |||||
{item.name} | |||||
</Tag.CheckableTag> | |||||
))} | |||||
</Flex> | |||||
</Descriptions.Item> | |||||
{/* 企业规模 */} | |||||
<Descriptions.Item span={24} label="企业规模"> | |||||
<Flex gap={4} wrap align="center"> | |||||
{dictModel.scaleList.map((item, index) => ( | |||||
<Tag.CheckableTag | |||||
key={item.id} | |||||
checked={scaleTags.includes(item.name)} | |||||
onChange={(checked) => { | |||||
scaleChange(item, checked) | |||||
}} | |||||
> | |||||
{item.name} | |||||
</Tag.CheckableTag> | |||||
))} | |||||
</Flex> | |||||
</Descriptions.Item> | |||||
{/* 地区选择 */} | |||||
<Descriptions.Item span={24} label="地区选择"> | |||||
<Space direction='vertical' size='small' style={{ maxWidth: 800, minWidth: 600 }}> | |||||
<Flex wrap style={{ width: '100%' }}> | |||||
{ | |||||
dictModel.xiaolanzhenList.map((item, index) => ( | |||||
<Tag.CheckableTag | |||||
checked={item.checked} | |||||
onChange={() => { | |||||
cityChange(item, index) | |||||
setAreaItem({ item: item, index: index }) | |||||
searchCityChange(areaItem.item, areaItem.index) | |||||
}} | |||||
> | |||||
{item.name} | |||||
</Tag.CheckableTag> | |||||
)) | |||||
} | |||||
</Flex> | |||||
<Flex wrap style={{ width: '100%' }}> | |||||
{ | |||||
dictModel.zhongshanList.map((item, index) => ( | |||||
<Tag.CheckableTag | |||||
checked={item.checked} | |||||
onChange={() => { | |||||
cityChange(item, index) | |||||
setAreaItem({ item: item, index: index }) | |||||
searchCityChange(areaItem.item, areaItem.index) | |||||
}} | |||||
> | |||||
{item.name} | |||||
</Tag.CheckableTag> | |||||
)) | |||||
} | |||||
</Flex> | |||||
<Cascader style={{ width: '50%' }} placeholder="请选择地区" options={dictModel.areaList} fieldNames={cascaderfieldNames} /> | |||||
</Space> | |||||
</Descriptions.Item> | |||||
{/* 地区选择 */} | |||||
<Descriptions.Item span={24} label="更多选择"> | |||||
<Space> | |||||
<Popconfirm | |||||
showCancel={false} | |||||
placement="right" | |||||
title='行业' | |||||
icon={null} | |||||
description={<> | |||||
{/* 行业 */} | |||||
<Space direction='vertical' size='small' style={{ maxWidth: 800, minWidth: 600, height: '600px' }}> | |||||
<Tabs | |||||
size='small' | |||||
style={{ maxWidth: 800, minWidth: 600, height: '600px' }} | |||||
tabPosition='left' | |||||
items={dictModel.industryPostList.map((item, index) => { | |||||
return { | |||||
key: item.id, | |||||
label: item.name, | |||||
children: (<> | |||||
<Space direction='vertical' style={{ height: '600px', overflow: 'auto' }}> | |||||
{ | |||||
item.children.map((childrenItem, childrenIndex) => ( | |||||
<> | |||||
<Tag.CheckableTag | |||||
key={childrenItem.id} | |||||
checked={industryTags.includes(childrenItem.name)} | |||||
onChange={(checked) => { | |||||
childrenItem.industry = item.id; | |||||
childrenItem.industry2 = childrenItem.id; | |||||
setIndustryItem(childrenItem) | |||||
industryChange(childrenItem, checked) | |||||
}} | |||||
style={{ | |||||
display: 'flex', | |||||
alignItems: 'center', | |||||
justifyContent: 'center', | |||||
width: 300, | |||||
padding: '8px 0', | |||||
background: industryTags.includes(childrenItem.name) ? '#19be6e' : '#edfff3', | |||||
color: industryTags.includes(childrenItem.name) ? '#f0f0f0' : '#000000', | |||||
}} | |||||
> | |||||
<Space> | |||||
{childrenItem.name} | |||||
</Space> | |||||
</Tag.CheckableTag> | |||||
</> | |||||
)) | |||||
} | |||||
</Space> | |||||
</>) | |||||
} | |||||
})} | |||||
/> | |||||
{/* <Cascader.Panel style={{border: 'none'}} options={dictModel.industryPostList} fieldNames={cascaderfieldNames} /> */} | |||||
</Space> | |||||
</> | |||||
} | |||||
okText="搜索" | |||||
onConfirm={() => { | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
industry: industryItem.industry, | |||||
industry2: industryItem.industry2, | |||||
})); | |||||
}} | |||||
> | |||||
<Button size='small'>行业选择</Button> | |||||
</Popconfirm> | |||||
</Space> | |||||
</Descriptions.Item> | |||||
</Descriptions> | |||||
<Flex justify='space-between' align='center'> | |||||
<Space> | |||||
<div style={{ width: 60 }}>已选择:</div> | |||||
<Row gutter={[10, 10]} > | |||||
{keywordName && <Col> | |||||
<Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setKeywordName('') | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
keyword: '' | |||||
})); | |||||
}} | |||||
>{keywordName}</Tag> | |||||
</Col>} | |||||
{probationItem && <Col> <Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setProbationItem(null) | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
probation: 0 | |||||
})); | |||||
}}>{probationItem.name}</Tag></Col>} | |||||
{famousItem && <Col> <Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setFamousItem(null) | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
famous: 0 | |||||
})); | |||||
}}>{famousItem.name}</Tag></Col>} | |||||
{areaName && <Col> <Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setAreaName('') | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
province: 0, | |||||
city: 0, | |||||
district: 0, | |||||
street: 0 | |||||
})); | |||||
}}>{areaName}</Tag></Col>} | |||||
{industryItem && <Col> <Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setIndustryItem(null) | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
industry: 0, | |||||
industry2: 0, | |||||
})); | |||||
}}>{industryItem.name}</Tag></Col>} | |||||
{natureItem && <Col> <Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setNatureItem(null); setNatureTags(['不限']) | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
nature: 0 | |||||
})); | |||||
}}>{natureItem.name}</Tag></Col>} | |||||
{scaleItem && <Col> <Tag closeIcon color="#4FBE70" onClose={() => { | |||||
setScaleItem(null); setScaleTags(['不限']) | |||||
setSearchJobParams(prevState => ({ | |||||
...prevState, | |||||
scale: 0 | |||||
})); | |||||
}}>{scaleItem.name}</Tag></Col>} | |||||
</Row> | |||||
</Space> | |||||
<Button size="small" onClick={() => { | |||||
setKeywordName('') | |||||
setAreaName('') | |||||
setIndustryItem(null) | |||||
setNatureItem(null) | |||||
setScaleItem(null) | |||||
setNatureTags(['不限']); | |||||
setScaleTags(['不限']); | |||||
setSearchJobParams({ | |||||
"keyword": "", | |||||
"location": 0, | |||||
"probation": 0, | |||||
"famous": 0, | |||||
"industry": 0, | |||||
"nature": 0, | |||||
"scale": 0, | |||||
"page": 1, | |||||
"pagesize": 18, | |||||
"sort": "id", | |||||
"sortby": "desc" | |||||
}); | |||||
}} > | |||||
清空筛选 | |||||
</Button> | |||||
</Flex> | |||||
</Space> | |||||
</Space> | |||||
</ConfigProvider> | |||||
</> | |||||
) | |||||
} | |||||
export default connect(({ dictModel, openModel }: any) => ({ | |||||
dictModel | |||||
}))(SearchFilter); |
checked: false | checked: false | ||||
}] | }] | ||||
const probationlist = [{ | |||||
name: '不限', | |||||
value: '0', | |||||
checked: true | |||||
}, { | |||||
name: '是', | |||||
value: 1, | |||||
checked: false | |||||
}, { | |||||
name: '否', | |||||
value: 2, | |||||
checked: false | |||||
}] | |||||
const famouslist = [{ | |||||
name: '不限', | |||||
value: '0', | |||||
checked: true | |||||
}, { | |||||
name: '是', | |||||
value: 1, | |||||
checked: false | |||||
}, { | |||||
name: '否', | |||||
value: 2, | |||||
checked: false | |||||
}] | |||||
export default { | export default { | ||||
state: { | state: { | ||||
name: '女', | name: '女', | ||||
value: '女', | value: '女', | ||||
checked: false | checked: false | ||||
}] // 性别要求 | |||||
}] ,// 性别要求 | |||||
probationList: probationlist, | |||||
famousList: famouslist | |||||
}, | }, | ||||
reducers: { | reducers: { | ||||
setXiaolanzhenList(state: any, { payload }: any) { | setXiaolanzhenList(state: any, { payload }: any) { |
setKeywordName(e.target.value) | setKeywordName(e.target.value) | ||||
}} | }} | ||||
/> | /> | ||||
<Link to={{ pathname: `/talent/search?keyword=${keywordName}` }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=${keywordName}` }}> | |||||
<Button size='large' type='primary' style={{ width: 200 }}>搜索</Button> | <Button size='large' type='primary' style={{ width: 200 }}>搜索</Button> | ||||
</Link> | </Link> | ||||
</Space.Compact> | </Space.Compact> | ||||
<Flex justify='center' align='center'> | <Flex justify='center' align='center'> | ||||
<Space size={30} style={{ width: '70%' }}> | <Space size={30} style={{ width: '70%' }}> | ||||
<Link to={{ pathname: `/talent/search?keyword=客服` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=客服` }} style={{ color: 'gray' }}> | |||||
客服 | 客服 | ||||
</Link> | </Link> | ||||
<Link to={{ pathname: `/talent/search?keyword=会计` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=会计` }} style={{ color: 'gray' }}> | |||||
会计 | 会计 | ||||
</Link> | </Link> | ||||
<Link to={{ pathname: `/talent/search?keyword=销售` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=销售` }} style={{ color: 'gray' }}> | |||||
销售 | 销售 | ||||
</Link> | </Link> | ||||
<Link to={{ pathname: `/talent/search?keyword=策划` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=策划` }} style={{ color: 'gray' }}> | |||||
策划 | 策划 | ||||
</Link> | </Link> | ||||
<Link to={{ pathname: `/talent/search?keyword=外贸` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=外贸` }} style={{ color: 'gray' }}> | |||||
外贸 | 外贸 | ||||
</Link> | </Link> | ||||
<Link to={{ pathname: `/talent/search?keyword=文员` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=文员` }} style={{ color: 'gray' }}> | |||||
文员 | 文员 | ||||
</Link> | </Link> | ||||
<Link to={{ pathname: `/talent/search?keyword=行政` }} style={{ color: 'gray' }}> | |||||
<Link to={{ pathname: `/talent/search/job?keyword=行政` }} style={{ color: 'gray' }}> | |||||
行政 | 行政 | ||||
</Link> | </Link> | ||||
</Space> | </Space> |
import { useState, useEffect, useRef } from 'react'; | |||||
import { ProList, PageContainer } from '@ant-design/pro-components'; | |||||
import { ConfigProvider, Button, Flex, Input, Space, Image, Select, Row, Col, Pagination, Tag, Card, Divider, Typography, Anchor } from 'antd'; | |||||
import { SearchOutlined, LikeOutlined, ArrowRightOutlined, StarOutlined } from '@ant-design/icons'; | |||||
import { useModel, connect, history, Link, useSearchParams } from 'umi'; | |||||
import SearchFilter from '@/components/Talent/Search/Filter/Company'; | |||||
import SearchJob from '@/components/Talent/Search/Company/index'; | |||||
import { Imageprefix } from '@/constants/index' | |||||
import { PostCompanySearch } from '@/services/apis/company'; | |||||
import { GetAdvertscheduleList } from '@/services/apis/advertschedule'; | |||||
import EmptyResult from '@/components/Common/EmptyResult' | |||||
import CommonJob from '@/components/Common/Job' | |||||
const HomePage: React.FC = () => { | |||||
const [searchParams, setSearchParams] = useSearchParams(); | |||||
const [list, setList] = useState<object[]>([]) | |||||
const [advertscheduleList, setAdvertscheduleList] = useState<object[]>([]) | |||||
const [search, setSearch] = useState<object | null>(null) | |||||
const [total, setTotal] = useState<number>(0) | |||||
const [page, setPage] = useState<number>(1) | |||||
const [pagesize, setPageSize] = useState<number>(7) | |||||
useEffect(() => { | |||||
GetAdvertscheduleList({ page: 1, pagesize: 4, code: 'wzsylbt' }).then(res => { | |||||
setAdvertscheduleList(res.data.advertschedules) | |||||
}) | |||||
}, []); | |||||
// useEffect(() => { | |||||
// PostJobSearch({ | |||||
// page: 1, | |||||
// pagesize: 12, | |||||
// sort: 'updated_at', | |||||
// sortby: 'desc' | |||||
// }).then(res => { | |||||
// setList(res.data.jobs) | |||||
// getTotal(res.data.total) | |||||
// }) | |||||
// }, []); | |||||
const getSearchParams = async (value) => { | |||||
setPage(value.page) | |||||
setPageSize(value.pagesize) | |||||
if (value.keyword) { | |||||
setSearchParams({ keyword: value.keyword }) | |||||
} else { | |||||
setSearchParams({ keyword: '' }) | |||||
} | |||||
let res = await PostCompanySearch(value ? value : { | |||||
page: 1, | |||||
pagesize: 18, | |||||
sort: 'updated_at', | |||||
sortby: 'desc', | |||||
}) | |||||
setList(res.data.list) | |||||
getTotal(res.data.total) | |||||
} | |||||
const getTotal = (value) => { | |||||
setTotal(value) | |||||
} | |||||
return ( | |||||
<> | |||||
<ConfigProvider | |||||
theme={{ | |||||
token: { | |||||
colorPrimary: '#19be6e', | |||||
}, | |||||
components: { | |||||
Button: { | |||||
colorText: '#19be6e' | |||||
} | |||||
} | |||||
}} | |||||
> | |||||
<Space direction='vertical' size={30} style={{ minHeight: '800px' }}> | |||||
<SearchFilter getSearchParams={getSearchParams} keyword={searchParams.get('keyword') ? searchParams.get('keyword') : ''}></SearchFilter> | |||||
<Row gutter={[16, 16]}> | |||||
<Col span={18}> | |||||
<Row gutter={[16, 16]}> | |||||
{ | |||||
list && list.length > 0 && list.map((item: any, index: number) => ( | |||||
<> | |||||
<Col span={8}> | |||||
<Link to={{ pathname: `/talent/company/detail?id=${item.id}` }} target="_blank" style={{ width: '100%' }}> | |||||
<Space direction='vertical' size={10} align='center' style={{ width: '100%', paddingTop: 20, paddingBottom: 20, background: '#ffffff', borderRadius: 8 }}> | |||||
<Image src={item.photo ? `${Imageprefix}${item.photo}` : '/images/logo.jpg'} preview={false} width={'140px'} height={'78px'} style={{ borderRadius: '8px' }}></Image> | |||||
<Typography.Title level={5} style={{ width: '100%', padding: '0 10px' }} | |||||
> | |||||
{item.full_name} | |||||
</Typography.Title> | |||||
<Flex justify='flex-end' align='center' style={{ fontSize: 14, color: '#999' }}> | |||||
{item.company_nature ? <>{item.company_nature}</> : <>性质不限</>} | |||||
{item.industry_text ? <><Divider type='vertical' /> {item.industry_text} </> : <><Divider type='vertical' />行业不限</>} | |||||
{item.company_scale ? <><Divider type='vertical' /> {item.company_scale} </> : <><Divider type='vertical' />规模不限</>} | |||||
</Flex> | |||||
</Space> | |||||
</Link> | |||||
</Col> | |||||
</> | |||||
)) | |||||
} | |||||
</Row> | |||||
{ | |||||
!list || list.length == 0 && <EmptyResult description="没有找到符合条件的企业" /> | |||||
} | |||||
<Flex justify='center' align='center' style={{ margin: '40px 0' }}> | |||||
<Pagination | |||||
hideOnSinglePage | |||||
total={total} | |||||
showTotal={(total) => `总共${total}条`} | |||||
current={page} | |||||
pageSize={pagesize} | |||||
pageSizeOptions={['12', '24', '36']} | |||||
onChange={(page, pageSize) => { | |||||
setPage(page) | |||||
setPageSize(pageSize) | |||||
}} | |||||
/> | |||||
</Flex> | |||||
</Col> | |||||
<Col span={6}> | |||||
{ | |||||
advertscheduleList && advertscheduleList.length && advertscheduleList.map((item, index) => ( | |||||
<div style={{ borderRadius: 8, marginBottom: 20 }}> | |||||
<div style={{ | |||||
width: '100%', | |||||
position: 'relative', | |||||
paddingTop: '56.25%', /* 16:9 的比例 */ | |||||
overflow: 'hidden' | |||||
}}> | |||||
<Link to={{ pathname: item.target_url }} target='_blank'> | |||||
<img src={Imageprefix + item.image_url} style={{ | |||||
position: 'absolute', | |||||
top: 0, | |||||
left: 0, | |||||
width: '100%', | |||||
height: '100%', | |||||
borderRadius: 8 | |||||
}} /> | |||||
</Link> | |||||
</div> | |||||
</div> | |||||
)) | |||||
} | |||||
</Col> | |||||
</Row> | |||||
</Space> | |||||
</ConfigProvider > | |||||
</> | |||||
); | |||||
}; | |||||
export default HomePage; |
import { useState, useEffect, useRef } from 'react'; | |||||
import { ProList, PageContainer } from '@ant-design/pro-components'; | |||||
import { ConfigProvider, Button, Flex, Input, Space, Image, Select, Row, Col, Pagination, Tag, Card, Avatar, Typography, Anchor } from 'antd'; | |||||
import { SearchOutlined, LikeOutlined, ArrowRightOutlined, StarOutlined } from '@ant-design/icons'; | |||||
import { useModel, connect, history, Link, useSearchParams } from 'umi'; | |||||
import SearchFilter from '@/components/Talent/Search/Filter/index'; | |||||
import SearchJob from '@/components/Talent/Search/Job/index'; | |||||
import { Imageprefix } from '@/constants/index' | |||||
import { PostJobSearch } from '@/services/apis/post'; | |||||
import { GetAdvertscheduleList } from '@/services/apis/advertschedule'; | |||||
import EmptyResult from '@/components/Common/EmptyResult' | |||||
import CommonJob from '@/components/Common/Job' | |||||
const HomePage: React.FC = () => { | |||||
const [searchParams, setSearchParams] = useSearchParams(); | |||||
const [list, setList] = useState<object[]>([]) | |||||
const [advertscheduleList, setAdvertscheduleList] = useState<object[]>([]) | |||||
const [search, setSearch] = useState<object | null>(null) | |||||
const [total, setTotal] = useState<number>(0) | |||||
const [page, setPage] = useState<number>(1) | |||||
const [pagesize, setPageSize] = useState<number>(7) | |||||
useEffect(() => { | |||||
GetAdvertscheduleList({ page: 1, pagesize: 4, code: 'wzsylbt' }).then(res => { | |||||
setAdvertscheduleList(res.data.advertschedules) | |||||
}) | |||||
}, []); | |||||
// useEffect(() => { | |||||
// PostJobSearch({ | |||||
// page: 1, | |||||
// pagesize: 12, | |||||
// sort: 'updated_at', | |||||
// sortby: 'desc' | |||||
// }).then(res => { | |||||
// setList(res.data.jobs) | |||||
// getTotal(res.data.total) | |||||
// }) | |||||
// }, []); | |||||
const getSearchParams = async (value) => { | |||||
setPage(value.page) | |||||
setPageSize(value.pagesize) | |||||
if (value.keyword) { | |||||
setSearchParams({ keyword: value.keyword }) | |||||
} else { | |||||
setSearchParams({ keyword: '' }) | |||||
} | |||||
let res = await PostJobSearch(value ? value : { | |||||
page: 1, | |||||
pagesize: 12, | |||||
sort: 'updated_at', | |||||
sortby: 'desc', | |||||
}) | |||||
setList(res.data.jobs) | |||||
getTotal(res.data.total) | |||||
} | |||||
const getTotal = (value) => { | |||||
setTotal(value) | |||||
} | |||||
return ( | |||||
<> | |||||
<ConfigProvider | |||||
theme={{ | |||||
token: { | |||||
colorPrimary: '#19be6e', | |||||
}, | |||||
components: { | |||||
Button: { | |||||
colorText: '#19be6e' | |||||
} | |||||
} | |||||
}} | |||||
> | |||||
<Space direction='vertical' size={30} style={{ minHeight: '800px' }}> | |||||
<SearchFilter getSearchParams={getSearchParams} keyword={searchParams.get('keyword') ? searchParams.get('keyword') : ''}></SearchFilter> | |||||
<Row gutter={[16, 16]}> | |||||
<Col span={18}> | |||||
{ | |||||
list && list.length > 0 && list.map((item: any, index: number) => ( | |||||
<> | |||||
<CommonJob item={item}></CommonJob> | |||||
</> | |||||
)) | |||||
} | |||||
{ | |||||
!list || list.length == 0 && <EmptyResult description="没有找到符合条件的职位" /> | |||||
} | |||||
<Flex justify='center' align='center' style={{ margin: '40px 0' }}> | |||||
<Pagination | |||||
hideOnSinglePage | |||||
total={total} | |||||
showTotal={(total) => `总共${total}条`} | |||||
current={page} | |||||
pageSize={pagesize} | |||||
pageSizeOptions={['12', '24', '36']} | |||||
onChange={(page, pageSize) => { | |||||
setPage(page) | |||||
setPageSize(pageSize) | |||||
}} | |||||
/> | |||||
</Flex> | |||||
</Col> | |||||
<Col span={6}> | |||||
{ | |||||
advertscheduleList && advertscheduleList.length && advertscheduleList.map((item, index) => ( | |||||
<div style={{ borderRadius: 8, marginBottom: 20 }}> | |||||
<div style={{ | |||||
width: '100%', | |||||
position: 'relative', | |||||
paddingTop: '56.25%', /* 16:9 的比例 */ | |||||
overflow: 'hidden' | |||||
}}> | |||||
<Link to={{ pathname: item.target_url }} target='_blank'> | |||||
<img src={Imageprefix + item.image_url} style={{ | |||||
position: 'absolute', | |||||
top: 0, | |||||
left: 0, | |||||
width: '100%', | |||||
height: '100%', | |||||
borderRadius: 8 | |||||
}} /> | |||||
</Link> | |||||
</div> | |||||
</div> | |||||
)) | |||||
} | |||||
</Col> | |||||
</Row> | |||||
</Space> | |||||
</ConfigProvider > | |||||
</> | |||||
); | |||||
}; | |||||
export default HomePage; |
export const GetCompanyRecruiters = GetModel(CompanyUrl.CompanyRecruiters); // 列表 | export const GetCompanyRecruiters = GetModel(CompanyUrl.CompanyRecruiters); // 列表 | ||||
export const PostJobseekerResetPwd = PostModel(CompanyUrl.JobseekerResetPwd); | export const PostJobseekerResetPwd = PostModel(CompanyUrl.JobseekerResetPwd); | ||||
export const PostCompanySearch = PostModel(CompanyUrl.CompanySearch); | |||||
CompanyRecruiters?: string | CompanyRecruiters?: string | ||||
JobseekerResetPwd?: string // 重置密码 | JobseekerResetPwd?: string // 重置密码 | ||||
CompanySearch?: string | |||||
} | } | ||||
interface Advertschedule { | interface Advertschedule { |
CompanyRecruiters: web + '/company/recruiters', // 详情 | CompanyRecruiters: web + '/company/recruiters', // 详情 | ||||
JobseekerResetPwd: web + '/jobseeker/resetpwd', // 重置密码 | JobseekerResetPwd: web + '/jobseeker/resetpwd', // 重置密码 | ||||
CompanySearch: web + '/company/search', // 重置密码 | |||||
} | } | ||||