From ed37133c6948c6126db49665ea256a72f2f82f77 Mon Sep 17 00:00:00 2001 From: francis-fh Date: Thu, 25 Jun 2026 13:32:03 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9D=A2=E8=AF=95=E5=8A=9F=E8=83=BD=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.ts | 5 + .../PersonalCenter/Interviews/index.tsx | 45 ++++- src/pages/Management/InterviewList/index.tsx | 154 ++++++++++++++++++ .../Management/List/SeeMatching/index.tsx | 21 ++- .../List/SeeMatching/resumeView.tsx | 9 + src/pages/Management/List/edit.tsx | 4 +- src/services/Management/list.ts | 8 + src/types/Management/interview.d.ts | 3 + src/types/mobileusers/list.d.ts | 2 + 9 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 src/pages/Management/InterviewList/index.tsx diff --git a/config/routes.ts b/config/routes.ts index 48a75d5..8b945fa 100644 --- a/config/routes.ts +++ b/config/routes.ts @@ -189,6 +189,11 @@ export default [ path: '/management/see-matching/index/:id', component: './Management/List/SeeMatching', }, + { + name: '面试列表', + path: '/management/interview-list', + component: './Management/InterviewList', + }, ], }, { diff --git a/src/pages/JobPortal/PersonalCenter/Interviews/index.tsx b/src/pages/JobPortal/PersonalCenter/Interviews/index.tsx index 9e80321..44d46a1 100644 --- a/src/pages/JobPortal/PersonalCenter/Interviews/index.tsx +++ b/src/pages/JobPortal/PersonalCenter/Interviews/index.tsx @@ -8,6 +8,7 @@ import { Typography, Button, Empty, + Modal, message, Spin } from 'antd'; @@ -19,7 +20,7 @@ import { } from '@ant-design/icons'; import { history } from '@umijs/max'; import JobPortalHeader from '@/components/JobPortalHeader'; -import { getAppInterviewList } from '@/services/Management/list'; +import { getAppInterviewList, updateAppInterviewStatus } from '@/services/Management/list'; import './index.less'; const { Title, Text } = Typography; @@ -78,6 +79,27 @@ const InterviewsPage: React.FC = () => { } }; + const handleStatusUpdate = (interviewId: number, status: string, statusText: string) => { + Modal.confirm({ + title: '提示', + content: `确定${statusText}该面试邀约吗?`, + onOk: async () => { + try { + const response = await updateAppInterviewStatus(interviewId, status); + if (response.code === 200) { + message.success(status === 'accepted' ? '已接受面试邀请' : '已婉拒面试邀请'); + fetchInterviews(); + } else { + message.error(response.msg || '操作失败'); + } + } catch (error) { + console.error('更新面试状态失败:', error); + message.error('操作失败,请重试'); + } + }, + }); + }; + const handleBack = () => { history.push('/job-portal/personal-center'); }; @@ -131,7 +153,7 @@ const InterviewsPage: React.FC = () => { {item.interviewMethod === 'online' ? '线上' : '线下'} - {/* {st.text} */} + {st.text}
{item.interviewMethod === 'online' ? ( @@ -166,6 +188,25 @@ const InterviewsPage: React.FC = () => { 备注:{item.remark}
)} + {item.status === 'pending' && ( +
+ + + + +
+ )} diff --git a/src/pages/Management/InterviewList/index.tsx b/src/pages/Management/InterviewList/index.tsx new file mode 100644 index 0000000..8c4c2dd --- /dev/null +++ b/src/pages/Management/InterviewList/index.tsx @@ -0,0 +1,154 @@ +import React, { useRef } from 'react'; +import { Tag } from 'antd'; +import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components'; +import { getCmsInterviewList } from '@/services/Management/list'; + +const interviewStatusMap: Record = { + pending: { text: '待确认', color: 'blue' }, + accepted: { text: '已接受', color: 'green' }, + rejected: { text: '已拒绝', color: 'red' }, + completed: { text: '已完成', color: 'purple' }, +}; + +const interviewMethodMap: Record = { + online: { text: '线上', color: 'blue' }, + offline: { text: '线下', color: 'orange' }, +}; + +const InterviewList: React.FC = () => { + const actionRef = useRef(); + + const columns: ProColumns[] = [ + { + title: '求职者姓名', + dataIndex: 'applicantName', + valueType: 'text', + align: 'center', + width: 100, + render: (_, record) => record.applicantName || '-', + }, + { + title: '联系方式', + dataIndex: 'applicantPhone', + valueType: 'text', + align: 'center', + width: 130, + hideInSearch: true, + render: (_, record) => record.applicantPhone || '-', + }, + { + title: '应聘岗位', + dataIndex: 'jobTitle', + valueType: 'text', + align: 'center', + width: 150, + render: (_, record) => record.jobTitle || record.jobName || '-', + }, + { + title: '公司名称', + dataIndex: 'companyName', + valueType: 'text', + align: 'center', + width: 150, + hideInSearch: true, + }, + { + title: '面试时间', + dataIndex: 'interviewTime', + valueType: 'text', + align: 'center', + width: 160, + hideInSearch: true, + }, + { + title: '面试方式', + dataIndex: 'interviewMethod', + valueType: 'text', + align: 'center', + width: 80, + hideInSearch: true, + render: (_, record) => { + const m = interviewMethodMap[record.interviewMethod || '']; + if (!m) return '-'; + return {m.text}; + }, + }, + { + title: '面试官姓名', + dataIndex: 'interviewerName', + valueType: 'text', + align: 'center', + width: 100, + hideInSearch: true, + render: (_, record) => record.interviewerName || '-', + }, + { + title: '面试官联系方式', + dataIndex: 'contactPhone', + valueType: 'text', + align: 'center', + width: 140, + hideInSearch: true, + }, + { + title: '状态', + dataIndex: 'status', + valueType: 'text', + align: 'center', + width: 80, + render: (_, record) => { + const st = interviewStatusMap[record.status || '']; + if (!st) return 未知; + return {st.text}; + }, + }, + { + title: '备注', + dataIndex: 'remark', + valueType: 'text', + align: 'center', + width: 150, + hideInSearch: true, + render: (_, record) => record.remark || '-', + }, + { + title: '创建时间', + dataIndex: 'createTime', + valueType: 'text', + align: 'center', + width: 160, + hideInSearch: true, + }, + ]; + + return ( + + actionRef={actionRef} + rowKey="id" + columns={columns} + headerTitle="面试列表" + request={async (params) => { + const { current, pageSize, ...searchParams } = params; + const response = await getCmsInterviewList({ + ...searchParams, + pageNum: current, + pageSize, + }); + return { + data: response.rows || [], + total: response.total || 0, + success: true, + }; + }} + search={{ + labelWidth: 'auto', + }} + pagination={{ + defaultPageSize: 10, + showSizeChanger: true, + }} + /> + ); +}; + +export default InterviewList; diff --git a/src/pages/Management/List/SeeMatching/index.tsx b/src/pages/Management/List/SeeMatching/index.tsx index d085a97..794727d 100644 --- a/src/pages/Management/List/SeeMatching/index.tsx +++ b/src/pages/Management/List/SeeMatching/index.tsx @@ -1,6 +1,6 @@ import React, { Fragment, useEffect, useRef, useState } from 'react'; import { FormattedMessage, useAccess, useParams } from '@umijs/max'; -import { Button, FormInstance, message } from 'antd'; +import { Button, FormInstance, message, Tag } from 'antd'; import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components'; import { FormOutlined, PlusOutlined,AlignLeftOutlined } from '@ant-design/icons'; import { getDictValueEnum } from '@/services/system/dict'; @@ -167,6 +167,25 @@ function ManagementList() { <>{similarityJobs.calculationMatchingDegreeJob(record).overallMatch} ), }, + { + title: '面试状态', + dataIndex: 'interviewStatus', + valueType: 'text', + hideInSearch: true, + align: 'center', + width: 100, + render: (_, record) => { + const statusMap: Record = { + pending: { text: '待确认', color: 'blue' }, + accepted: { text: '已接受', color: 'green' }, + rejected: { text: '已拒绝', color: 'red' }, + completed: { text: '已完成', color: 'purple' }, + }; + const st = statusMap[record.interviewStatus || '']; + if (!st) return 未邀约; + return {st.text}; + }, + }, { title: '操作', hideInSearch: true, diff --git a/src/pages/Management/List/SeeMatching/resumeView.tsx b/src/pages/Management/List/SeeMatching/resumeView.tsx index 12e8b12..afdd374 100644 --- a/src/pages/Management/List/SeeMatching/resumeView.tsx +++ b/src/pages/Management/List/SeeMatching/resumeView.tsx @@ -102,6 +102,7 @@ const listEdit: React.FC = (props) => { meetingPassword: values.meetingPassword, interviewLocation: values.interviewLocation, contactPhone: values.contactPhone, + interviewerName: values.interviewerName, status: 'pending', remark: values.remark, }; @@ -250,6 +251,14 @@ const listEdit: React.FC = (props) => {