bug修复
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled

This commit is contained in:
francis-fh
2026-06-16 22:58:59 +08:00
parent bcb5c6af19
commit 077f6548cf
7 changed files with 264 additions and 6 deletions

View File

@@ -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;

View File

@@ -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<boolean>(false);
const [itemsPerPage] = useState<number>(6);
const [totalPages, setTotalPages] = useState<number>(1);
const [activeJobTitle, setActiveJobTitle] = useState<string>('');
const [jobTitles, setJobTitles] = useState<string[]>(() => {
// 初始化时先尝试从缓存读取
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<string, unknown>);
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 = () => {
<div className="jobs-section">
<div className="jobs-section-header">
<Title level={3} className="jobs-title"></Title>
<div className="jobs-section-header-left">
<Title level={3} className="jobs-title"></Title>
{jobTitles.length > 0 && (
<div className="expectation-tags">
<span className="expectation-label"></span>
{jobTitles.map((title) => (
<Tag
key={title}
className={`expectation-tag ${activeJobTitle === title ? 'active' : ''}`}
onClick={() => handleExpectationTagClick(title)}
>
{title}
</Tag>
))}
</div>
)}
</div>
<span className="view-more" onClick={() => history.push('/job-portal/list')}>
&gt;
</span>