简历筛选功能开发
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
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
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:
@@ -2,7 +2,7 @@ import React, { Fragment, useEffect, useRef, useState } from 'react';
|
||||
import { FormattedMessage, useAccess, useParams } from '@umijs/max';
|
||||
import { Button, FormInstance, message, Tag } from 'antd';
|
||||
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
|
||||
import { FormOutlined, PlusOutlined, AlignLeftOutlined, SendOutlined } from '@ant-design/icons';
|
||||
import { FormOutlined, PlusOutlined, AlignLeftOutlined, SendOutlined, FilterOutlined } from '@ant-design/icons';
|
||||
import { getDictValueEnum } from '@/services/system/dict';
|
||||
import DictTag from '@/components/DictTag';
|
||||
import { exportCmsAppUserExport } from '@/services/mobileusers/list';
|
||||
@@ -16,6 +16,7 @@ import Detail from './detail';
|
||||
import Hire from './hire';
|
||||
import ResumeView from './resumeView';
|
||||
import InterviewInvite from '../ResumeRecommend/InterviewInvite';
|
||||
import ResumeFilter from './resumeFilter';
|
||||
|
||||
|
||||
const handleExport = async (values: API.MobileUser.ListParams) => {
|
||||
@@ -53,6 +54,7 @@ function ManagementList() {
|
||||
const [matchingDegree, setMatchingDegree] = useState<any>(null);
|
||||
const [resumeVisible, setResumeVisible] = useState<boolean>(false);
|
||||
const [inviteVisible, setInviteVisible] = useState<boolean>(false);
|
||||
const [filterVisible, setFilterVisible] = useState<boolean>(false);
|
||||
const [hireAdd, setHireAdd] = useState<any>(null);
|
||||
const [mode, setMode] = useState<'view' | 'edit' | 'create'>('create');
|
||||
const params = useParams();
|
||||
@@ -250,6 +252,21 @@ function ManagementList() {
|
||||
>
|
||||
查看匹配详情
|
||||
</Button>
|
||||
</div>,
|
||||
<div key="second-row" style={{display: 'flex', justifyContent: 'center'}}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
key="resume-filter"
|
||||
icon={<FilterOutlined/>}
|
||||
hidden={!access.hasPerms('cms:jobApply:filterQzz')}
|
||||
onClick={() => {
|
||||
setCurrentRow(record);
|
||||
setFilterVisible(true);
|
||||
}}
|
||||
>
|
||||
简历筛选
|
||||
</Button>
|
||||
</div>
|
||||
],
|
||||
},
|
||||
@@ -353,6 +370,18 @@ function ManagementList() {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<ResumeFilter
|
||||
open={filterVisible}
|
||||
applyId={currentRow?.applyId}
|
||||
userName={currentRow?.name}
|
||||
onClose={(needRefresh) => {
|
||||
setFilterVisible(false);
|
||||
setCurrentRow(undefined);
|
||||
if (needRefresh) {
|
||||
actionRef.current?.reload();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
119
src/pages/Management/List/SeeMatching/resumeFilter.tsx
Normal file
119
src/pages/Management/List/SeeMatching/resumeFilter.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import { Modal, Form, Radio, Select, message } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { filterQzz } from '@/services/Management/list';
|
||||
import { getDictValueEnum } from '@/services/system/dict';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
export type ResumeFilterProps = {
|
||||
onClose: (needRefresh?: boolean) => void;
|
||||
open: boolean;
|
||||
applyId?: string;
|
||||
userName?: string;
|
||||
};
|
||||
|
||||
const ResumeFilter: React.FC<ResumeFilterProps> = (props) => {
|
||||
const { open, applyId, userName } = props;
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const [submitting, setSubmitting] = useState<boolean>(false);
|
||||
const [filterStatus, setFilterStatus] = useState<string>('0');
|
||||
const [reasonEnum, setReasonEnum] = useState<any>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
form.resetFields();
|
||||
setFilterStatus('0');
|
||||
// 加载不通过筛选原因的字典
|
||||
getDictValueEnum('resume_file_type', false, true).then((data) => {
|
||||
setReasonEnum(data);
|
||||
});
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
setSubmitting(true);
|
||||
|
||||
const payload: { id: string; filterStatus: string; filterReason?: string } = {
|
||||
id: applyId || '',
|
||||
filterStatus: values.filterStatus,
|
||||
};
|
||||
|
||||
// 如果不通过筛选,拼接原因
|
||||
if (values.filterStatus === '2' && values.filterReason && values.filterReason.length > 0) {
|
||||
payload.filterReason = values.filterReason.join('、');
|
||||
}
|
||||
|
||||
const response = await filterQzz(payload);
|
||||
if (response.code === 200) {
|
||||
message.success('简历筛选完成');
|
||||
form.resetFields();
|
||||
props.onClose(true);
|
||||
} else {
|
||||
message.error(response.msg || '筛选失败');
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errMsg = error?.response?.data?.msg || error?.message || '简历筛选失败';
|
||||
message.error(errMsg);
|
||||
console.error('简历筛选失败:', error);
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
onCancel={() => props.onClose()}
|
||||
title={`简历筛选${userName ? ` - ${userName}` : ''}`}
|
||||
width={520}
|
||||
onOk={handleSubmit}
|
||||
confirmLoading={submitting}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
initialValues={{ filterStatus: '0' }}
|
||||
>
|
||||
<Form.Item
|
||||
name="filterStatus"
|
||||
label="筛选结果"
|
||||
rules={[{ required: true, message: '请选择筛选结果' }]}
|
||||
>
|
||||
<Radio.Group
|
||||
onChange={(e) => setFilterStatus(e.target.value)}
|
||||
>
|
||||
<Radio value="0">通过筛选</Radio>
|
||||
<Radio value="2">不通过筛选</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
|
||||
{filterStatus === '2' && (
|
||||
<Form.Item
|
||||
name="filterReason"
|
||||
label="不通过原因"
|
||||
rules={[{ required: true, message: '请选择或输入不通过原因' }]}
|
||||
>
|
||||
<Select
|
||||
mode="tags"
|
||||
placeholder="请选择或输入不通过原因,按回车添加"
|
||||
style={{ width: '100%' }}
|
||||
tokenSeparators={['、', ',', ',']}
|
||||
>
|
||||
{Object.keys(reasonEnum).map((key) => (
|
||||
<Option key={key} value={reasonEnum[key].text}>
|
||||
{reasonEnum[key].text}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResumeFilter;
|
||||
Reference in New Issue
Block a user