| 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', // 重置密码 | |||||
| } | } | ||||