diff --git a/config/routes.ts b/config/routes.ts
index 40a9833..e0d66b9 100644
--- a/config/routes.ts
+++ b/config/routes.ts
@@ -88,6 +88,10 @@ export default [
path: '/job-portal/personal-center/complaints', // 我的投诉
component: './JobPortal/PersonalCenter/Complaints',
},
+ {
+ path: '/job-portal/personal-center/blocked-companies', // 屏蔽企业列表
+ component: './JobPortal/PersonalCenter/BlockedCompanies',
+ },
{
path: '/job-portal/message', // 消息通知页面
component: './JobPortal/Message',
diff --git a/src/pages/JobPortal/Detail/index.less b/src/pages/JobPortal/Detail/index.less
index 84338b5..e309ea7 100644
--- a/src/pages/JobPortal/Detail/index.less
+++ b/src/pages/JobPortal/Detail/index.less
@@ -128,6 +128,12 @@
}
}
+ .company-block-action {
+ flex-shrink: 0;
+ margin-left: auto;
+ align-self: center;
+ }
+
.company-section-divider {
margin: 18px 0 16px;
}
diff --git a/src/pages/JobPortal/Detail/index.tsx b/src/pages/JobPortal/Detail/index.tsx
index 7855ebe..339f835 100644
--- a/src/pages/JobPortal/Detail/index.tsx
+++ b/src/pages/JobPortal/Detail/index.tsx
@@ -11,7 +11,8 @@ import {
Progress,
Divider,
Avatar,
- message
+ message,
+ Modal
} from 'antd';
import {
ArrowLeftOutlined,
@@ -23,7 +24,8 @@ import {
TrophyOutlined,
FireOutlined,
StarOutlined,
- FlagOutlined
+ FlagOutlined,
+ StopOutlined
} from '@ant-design/icons';
import { Radar } from '@ant-design/charts';
import JobPortalHeader from '@/components/JobPortalHeader';
@@ -33,7 +35,7 @@ import {
getEmptyCompetitivenessRadar,
} from '@/services/jobportal/competitiveness';
import { isJobPortalLoggedIn } from '@/utils/jobPortalAuth';
-import { favoriteJob, unfavoriteJob, applyJob, browseJob, getJobDetail } from '@/services/jobportal/user';
+import { favoriteJob, unfavoriteJob, applyJob, browseJob, getJobDetail, blockCompany } from '@/services/jobportal/user';
import { ensureJobPortalLogin, requireJobPortalUserId } from '@/utils/jobPortalAuth';
import { getDictLabel, resolveIndustryLabel } from '@/utils/jobPortalDict';
import JobComplaintModal from '@/components/JobComplaintModal';
@@ -444,6 +446,37 @@ const JobDetailPage: React.FC = () => {
}
};
+ const handleBlockCompany = async () => {
+ const companyId = originalJobData?.companyId || originalJobData?.companyVo?.companyId;
+ if (!companyId) {
+ message.error('未获取到企业信息');
+ return;
+ }
+ const userId = await requireJobPortalUserId('屏蔽企业');
+ if (!userId) {
+ return;
+ }
+ Modal.confirm({
+ title: '屏蔽该企业',
+ content: '确定要屏蔽该企业吗?屏蔽后将不再收到该企业的招聘信息。',
+ okText: '确定屏蔽',
+ cancelText: '取消',
+ okButtonProps: { danger: true },
+ onOk: async () => {
+ try {
+ const res = await blockCompany({ userId, companyId });
+ if (res?.code === 200) {
+ message.success('已屏蔽该企业');
+ } else {
+ message.error(res?.msg || '屏蔽失败,请稍后重试');
+ }
+ } catch {
+ message.error('操作失败,请稍后重试');
+ }
+ },
+ });
+ };
+
return (
@@ -551,6 +584,15 @@ const JobDetailPage: React.FC = () => {
)}
+
+ }
+ onClick={handleBlockCompany}
+ >
+ 屏蔽该企业
+
+
diff --git a/src/pages/JobPortal/List/index.less b/src/pages/JobPortal/List/index.less
index 6e5637f..4e84c2e 100644
--- a/src/pages/JobPortal/List/index.less
+++ b/src/pages/JobPortal/List/index.less
@@ -317,6 +317,12 @@
}
}
+ .company-block-action {
+ flex-shrink: 0;
+ margin-left: auto;
+ align-self: center;
+ }
+
.company-section-divider {
margin: 18px 0 16px;
}
diff --git a/src/pages/JobPortal/List/index.tsx b/src/pages/JobPortal/List/index.tsx
index 750e755..6f77075 100644
--- a/src/pages/JobPortal/List/index.tsx
+++ b/src/pages/JobPortal/List/index.tsx
@@ -11,7 +11,8 @@ import {
Button,
Select,
Input,
- message
+ message,
+ Modal
} from 'antd';
import {
EnvironmentOutlined,
@@ -21,12 +22,13 @@ import {
FlagOutlined,
ArrowLeftOutlined,
SearchOutlined,
- TrophyOutlined
+ TrophyOutlined,
+ StopOutlined
} from '@ant-design/icons';
import { history, useLocation } from '@umijs/max';
import { getJobList, getJobRecommend } from '@/services/common/jobTitle';
import JobPortalHeader from '@/components/JobPortalHeader';
-import { favoriteJob, unfavoriteJob, applyJob, browseJob } from '@/services/jobportal/user';
+import { favoriteJob, unfavoriteJob, applyJob, browseJob, blockCompany } from '@/services/jobportal/user';
import { ensureJobPortalLogin, requireJobPortalUserId } from '@/utils/jobPortalAuth';
import { getDictValueEnum } from '@/services/system/dict';
import { getDictLabel, findTreeLabelById, resolveIndustryLabel } from '@/utils/jobPortalDict';
@@ -525,6 +527,37 @@ const JobListPage: React.FC = () => {
}
};
+ const handleBlockCompany = async () => {
+ const companyId = selectedJob?.companyId || selectedJob?.companyVo?.companyId;
+ if (!companyId) {
+ message.error('未获取到企业信息');
+ return;
+ }
+ const userId = await requireJobPortalUserId('屏蔽企业');
+ if (!userId) {
+ return;
+ }
+ Modal.confirm({
+ title: '屏蔽该企业',
+ content: '确定要屏蔽该企业吗?屏蔽后将不再收到该企业的招聘信息。',
+ okText: '确定屏蔽',
+ cancelText: '取消',
+ okButtonProps: { danger: true },
+ onOk: async () => {
+ try {
+ const res = await blockCompany({ userId, companyId });
+ if (res?.code === 200) {
+ message.success('已屏蔽该企业');
+ } else {
+ message.error(res?.msg || '屏蔽失败,请稍后重试');
+ }
+ } catch {
+ message.error('操作失败,请稍后重试');
+ }
+ },
+ });
+ };
+
// 处理搜索功能(服务端搜索,不再做客户端过滤)
const handleSearch = async () => {
const term = searchValue.trim();
@@ -975,6 +1008,15 @@ const JobListPage: React.FC = () => {
)}
+
+ }
+ onClick={handleBlockCompany}
+ >
+ 屏蔽该企业
+
+
diff --git a/src/pages/JobPortal/PersonalCenter/BlockedCompanies/index.less b/src/pages/JobPortal/PersonalCenter/BlockedCompanies/index.less
new file mode 100644
index 0000000..8f3eed6
--- /dev/null
+++ b/src/pages/JobPortal/PersonalCenter/BlockedCompanies/index.less
@@ -0,0 +1,79 @@
+@import '../../theme.less';
+
+.blocked-companies-page {
+ min-height: 100vh;
+ background: @jp-bg-page;
+ padding-bottom: 40px;
+
+ .blocked-companies-container {
+ .jp-page-container();
+ margin-top: 20px;
+ padding: 0 20px;
+ box-sizing: border-box;
+ }
+
+ .page-header {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 16px;
+
+ .back-btn {
+ flex-shrink: 0;
+ color: @jp-text-secondary;
+ padding: 0 8px;
+
+ &:hover {
+ color: @jp-primary;
+ }
+ }
+
+ .page-title {
+ margin: 0;
+ font-size: 20px;
+ font-weight: 600;
+ color: @jp-text-primary;
+ }
+ }
+
+ .list-card {
+ .jp-card-base();
+
+ .blocked-item {
+ padding: 16px 20px;
+
+ &:not(:last-child) {
+ border-bottom: 1px solid @jp-border;
+ }
+
+ .company-avatar {
+ width: 40px;
+ height: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #fff2f0;
+ border-radius: @jp-radius;
+ color: #ff4d4f;
+ font-size: 18px;
+ }
+
+ .company-name {
+ font-size: 15px;
+ color: @jp-text-primary;
+ }
+
+ .block-time {
+ font-size: 13px;
+ color: @jp-text-muted;
+ }
+ }
+ }
+}
+
+@media (max-width: 768px) {
+ .blocked-companies-page .blocked-companies-container {
+ padding: 0 12px;
+ margin-top: 12px;
+ }
+}
diff --git a/src/pages/JobPortal/PersonalCenter/BlockedCompanies/index.tsx b/src/pages/JobPortal/PersonalCenter/BlockedCompanies/index.tsx
new file mode 100644
index 0000000..ca19300
--- /dev/null
+++ b/src/pages/JobPortal/PersonalCenter/BlockedCompanies/index.tsx
@@ -0,0 +1,153 @@
+import React, { useState, useEffect } from 'react';
+import {
+ Card,
+ List,
+ Typography,
+ Button,
+ message,
+ Modal,
+ Spin,
+ Empty
+} from 'antd';
+import {
+ StopOutlined,
+ DeleteOutlined,
+ ArrowLeftOutlined
+} from '@ant-design/icons';
+import { history } from '@umijs/max';
+import JobPortalHeader from '@/components/JobPortalHeader';
+import { getBlockedCompanyList } from '@/services/jobportal/user';
+import { request } from '@umijs/max';
+import './index.less';
+
+const { Title, Text } = Typography;
+
+interface BlockedCompany {
+ id: number;
+ userId: number;
+ companyId: number;
+ companyName: string;
+ name: string;
+ createTime: string;
+ updateTime: string;
+}
+
+const BlockedCompaniesPage: React.FC = () => {
+ const [loading, setLoading] = useState(false);
+ const [dataSource, setDataSource] = useState
([]);
+ const [total, setTotal] = useState(0);
+
+ const fetchList = async () => {
+ setLoading(true);
+ try {
+ const res = await getBlockedCompanyList({ pageNum: 1, pageSize: 100 });
+ if (res?.code === 200) {
+ setDataSource((res as any)?.rows || []);
+ setTotal((res as any)?.total || 0);
+ } else {
+ message.error(res?.msg || '获取屏蔽企业列表失败');
+ }
+ } catch {
+ message.error('获取屏蔽企业列表失败');
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ fetchList();
+ }, []);
+
+ const handleCancelBlock = (record: BlockedCompany) => {
+ Modal.confirm({
+ title: '取消屏蔽',
+ content: `确定要取消屏蔽"${record.companyName}"吗?`,
+ okText: '确定取消',
+ cancelText: '取消',
+ onOk: async () => {
+ try {
+ const res = await request('/api/cms/blockCompany/' + record.id, {
+ method: 'DELETE',
+ });
+ if (res?.code === 200) {
+ message.success('已取消屏蔽');
+ setDataSource(prev => prev.filter(item => item.id !== record.id));
+ setTotal(prev => prev - 1);
+ } else {
+ message.error(res?.msg || '取消屏蔽失败');
+ }
+ } catch {
+ message.error('操作失败,请稍后重试');
+ }
+ },
+ });
+ };
+
+ return (
+
+
+
+
+
+ }
+ onClick={() => history.back()}
+ className="back-btn"
+ >
+ 返回
+
+
屏蔽企业
+
+
+
+
+ {dataSource.length === 0 && !loading ? (
+
+ ) : (
+ (
+ }
+ onClick={() => handleCancelBlock(item)}
+ >
+ 取消屏蔽
+
+ ]}
+ >
+
+
+
+ }
+ title={
+
+ {item.companyName}
+
+ }
+ description={
+
+ 屏蔽时间:{item.createTime}
+
+ }
+ />
+
+ )}
+ />
+ )}
+
+
+
+
+ );
+};
+
+export default BlockedCompaniesPage;
diff --git a/src/pages/JobPortal/PersonalCenter/index.less b/src/pages/JobPortal/PersonalCenter/index.less
index 63c906f..09a803e 100644
--- a/src/pages/JobPortal/PersonalCenter/index.less
+++ b/src/pages/JobPortal/PersonalCenter/index.less
@@ -97,6 +97,16 @@
}
.stats-section {
+ .stats-row {
+ flex-wrap: nowrap;
+ justify-content: space-around;
+ }
+
+ .stat-col {
+ flex: 1 1 0;
+ min-width: 0;
+ }
+
.stat-item {
text-align: center;
cursor: pointer;
diff --git a/src/pages/JobPortal/PersonalCenter/index.tsx b/src/pages/JobPortal/PersonalCenter/index.tsx
index d7006b1..35ea3ce 100644
--- a/src/pages/JobPortal/PersonalCenter/index.tsx
+++ b/src/pages/JobPortal/PersonalCenter/index.tsx
@@ -138,6 +138,7 @@ const PersonalCenter: React.FC = () => {
footprints: 0,
appointments: 0,
complaints: 0,
+ blockedCompanies: 0,
});
useEffect(() => {
@@ -151,6 +152,7 @@ const PersonalCenter: React.FC = () => {
footprints: Number(response.data.yzj) || 0,
appointments: Number(response.data.yyy) || 0,
complaints: Number(response.data.yts) || 0,
+ blockedCompanies: Number(response.data.ypbqys) || 0,
});
}
} catch (error) {
@@ -269,8 +271,8 @@ const PersonalCenter: React.FC = () => {
-
-
+
+
history.push('/job-portal/personal-center/applications')}
@@ -279,7 +281,7 @@ const PersonalCenter: React.FC = () => {
投递
-
+
history.push('/job-portal/personal-center/favorites')}
@@ -288,7 +290,7 @@ const PersonalCenter: React.FC = () => {
收藏
-
+
history.push('/job-portal/personal-center/footprints')}
@@ -297,7 +299,7 @@ const PersonalCenter: React.FC = () => {
足迹
-
+
history.push('/job-portal/personal-center/complaints')}
@@ -306,6 +308,15 @@ const PersonalCenter: React.FC = () => {
投诉
+
+ history.push('/job-portal/personal-center/blocked-companies')}
+ >
+
{statistics.blockedCompanies || 0}
+
屏蔽企业
+
+
diff --git a/src/services/jobportal/user.ts b/src/services/jobportal/user.ts
index 5f4c442..5430411 100644
--- a/src/services/jobportal/user.ts
+++ b/src/services/jobportal/user.ts
@@ -182,3 +182,22 @@ export async function submitJobComplaint(params: {
});
}
+/** 屏蔽企业 POST /cms/blockCompany */
+export async function blockCompany(params: { userId: number; companyId: number }) {
+ return request('/api/cms/blockCompany', {
+ method: 'POST',
+ data: params,
+ });
+}
+
+/** 获取屏蔽企业列表 GET /cms/blockCompany/list */
+export async function getBlockedCompanyList(params?: { pageNum?: number; pageSize?: number }) {
+ return request('/api/cms/blockCompany/list', {
+ method: 'GET',
+ params: {
+ pageNum: params?.pageNum || 1,
+ pageSize: params?.pageSize || 10,
+ },
+ });
+}
+
diff --git a/src/types/jobportal/user.d.ts b/src/types/jobportal/user.d.ts
index 58d9e65..437c9a8 100644
--- a/src/types/jobportal/user.d.ts
+++ b/src/types/jobportal/user.d.ts
@@ -73,6 +73,7 @@ declare namespace API {
yzj?: string; // 足迹
yyy?: string; // 预约
yts?: string; // 投诉
+ ypbqys?: string; // 屏蔽企业数
}
export interface AppUserYhscResult {