flat: 暂存

This commit is contained in:
史典卓
2025-03-28 15:30:35 +08:00
parent 2bf8cf55ac
commit b3238e5c2b
50 changed files with 3302 additions and 416 deletions

View File

@@ -0,0 +1,74 @@
import { Modal } from 'antd';
import React, { useEffect, useRef } from 'react';
import * as echarts from 'echarts';
export type ListFormProps = {
onClose: (flag?: boolean, formVals?: unknown) => void;
open: boolean;
values?: Partial<API.MobileUser.ListRow>;
matching?: any;
};
const listEdit: React.FC<ListFormProps> = (props) => {
const { open, values, matching } = props;
const mapRef = useRef(null);
useEffect(() => {
console.log(matching);
if (matching && open) {
const myCharts = echarts.init(mapRef.current);
const { educationMatch, maxSimilarity, salaryMatch, areaMatch } = matching;
// educationMatch
// maxSimilarity
// salaryMatch
// areaMatch
myCharts.setOption({
radar: {
shape: 'circle',
indicator: [
{ name: '学历', max: 1 },
{ name: '薪资', max: 1 },
{ name: '区域', max: 1 },
{ name: '内容', max: 1 },
],
},
series: [
{
name: '综合匹配度',
type: 'radar',
data: [
{
value: [educationMatch, salaryMatch, areaMatch, maxSimilarity],
name: 'Allocated Budget',
},
],
},
],
});
}
}, [matching]);
return (
<Modal
title="匹配详情"
width={400}
open={props.open}
footer={''}
onCancel={() => props.onClose()}
maskClosable={true}
>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div style={{ width: '300px', height: '300px' }} ref={mapRef}></div>
</div>
</Modal>
);
};
export default listEdit;

View File

@@ -0,0 +1,235 @@
import React, { Fragment, useEffect, useRef, useState } from 'react';
import { FormattedMessage, useAccess, useParams } from '@umijs/max';
import { Button, FormInstance, message } from 'antd';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { FormOutlined, PlusOutlined } from '@ant-design/icons';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
import { exportCmsAppUserExport } from '@/services/mobileusers/list';
import { exportCmsJobCandidates, getCmsJobIds } from '@/services/Management/list';
import similarityJobs from '@/utils/similarity_Job';
import Detail from './detail';
const handleExport = async (values: API.MobileUser.ListParams) => {
const hide = message.loading('正在导出');
try {
await exportCmsAppUserExport(values);
hide();
message.success('导出成功');
return true;
} catch (error) {
hide();
message.error('导出失败,请重试');
return false;
}
};
function ManagementList() {
const access = useAccess();
const formTableRef = useRef<FormInstance>();
const actionRef = useRef<ActionType>();
const [jobId, setJobId] = useState<string>();
const [educationEnum, setEducationEnum] = useState<any>([]);
const [experienceEnum, setExperienceEnum] = useState<any>([]);
const [areaEnum, setAreaEnum] = useState<any>([]);
const [sexEnum, setSexEnum] = useState<any>([]);
const [hotEnum, setHotEnum] = useState<any>([]);
const [politicalEnum, setPoliticalEnum] = useState<any>([]);
const [currentRow, setCurrentRow] = useState<API.MobileUser.ListRow>();
const [modalVisible, setModalVisible] = useState<boolean>(false);
const [jobInfo, setJobInfo] = useState({});
const [matchingDegree, setMatchingDegree] = useState<any>(null);
const params = useParams();
const id = params.id || '0';
useEffect(() => {
if (jobId !== id) {
setJobId(id);
getJobInfo(id);
}
}, [jobId, params]);
const getJobInfo = async (jobId: string) => {
let resData = await getCmsJobIds(jobId);
if (resData.code === 200) {
similarityJobs.setJobInfo(resData.data);
setJobInfo(resData.data);
}
};
useEffect(() => {
getDictValueEnum('education', true, true).then((data) => {
setEducationEnum(data);
});
getDictValueEnum('experience', true, true).then((data) => {
setExperienceEnum(data);
});
getDictValueEnum('area', true, true).then((data) => {
setAreaEnum(data);
});
getDictValueEnum('sys_user_sex', true).then((data) => {
setSexEnum(data);
});
getDictValueEnum('political_affiliation', true, true).then((data) => {
setPoliticalEnum(data);
});
}, []);
const columns: ProColumns<API.MobileUser.ListRow>[] = [
{
title: '用户名',
dataIndex: 'name',
valueType: 'text',
align: 'center',
},
{
title: '期望薪资',
dataIndex: 'minSalary',
valueType: 'text',
hideInSearch: true,
align: 'center',
render: (_, record) => (
<>
{record.salaryMin}-{record.salaryMax}
</>
),
},
{
title: '出生日期',
dataIndex: 'birthDate',
valueType: 'text',
align: 'center',
hideInSearch: true,
},
{
title: '学历要求',
dataIndex: 'education',
valueType: 'select',
align: 'center',
valueEnum: educationEnum,
render: (_, record) => {
return <DictTag enums={educationEnum} value={record.education} />;
},
},
{
title: '区域',
dataIndex: 'area',
valueType: 'select',
align: 'center',
valueEnum: areaEnum,
render: (_, record) => {
return <DictTag enums={areaEnum} value={record.area} />;
},
},
{
title: '性别',
dataIndex: 'sex',
valueType: 'select',
align: 'center',
valueEnum: sexEnum,
render: (_, record) => {
return <DictTag enums={sexEnum} value={record.sex} />;
},
},
{
title: '政治面貌',
dataIndex: 'politicalAffiliation',
valueType: 'select',
align: 'center',
valueEnum: politicalEnum,
render: (_, record) => {
return <DictTag enums={politicalEnum} value={record.politicalAffiliation} />;
},
},
{
title: '匹配度',
dataIndex: 'minSalary',
valueType: 'text',
hideInSearch: true,
align: 'center',
render: (_, record) => (
<>{similarityJobs.calculationMatchingDegreeJob(record).overallMatch}</>
),
},
{
title: '操作',
hideInSearch: true,
align: 'center',
dataIndex: 'jobId',
width: 200,
render: (jobId, record) => [
<Button
type="link"
size="small"
key="edit"
icon={<FormOutlined />}
hidden={!access.hasPerms('area:business:List.update')}
onClick={() => {
setModalVisible(true);
setCurrentRow(record);
const val = similarityJobs.calculationMatchingDegreeJob(record);
setMatchingDegree(val);
}}
>
</Button>,
],
},
];
return (
<Fragment>
<div style={{ width: '100%', float: 'right' }}>
<ProTable<API.MobileUser.ListRow>
// params 是需要自带的参数
// 这个参数优先级更高,会覆盖查询表单的参数
actionRef={actionRef}
formRef={formTableRef}
rowKey="jobId"
key="index"
columns={columns}
request={(params) =>
exportCmsJobCandidates(jobId).then((res) => {
// const v = similarityJobs.calculationMatchingDegreeJob(res.rows[0]);
// console.log(v);
const result = {
data: res.rows,
total: res.total,
success: true,
};
return result;
})
}
toolBarRender={() => [
<Button
type="primary"
key="export"
hidden={!access.hasPerms('system:user:export')}
onClick={async () => {
const searchVal = formTableRef.current && formTableRef.current.getFieldsValue();
handleExport(searchVal as API.MobileUser.ListParams);
}}
>
<PlusOutlined />
<FormattedMessage id="pages.searchTable.export" defaultMessage="导出" />
</Button>,
]}
/>
<Detail
values={currentRow}
open={modalVisible}
matching={matchingDegree}
onClose={() => {
console.log('close');
setModalVisible(false);
setCurrentRow(undefined);
setMatchingDegree(null);
}}
></Detail>
</div>
</Fragment>
);
}
export default ManagementList;

View File

@@ -1,21 +1,24 @@
import { PlusOutlined } from '@ant-design/icons';
import {
ModalForm,
ProForm,
ProFormDateRangePicker,
ProFormDigit,
ProFormSelect,
ProFormText,
ProFormTextArea,
} from '@ant-design/pro-components';
import { Button, Form, message } from 'antd';
import {DictOptionType, DictValueEnumObj} from "@/components/DictTag";
import { Form } from 'antd';
import React, { useEffect } from 'react';
import { DictValueEnumObj } from '@/components/DictTag';
import { getCmsCompanyList } from '@/services/company/list';
export type ListFormProps = {
onCancel: (flag?: boolean, formVals?: unknown) => void;
onSubmit: (values: API.ManagementList.Manage) => Promise<void>;
open: boolean;
// values: Partial<API.Management.Manage>;
// jobGroupOptions: DictOptionType[];
// statusOptions: DictValueEnumObj;
values?: Partial<API.ManagementList.Manage>;
educationEnum: DictValueEnumObj;
experienceEnum: DictValueEnumObj;
areaEnum: DictValueEnumObj;
};
const waitTime = (time: number = 100) => {
@@ -27,7 +30,17 @@ const waitTime = (time: number = 100) => {
};
const listEdit: React.FC<ListFormProps> = (props) => {
const [form] = Form.useForm<{ name: string; company: string }>();
const [form] = Form.useForm<{ name: string; company: string; companyName: number }>();
const { educationEnum, experienceEnum, areaEnum } = props;
useEffect(() => {
form.resetFields();
if (props.values) {
form.setFieldsValue({
...props.values,
jobLocationAreaCode: String(props.values.jobLocationAreaCode || ''),
});
}
}, [form, props]);
const handleCancel = () => {
props.onCancel();
@@ -38,6 +51,10 @@ const listEdit: React.FC<ListFormProps> = (props) => {
props.onSubmit(values as API.ManagementList.Manage);
};
const handleChange = (_: string, value: any) => {
form.setFieldValue('companyName', value.label);
};
return (
<ModalForm<{
name: string;
@@ -55,71 +72,87 @@ const listEdit: React.FC<ListFormProps> = (props) => {
onFinish={handleFinish}
>
<ProForm.Group>
<ProFormText
<ProFormText width="md" hidden name="jobId" />
<ProFormText width="md" hidden name="companyName" />
<ProFormText width="md" name="jobTitle" label="岗位名称" placeholder="请输入岗位名称" />
<ProFormSelect
showSearch
width="md"
name="jobTitle"
label="岗位名称"
placeholder="请输入名称"
name="companyId"
onChange={handleChange}
request={async ({ keyWords }) => {
let resData = await getCmsCompanyList({ name: keyWords });
return resData.rows.map((item) => ({ label: item.name, value: item.companyId }));
}}
placeholder="请输入公司名称选择公司"
rules={[{ required: true, message: '请输入公司名称选择公司!' }]}
label="招聘会公司"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
width="md"
<ProFormDigit
name="minSalary"
label="最小薪资"
width="md"
min={0}
label="最小薪资(元/月)"
placeholder="请输入最小薪资(元)"
/>
<ProFormText
width="md"
<ProFormDigit
name="maxSalary"
label="最大薪资"
width="md"
min={0}
label="最大薪资(元/月)"
placeholder="请输入最大薪资(元)"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
<ProFormSelect
width="md"
name="education"
label="学历要求"
placeholder="请输入学历要求"
label={'学历要求'}
valueEnum={educationEnum}
placeholder="请选择学历要求"
rules={[{ required: true, message: '请选择学历要求!' }]}
/>
<ProFormText
<ProFormSelect
width="md"
name="experience"
label="工作经验"
placeholder="请输入工作经验"
label={'工作经验'}
valueEnum={experienceEnum}
placeholder="请选择岗位"
rules={[{ required: true, message: '请选择工作经验!' }]}
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
<ProFormSelect
width="md"
name="companyName"
label="单位名称"
placeholder="请输入单位名称"
name="jobLocationAreaCode"
label={'工作区县'}
valueEnum={areaEnum}
placeholder="请选择区县"
rules={[{ required: true, message: '请选择区县!' }]}
/>
<ProFormText
width="md"
name="jobLocation"
label="工作地点"
placeholder="请输入工作地点"
/>
</ProForm.Group>
<ProForm.Group>
<ProFormText
width="md"
name="vacancies"
<ProFormDigit
label="招聘人数"
name="vacancies"
width="md"
min={0}
placeholder="请输入招聘人数"
/>
<ProFormText
width="md"
name="jobLocation"
label="工作地点"
placeholder="请输入工作地点"
</ProForm.Group>
<ProForm.Group>
<ProFormText width="lg" name="jobLocation" label="工作地点" placeholder="请输入工作地点" />
</ProForm.Group>
<ProForm.Group>
<ProFormTextArea
width="lg"
name="description"
label="岗位描述"
placeholder="请输入岗位描述"
/>
</ProForm.Group>
</ModalForm>
);
};
export default listEdit
export default listEdit;

View File

@@ -1,13 +1,33 @@
import React, {Fragment, useRef, useState, useEffect} from "react";
import { useIntl, FormattedMessage, useAccess, history } from '@umijs/max';
import {delCmsJobIds, getCmsJobList} from "@/services/Management/list";
import { Dropdown, FormInstance, Space, Button, message, Modal } from 'antd';
import { ActionType, FooterToolbar, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
import { PlusOutlined, DeleteOutlined, FormOutlined, DownOutlined, EditOutlined } from '@ant-design/icons';
import EditManageRow from './edit'
import {getDictValueEnum} from "@/services/system/dict";
import DictTag from "@/components/DictTag";
import React, { Fragment, useEffect, useRef, useState } from 'react';
import { FormattedMessage, history, useAccess } from '@umijs/max';
import {
addCmsJobList,
delCmsJobIds,
exportCmsJob,
getCmsJobList,
updateCmsJobList,
} from '@/services/Management/list';
import { Button, FormInstance, message, Modal, Switch } from 'antd';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { BarChartOutlined, DeleteOutlined, FormOutlined, PlusOutlined } from '@ant-design/icons';
import EditManageRow from './edit';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
const handleExport = async (values: API.ManagementList.ListParams) => {
const hide = message.loading('正在导出');
try {
await exportCmsJob(values);
hide();
message.success('导出成功');
return true;
} catch (error) {
hide();
message.error('导出失败,请重试');
return false;
}
};
const handleRemoveOne = async (jobId: string) => {
const hide = message.loading('正在删除');
if (!jobId) return true;
@@ -33,23 +53,44 @@ function ManagementList() {
const formTableRef = useRef<FormInstance>();
const actionRef = useRef<ActionType>();
const [educationEnum, setEducationEnum] = useState<any>([])
const [experienceEnum, setExperienceEnum] = useState<any>([])
const [hotEnum, setHotEnum] = useState<any>([])
const [currentRow, setCurrentRow] = useState<API.ManagementList.Manage>()
const [modalVisible, setModalVisible] = useState<boolean>(false)
const [educationEnum, setEducationEnum] = useState<any>([]);
const [experienceEnum, setExperienceEnum] = useState<any>([]);
const [areaEnum, setAreaEnum] = useState<any>([]);
const [isPublishEnum, setIsPublishEnum] = useState<any>([]);
const [hotEnum, setHotEnum] = useState<any>([]);
const [currentRow, setCurrentRow] = useState<API.ManagementList.Manage>();
const [modalVisible, setModalVisible] = useState<boolean>(false);
useEffect(() => {
getDictValueEnum('education',true).then((data) => {
setEducationEnum(data)
})
getDictValueEnum('experience',true).then((data) => {
setExperienceEnum(data)
})
getDictValueEnum('education', true, true).then((data) => {
setEducationEnum(data);
});
getDictValueEnum('experience', true, true).then((data) => {
setExperienceEnum(data);
});
getDictValueEnum('area', true, true).then((data) => {
setAreaEnum(data);
});
getDictValueEnum('is_publish', true).then((data) => {
setIsPublishEnum(data);
});
// getDictValueEnum('job_hot',true).then((data) => {
// setHotEnum(data)
// })
}, [])
}, []);
async function changeRelease(record: API.ManagementList.Manage) {
let resData = await updateCmsJobList({
jobId: record.jobId,
isPublish: record.isPublish === 1 ? 0 : 1,
});
if (resData.code === 200) {
message.success('修改成功');
if (actionRef.current) {
actionRef.current.reload();
}
}
}
const columns: ProColumns<API.ManagementList.Manage>[] = [
{
@@ -57,13 +98,18 @@ function ManagementList() {
dataIndex: 'jobTitle',
valueType: 'text',
align: 'center',
},{
},
{
title: '最大最小薪资',
dataIndex: 'maxSalary',
valueType: 'text',
hideInSearch: true,
align: 'center',
render: (_, record) => <>{record.minSalary}-{record.maxSalary}</>
render: (_, record) => (
<>
{record.minSalary}-{record.maxSalary}
</>
),
},
{
title: '单位名称',
@@ -78,18 +124,17 @@ function ManagementList() {
align: 'center',
valueEnum: educationEnum,
render: (_, record) => {
return (<DictTag enums={educationEnum} value={record.education} />);
return <DictTag enums={educationEnum} value={record.education} />;
},
},
{
title: '经验要求',
dataIndex: 'experience',
hideInSearch: true,
valueType: 'select',
align: 'center',
valueEnum: experienceEnum,
render: (_, record) => {
return (<DictTag enums={experienceEnum} value={record.experience} />);
return <DictTag enums={experienceEnum} value={record.experience} />;
},
},
// {
@@ -103,11 +148,14 @@ function ManagementList() {
// },
// },
{
title: '发布时间',
dataIndex: 'postingDate',
valueType: 'text',
hideInSearch: true,
title: '是否发布',
dataIndex: 'isPublish',
valueType: 'select',
align: 'center',
valueEnum: isPublishEnum,
render: (text, record) => (
<Switch checked={record.isPublish === 1} onChange={changeRelease.bind(null, record)} />
),
},
{
title: '招聘人数',
@@ -134,7 +182,17 @@ function ManagementList() {
type="link"
size="small"
key="edit"
icon={<FormOutlined/>}
icon={<BarChartOutlined />}
hidden={!access.hasPerms('area:business:List.update')}
onClick={() => history.push(`/management/see-matching/index/${record.jobId}`)}
>
</Button>,
<Button
type="link"
size="small"
key="edit"
icon={<FormOutlined />}
hidden={!access.hasPerms('area:business:List.update')}
onClick={() => {
setModalVisible(true);
@@ -148,7 +206,7 @@ function ManagementList() {
size="small"
danger
key="batchRemove"
icon ={<DeleteOutlined/>}
icon={<DeleteOutlined />}
hidden={!access.hasPerms('area:subway:List')}
onClick={async () => {
Modal.confirm({
@@ -168,10 +226,10 @@ function ManagementList() {
}}
>
</Button>
]
}
]
</Button>,
],
},
];
return (
<Fragment>
<div style={{ width: '100%', float: 'right' }}>
@@ -185,7 +243,7 @@ function ManagementList() {
columns={columns}
request={(params) =>
getCmsJobList({ ...params } as API.ManagementList.ListParams).then((res) => {
console.log(params)
console.log(params);
const result = {
data: res.rows,
total: res.total,
@@ -206,21 +264,54 @@ function ManagementList() {
>
<PlusOutlined />
</Button>,
<Button
type="primary"
key="export"
hidden={!access.hasPerms('system:user:export')}
onClick={async () => {
const searchVal = formTableRef.current && formTableRef.current.getFieldsValue();
handleExport(searchVal as API.ManagementList.ListParams);
}}
>
<PlusOutlined />
<FormattedMessage id="pages.searchTable.export" defaultMessage="导出" />
</Button>,
]}
/>
</div>
<EditManageRow
open={modalVisible}
onSubmit={(values) => {
console.log(values)
return Promise.resolve()
onSubmit={async (values) => {
let resData;
if (values.jobId) {
resData = await updateCmsJobList(values);
} else {
resData = await addCmsJobList(values);
}
if (resData.code === 200) {
setModalVisible(false);
setCurrentRow(undefined);
if (values.jobId) {
message.success('修改成功');
} else {
message.success('新增成功');
}
if (actionRef.current) {
actionRef.current.reload();
}
}
}}
values={currentRow}
onCancel={() => {
setModalVisible(false);
setCurrentRow(undefined);
}}
educationEnum={educationEnum}
experienceEnum={experienceEnum}
areaEnum={areaEnum}
></EditManageRow>
</Fragment>
)
);
}
export default ManagementList
export default ManagementList;