Soleilw 2 місяці тому
джерело
коміт
0c405038b2
32 змінених файлів з 1259 додано та 152 видалено
  1. 10
    4
      config/routes.ts
  2. 1
    0
      dist/3650.e04411a6.async.js
  3. 1
    1
      dist/index.html
  4. 1
    1
      dist/p__Manage__Company__Department__index.ed33e563.async.js
  5. 1
    0
      dist/p__Manage__Company__Home__index.1d77932f.async.js
  6. 0
    1
      dist/p__Manage__Company__Home__index.c505a916.async.js
  7. 1
    1
      dist/p__Manage__Company__Info__index.9316dad4.async.js
  8. 1
    1
      dist/p__Manage__Company__Post__index.8d71d763.async.js
  9. 0
    1
      dist/p__Manage__Company__Recommend__index.3cf0fe6f.async.js
  10. 1
    0
      dist/p__Manage__Company__Recommend__index.ef6c2e2c.async.js
  11. 1
    1
      dist/p__Manage__Company__Resume__index.90784606.async.js
  12. 1
    1
      dist/p__Manage__Company__Setting__index.36d3f070.async.js
  13. 1
    0
      dist/p__Manage__Jobseeker__Setting__index.270ea838.async.js
  14. 0
    1
      dist/p__Manage__Jobseeker__Setting__index.9e4cb0a8.async.js
  15. 0
    1
      dist/p__Talent__Detail__Company__index.15aa5ef5.async.js
  16. 1
    0
      dist/p__Talent__Detail__Company__index.cb4b78cb.async.js
  17. 1
    0
      dist/p__Talent__Forget__index.73cafb6a.async.js
  18. 0
    1
      dist/p__Talent__Forget__index.ecc2a5fa.async.js
  19. 1
    1
      dist/p__Talent__Home__index.7fdac5ba.async.js
  20. 1
    0
      dist/p__Talent__Search__Company__index.10486560.async.js
  21. 1
    1
      dist/p__Talent__Search__Job__index.1e7af6b5.async.js
  22. 124
    124
      dist/umi.85104365.js
  23. 2
    1
      src/access.ts
  24. 133
    0
      src/components/Talent/Search/Company/index.tsx
  25. 590
    0
      src/components/Talent/Search/Filter/Company/index.tsx
  26. 33
    1
      src/models/dictModel.ts
  27. 8
    8
      src/pages/Talent/Home/index.tsx
  28. 177
    0
      src/pages/Talent/Search/Company/index.tsx
  29. 157
    0
      src/pages/Talent/Search/Job/index.tsx
  30. 4
    0
      src/services/apis/company.ts
  31. 1
    1
      src/services/types/url.d.ts
  32. 5
    0
      src/services/url/company.ts

+ 10
- 4
config/routes.ts Переглянути файл

@@ -24,10 +24,16 @@ export default [
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: '招聘会',

+ 1
- 0
dist/3650.e04411a6.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 1
dist/index.html Переглянути файл

@@ -8,6 +8,6 @@
</head>
<body>
<div id="root"></div>
<script src="/umi.ebceb906.js"></script>
<script src="/umi.85104365.js"></script>
</body>
</html>

dist/p__Manage__Company__Department__index.ed33e563.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
dist/p__Manage__Company__Home__index.1d77932f.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 0
- 1
dist/p__Manage__Company__Home__index.c505a916.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/p__Manage__Company__Info__index.9316dad4.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/p__Manage__Company__Post__index.8d71d763.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 0
- 1
dist/p__Manage__Company__Recommend__index.3cf0fe6f.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
dist/p__Manage__Company__Recommend__index.ef6c2e2c.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/p__Manage__Company__Resume__index.90784606.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/p__Manage__Company__Setting__index.36d3f070.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
dist/p__Manage__Jobseeker__Setting__index.270ea838.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 0
- 1
dist/p__Manage__Jobseeker__Setting__index.9e4cb0a8.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 0
- 1
dist/p__Talent__Detail__Company__index.15aa5ef5.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
dist/p__Talent__Detail__Company__index.cb4b78cb.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
dist/p__Talent__Forget__index.73cafb6a.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 0
- 1
dist/p__Talent__Forget__index.ecc2a5fa.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/p__Talent__Home__index.7fdac5ba.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
dist/p__Talent__Search__Company__index.10486560.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/p__Talent__Search__Job__index.1e7af6b5.async.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


dist/umi.85104365.js
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 2
- 1
src/access.ts Переглянути файл

@@ -33,7 +33,8 @@ export default () => {
permissions = {
talent: true,
talenthome: true,
talentsearch: true,
talentsearchjob: true,
talentsearchcompany: true,
talentfair: true,
talentinformation: true,
talentdownload: true,

+ 133
- 0
src/components/Talent/Search/Company/index.tsx Переглянути файл

@@ -0,0 +1,133 @@



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;


+ 590
- 0
src/components/Talent/Search/Filter/Company/index.tsx Переглянути файл

@@ -0,0 +1,590 @@
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);

+ 33
- 1
src/models/dictModel.ts Переглянути файл

@@ -27,6 +27,36 @@ const naturelist = [{
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 {
state: {
@@ -83,7 +113,9 @@ export default {
name: '女',
value: '女',
checked: false
}] // 性别要求
}] ,// 性别要求
probationList: probationlist,
famousList: famouslist
},
reducers: {
setXiaolanzhenList(state: any, { payload }: any) {

+ 8
- 8
src/pages/Talent/Home/index.tsx Переглянути файл

@@ -103,7 +103,7 @@ const HomePage: React.FC = ({ dispatch, dictModel }: any) => {
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>
</Link>
</Space.Compact>
@@ -111,25 +111,25 @@ const HomePage: React.FC = ({ dispatch, dictModel }: any) => {

<Flex justify='center' align='center'>
<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 to={{ pathname: `/talent/search?keyword=会计` }} style={{ color: 'gray' }}>
<Link to={{ pathname: `/talent/search/job?keyword=会计` }} style={{ color: 'gray' }}>
会计
</Link>
<Link to={{ pathname: `/talent/search?keyword=销售` }} style={{ color: 'gray' }}>
<Link to={{ pathname: `/talent/search/job?keyword=销售` }} style={{ color: 'gray' }}>
销售
</Link>
<Link to={{ pathname: `/talent/search?keyword=策划` }} style={{ color: 'gray' }}>
<Link to={{ pathname: `/talent/search/job?keyword=策划` }} style={{ color: 'gray' }}>
策划
</Link>
<Link to={{ pathname: `/talent/search?keyword=外贸` }} style={{ color: 'gray' }}>
<Link to={{ pathname: `/talent/search/job?keyword=外贸` }} style={{ color: 'gray' }}>
外贸
</Link>
<Link to={{ pathname: `/talent/search?keyword=文员` }} style={{ color: 'gray' }}>
<Link to={{ pathname: `/talent/search/job?keyword=文员` }} style={{ color: 'gray' }}>
文员
</Link>
<Link to={{ pathname: `/talent/search?keyword=行政` }} style={{ color: 'gray' }}>
<Link to={{ pathname: `/talent/search/job?keyword=行政` }} style={{ color: 'gray' }}>
行政
</Link>
</Space>

+ 177
- 0
src/pages/Talent/Search/Company/index.tsx Переглянути файл

@@ -0,0 +1,177 @@
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;

+ 157
- 0
src/pages/Talent/Search/Job/index.tsx Переглянути файл

@@ -0,0 +1,157 @@
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;

+ 4
- 0
src/services/apis/company.ts Переглянути файл

@@ -39,3 +39,7 @@ export const GetCompanyCustomerCodeDetail = GetModel(CompanyUrl.CompanyCustomerC
export const GetCompanyRecruiters = GetModel(CompanyUrl.CompanyRecruiters); // 列表

export const PostJobseekerResetPwd = PostModel(CompanyUrl.JobseekerResetPwd);

export const PostCompanySearch = PostModel(CompanyUrl.CompanySearch);



+ 1
- 1
src/services/types/url.d.ts Переглянути файл

@@ -173,7 +173,7 @@ declare namespace Url {
CompanyRecruiters?: string

JobseekerResetPwd?: string // 重置密码
CompanySearch?: string
}

interface Advertschedule {

+ 5
- 0
src/services/url/company.ts Переглянути файл

@@ -39,5 +39,10 @@ export const CompanyUrl: Url.Company = {
CompanyRecruiters: web + '/company/recruiters', // 详情
JobseekerResetPwd: web + '/jobseeker/resetpwd', // 重置密码

CompanySearch: web + '/company/search', // 重置密码


}


Завантаження…
Відмінити
Зберегти