diff --git a/src/app.tsx b/src/app.tsx index 477646a..9f2487f 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,4 +1,5 @@ import { AvatarDropdown, AvatarName, Footer, SelectLang } from '@/components'; +import EnterpriseHeader from '@/components/EnterpriseHeader'; import type { Settings as LayoutSettings } from '@ant-design/pro-components'; import { SettingDrawer } from '@ant-design/pro-components'; import type { RunTimeLayoutConfig } from '@umijs/max'; @@ -166,8 +167,11 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) = // 增加一个 loading 的状态 childrenRender: (children) => { // if (initialState?.loading) return ; + // roles?.[0] 为 'view' 时是企业账号,显示返回首页顶栏 + const isEnterprise = initialState?.currentUser?.userType === 'view'; return ( <> + {isEnterprise && } {children} { + useEffect(() => { + document.body.classList.add('has-enterprise-header'); + return () => { + document.body.classList.remove('has-enterprise-header'); + }; + }, []); + + const handleGoHome = () => { + window.open(PORTAL_HOME_URL, '_blank'); + }; + + const header = ( +
+
+ 石城智慧就业 +
+ 石河子智慧就业 · 企业管理端 +
+ +
+
+ + 返回首页 +
+
+
+ ); + + return createPortal(header, document.body); +}; + +export default EnterpriseHeader; diff --git a/src/components/index.ts b/src/components/index.ts index ca88a6d..8a3890e 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -8,5 +8,6 @@ import Footer from './Footer'; import { Question, SelectLang } from './RightContent'; import { AvatarDropdown, AvatarName } from './RightContent/AvatarDropdown'; +import EnterpriseHeader from './EnterpriseHeader'; -export { Footer, Question, SelectLang, AvatarDropdown, AvatarName }; +export { Footer, Question, SelectLang, AvatarDropdown, AvatarName, EnterpriseHeader }; diff --git a/src/pages/JobPortal/index.less b/src/pages/JobPortal/index.less index 6b39caa..02093ae 100644 --- a/src/pages/JobPortal/index.less +++ b/src/pages/JobPortal/index.less @@ -184,12 +184,54 @@ justify-content: space-between; align-items: center; margin-bottom: 20px; + flex-wrap: wrap; + gap: 12px; + + .jobs-section-header-left { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + } .jobs-title { .jp-section-title(); margin: 0; } + .expectation-tags { + display: flex; + align-items: center; + gap: 8px; + + .expectation-label { + font-size: 13px; + color: @jp-text-secondary; + white-space: nowrap; + } + + .expectation-tag { + .jp-job-tag(); + padding: 4px 12px; + cursor: pointer; + font-size: 13px; + transition: all 0.2s; + border-radius: 20px; + + &:hover { + background: @jp-primary !important; + color: #fff !important; + border-color: @jp-primary !important; + } + + &.active { + background: @jp-primary !important; + color: #fff !important; + border-color: @jp-primary !important; + } + } + } + .view-more { color: @jp-primary; font-size: 14px; diff --git a/src/pages/JobPortal/index.tsx b/src/pages/JobPortal/index.tsx index d43d6a9..b168da6 100644 --- a/src/pages/JobPortal/index.tsx +++ b/src/pages/JobPortal/index.tsx @@ -15,6 +15,8 @@ import { } from '@ant-design/icons'; import { history } from '@umijs/max'; import { getJobTitleTreeSelect, getJobRecommend } from '@/services/common/jobTitle'; +import { getGetInfoCache, saveGetInfoCache } from '@/utils/jobPortalAuth'; +import { getUserInfo } from '@/services/session'; import JobPortalHeader from '@/components/JobPortalHeader'; import './index.less'; @@ -128,6 +130,33 @@ const JobPortalPage: React.FC = () => { const [loading, setLoading] = useState(false); const [itemsPerPage] = useState(6); const [totalPages, setTotalPages] = useState(1); + const [activeJobTitle, setActiveJobTitle] = useState(''); + const [jobTitles, setJobTitles] = useState(() => { + // 初始化时先尝试从缓存读取 + return (getGetInfoCache()?.user as any)?.jobTitles || []; + }); + + // 缓存可能因 SSO 登录时序问题尚未写入,主动拉取一次 + useEffect(() => { + if (jobTitles.length > 0) return; + const cached = (getGetInfoCache()?.user as any)?.jobTitles; + if (cached?.length) { + setJobTitles(cached); + return; + } + // 缓存不存在则请求 /api/getInfo 写入后再读取 + getUserInfo({ skipErrorHandler: true }) + .then((res: any) => { + saveGetInfoCache(res as Record); + const titles = (res?.user as any)?.jobTitles; + if (titles?.length) { + setJobTitles(titles); + } + }) + .catch(() => { + // 静默处理 + }); + }, []); useEffect(() => { const fetchJobTitleData = async () => { @@ -147,9 +176,9 @@ const JobPortalPage: React.FC = () => { } }; - const fetchJobRecommendData = async () => { + const fetchJobRecommendData = async (jobTitle?: string) => { try { - const response = await getJobRecommend(); + const response = await getJobRecommend(jobTitle ? { jobTitle } : undefined); setJobRecommendData(response); } catch { // 静默处理 @@ -217,6 +246,20 @@ const JobPortalPage: React.FC = () => { history.push(`/job-portal/list`, { queryParams: { name } }); }; + const handleExpectationTagClick = (jobTitle: string) => { + const newActive = activeJobTitle === jobTitle ? '' : jobTitle; + setActiveJobTitle(newActive); + const fetchJobRecommendData = async () => { + try { + const response = await getJobRecommend(newActive ? { jobTitle: newActive } : undefined); + setJobRecommendData(response); + } catch { + // 静默处理 + } + }; + fetchJobRecommendData(); + }; + const renderJobCards = () => { const jobs = jobRecommendData?.data; if (jobs?.length) { @@ -358,7 +401,23 @@ const JobPortalPage: React.FC = () => {
- 热门职位推荐 +
+ 热门职位推荐 + {jobTitles.length > 0 && ( +
+ 求职期望 + {jobTitles.map((title) => ( + handleExpectationTagClick(title)} + > + {title} + + ))} +
+ )} +
history.push('/job-portal/list')}> 查看更多 > diff --git a/src/services/common/jobTitle.ts b/src/services/common/jobTitle.ts index 42cbd44..820f38f 100644 --- a/src/services/common/jobTitle.ts +++ b/src/services/common/jobTitle.ts @@ -8,11 +8,12 @@ export async function getJobTitleTreeSelect() { } // 获取热门岗位推荐数据 -export async function getJobRecommend() { +export async function getJobRecommend(params?: { jobTitle?: string }) { return request('/api/cms/job/recommend', { method: 'GET', params: { - order: 2 + order: 2, + ...(params?.jobTitle ? { jobTitle: params.jobTitle } : {}) } }); }