11
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
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:
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { useParams, history, useLocation } from '@umijs/max';
|
||||
import {
|
||||
Card,
|
||||
@@ -27,10 +27,17 @@ import {
|
||||
import { Radar } from '@ant-design/charts';
|
||||
import JobPortalHeader from '@/components/JobPortalHeader';
|
||||
import './index.less';
|
||||
import { getJobCompetitiveness } from '@/services/jobportal/competitiveness';
|
||||
import {
|
||||
getJobCompetitiveness,
|
||||
getEmptyCompetitivenessRadar,
|
||||
} from '@/services/jobportal/competitiveness';
|
||||
import { isJobPortalLoggedIn } from '@/utils/jobPortalAuth';
|
||||
import { favoriteJob, unfavoriteJob, applyJob } from '@/services/jobportal/user';
|
||||
import { getAccessToken } from '@/access';
|
||||
import { PageEnum } from '@/enums/pagesEnums';
|
||||
import { ensureJobPortalLogin, PORTAL_LOGIN_URL } from '@/utils/jobPortalAuth';
|
||||
import { getDictLabel, findTreeLabelById } from '@/utils/jobPortalDict';
|
||||
import { getDictValueEnum } from '@/services/system/dict';
|
||||
import { getCmsIndustryTreeList } from '@/services/classify/industry';
|
||||
import type { DictValueEnumObj } from '@/components/DictTag';
|
||||
|
||||
const { Title, Text, Paragraph } = Typography;
|
||||
|
||||
@@ -106,11 +113,13 @@ const transformJobData = (jobData: any) => {
|
||||
<p>3. 具备良好的团队协作能力;</p>
|
||||
`,
|
||||
companyInfo: {
|
||||
name: jobData.companyName || jobData.company,
|
||||
type: jobData.industry || '互联网/电子商务',
|
||||
scale: jobData.scale || '100-499人',
|
||||
industry: jobData.industry || '计算机/互联网',
|
||||
description: jobData.companyVo?.companyDescription || jobData.companyDescription || '暂无公司描述信息'
|
||||
name: jobData.companyName || jobData.company || jobData.companyVo?.name,
|
||||
scale: jobData.companyVo?.scale ?? jobData.scale ?? '',
|
||||
industry: jobData.companyVo?.industry ?? jobData.industry ?? '',
|
||||
description:
|
||||
jobData.companyVo?.companyDescription
|
||||
|| jobData.companyDescription
|
||||
|| '暂无公司描述信息',
|
||||
},
|
||||
competitiveness: {
|
||||
overall: 75,
|
||||
@@ -157,7 +166,6 @@ const mockJobDetail = {
|
||||
`,
|
||||
companyInfo: {
|
||||
name: '青岛科技发展有限公司',
|
||||
type: '互联网/电子商务',
|
||||
scale: '500-999人',
|
||||
industry: '计算机/互联网',
|
||||
description: '青岛科技发展有限公司是一家专注于软件开发、技术服务的科技企业。公司致力于为客户提供优质的IT解决方案,业务涵盖企业信息化、移动应用开发等领域。我们拥有一支年轻、专业的团队,注重技术创新和人才培养,为员工提供良好的发展平台。'
|
||||
@@ -193,6 +201,36 @@ const JobDetailPage: React.FC = () => {
|
||||
{ item: '年龄', score: 0 },
|
||||
{ item: '工作地', score: 0 }
|
||||
]);
|
||||
const [scaleEnum, setScaleEnum] = useState<DictValueEnumObj>({});
|
||||
const [industryTree, setIndustryTree] = useState<any[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all([
|
||||
getDictValueEnum('scale', true, true),
|
||||
getCmsIndustryTreeList(),
|
||||
]).then(([scaleData, industryRes]) => {
|
||||
setScaleEnum(scaleData);
|
||||
if (industryRes?.code === 200 && industryRes?.data) {
|
||||
setIndustryTree(industryRes.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const companyMetaItems = useMemo(() => {
|
||||
const company = originalJobData?.companyVo || {};
|
||||
const rawScale = company.scale ?? originalJobData?.scale ?? jobDetail.companyInfo?.scale;
|
||||
const rawIndustry =
|
||||
company.industry ?? originalJobData?.industry ?? jobDetail.companyInfo?.industry;
|
||||
|
||||
const items: string[] = [];
|
||||
const scaleLabel = getDictLabel(scaleEnum, rawScale) || rawScale;
|
||||
const industryLabel = findTreeLabelById(industryTree, rawIndustry) || rawIndustry;
|
||||
|
||||
if (scaleLabel) items.push(scaleLabel);
|
||||
if (industryLabel) items.push(industryLabel);
|
||||
|
||||
return items;
|
||||
}, [originalJobData, jobDetail.companyInfo, scaleEnum, industryTree]);
|
||||
|
||||
useEffect(() => {
|
||||
// 首先尝试从传递的数据中获取职位信息
|
||||
@@ -226,10 +264,19 @@ const JobDetailPage: React.FC = () => {
|
||||
}, [jobDetail?.id]);
|
||||
|
||||
const fetchCompetitiveness = async (jobIdNum: number) => {
|
||||
if (!isJobPortalLoggedIn()) {
|
||||
setOverallScore(0);
|
||||
setRadarData(getEmptyCompetitivenessRadar());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await getJobCompetitiveness(jobIdNum);
|
||||
const data = res as any;
|
||||
if (!data) return;
|
||||
if (!data) {
|
||||
setOverallScore(0);
|
||||
setRadarData(getEmptyCompetitivenessRadar());
|
||||
return;
|
||||
}
|
||||
if (typeof data.matchScore === 'number') {
|
||||
const clamped = Math.max(0, Math.min(100, data.matchScore));
|
||||
setOverallScore(clamped);
|
||||
@@ -248,36 +295,25 @@ const JobDetailPage: React.FC = () => {
|
||||
].map(d => ({ ...d, score: Math.max(0, Math.min(100, d.score)) }));
|
||||
setRadarData(mapped);
|
||||
} else {
|
||||
setRadarData([
|
||||
{ item: '技能', score: 0 },
|
||||
{ item: '工作经验', score: 0 },
|
||||
{ item: '学历', score: 0 },
|
||||
{ item: '薪资', score: 0 },
|
||||
{ item: '年龄', score: 0 },
|
||||
{ item: '工作地', score: 0 }
|
||||
]);
|
||||
setRadarData(getEmptyCompetitivenessRadar());
|
||||
}
|
||||
} catch (e) {
|
||||
// 保持默认mock数据
|
||||
setOverallScore(0);
|
||||
setRadarData(getEmptyCompetitivenessRadar());
|
||||
}
|
||||
};
|
||||
|
||||
const handleCollect = async () => {
|
||||
// 检查用户是否登录
|
||||
const token = getAccessToken();
|
||||
if (!token) {
|
||||
message.warning('请先登录');
|
||||
history.push(PageEnum.LOGIN);
|
||||
if (!ensureJobPortalLogin('收藏职位')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是取消收藏,调用取消收藏接口
|
||||
if (isFavorited) {
|
||||
// 获取用户ID
|
||||
const userId = getUserIdFromCache();
|
||||
if (!userId) {
|
||||
message.warning('无法获取用户信息,请重新登录');
|
||||
history.push(PageEnum.LOGIN);
|
||||
window.location.href = PORTAL_LOGIN_URL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -307,12 +343,10 @@ const JobDetailPage: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是收藏,调用收藏接口
|
||||
// 获取用户ID
|
||||
const userId = getUserIdFromCache();
|
||||
if (!userId) {
|
||||
message.warning('无法获取用户信息,请重新登录');
|
||||
history.push(PageEnum.LOGIN);
|
||||
window.location.href = PORTAL_LOGIN_URL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -342,19 +376,14 @@ const JobDetailPage: React.FC = () => {
|
||||
};
|
||||
|
||||
const handleApply = async () => {
|
||||
// 检查用户是否登录
|
||||
const token = getAccessToken();
|
||||
if (!token) {
|
||||
message.warning('请先登录');
|
||||
history.push(PageEnum.LOGIN);
|
||||
if (!ensureJobPortalLogin('申请职位')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取用户ID
|
||||
const userId = getUserIdFromCache();
|
||||
if (!userId) {
|
||||
message.warning('无法获取用户信息,请重新登录');
|
||||
history.push(PageEnum.LOGIN);
|
||||
window.location.href = PORTAL_LOGIN_URL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -471,12 +500,10 @@ const JobDetailPage: React.FC = () => {
|
||||
<Title level={4} style={{ margin: 0 }}>
|
||||
{jobDetail.companyInfo.name}
|
||||
</Title>
|
||||
<Space className="company-meta">
|
||||
<Text>{jobDetail.companyInfo.type}</Text>
|
||||
<Divider type="vertical" />
|
||||
<Text>{jobDetail.companyInfo.scale}</Text>
|
||||
<Divider type="vertical" />
|
||||
<Text>{jobDetail.companyInfo.industry}</Text>
|
||||
<Space className="company-meta" split={<Divider type="vertical" />}>
|
||||
{companyMetaItems.map((label) => (
|
||||
<Text key={label}>{label}</Text>
|
||||
))}
|
||||
</Space>
|
||||
</div>
|
||||
</Space>
|
||||
|
||||
Reference in New Issue
Block a user