二次调研功能开发
Some checks are pending
Node CI / build (14.x, macOS-latest) (push) Waiting to run
Node CI / build (14.x, ubuntu-latest) (push) Waiting to run
Node CI / build (14.x, windows-latest) (push) Waiting to run
Node CI / build (16.x, macOS-latest) (push) Waiting to run
Node CI / build (16.x, ubuntu-latest) (push) Waiting to run
Node CI / build (16.x, windows-latest) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
coverage CI / build (push) Waiting to run
Node pnpm CI / build (16.x, macOS-latest) (push) Waiting to run
Node pnpm CI / build (16.x, ubuntu-latest) (push) Waiting to run
Node pnpm CI / build (16.x, windows-latest) (push) Waiting to run
Some checks are pending
Node CI / build (14.x, macOS-latest) (push) Waiting to run
Node CI / build (14.x, ubuntu-latest) (push) Waiting to run
Node CI / build (14.x, windows-latest) (push) Waiting to run
Node CI / build (16.x, macOS-latest) (push) Waiting to run
Node CI / build (16.x, ubuntu-latest) (push) Waiting to run
Node CI / build (16.x, windows-latest) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
coverage CI / build (push) Waiting to run
Node pnpm CI / build (16.x, macOS-latest) (push) Waiting to run
Node pnpm CI / build (16.x, ubuntu-latest) (push) Waiting to run
Node pnpm CI / build (16.x, windows-latest) (push) Waiting to run
This commit is contained in:
@@ -279,14 +279,14 @@ const JobPortalHeader: React.FC<JobPortalHeaderProps> = ({
|
|||||||
>
|
>
|
||||||
简历
|
简历
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
{/* <Button
|
||||||
type="text"
|
type="text"
|
||||||
icon={<FundProjectionScreenOutlined />}
|
icon={<FundProjectionScreenOutlined />}
|
||||||
onClick={() => handleNavClick('/job-portal/career-recommendation')}
|
onClick={() => handleNavClick('/job-portal/career-recommendation')}
|
||||||
className={`nav-btn${isCareerRecommend ? ' active' : ''}`}
|
className={`nav-btn${isCareerRecommend ? ' active' : ''}`}
|
||||||
>
|
>
|
||||||
职业推荐
|
职业推荐
|
||||||
</Button>
|
</Button> */}
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
icon={<ReadOutlined />}
|
icon={<ReadOutlined />}
|
||||||
|
|||||||
@@ -17,6 +17,16 @@ import { getDictValueEnum } from '@/services/system/dict';
|
|||||||
import DictTag from '@/components/DictTag';
|
import DictTag from '@/components/DictTag';
|
||||||
import { postCompanyApproval } from '@/services/company/review';
|
import { postCompanyApproval } from '@/services/company/review';
|
||||||
|
|
||||||
|
const buildListSearchParams = (values: Record<string, any>): API.CompanyList.Params => {
|
||||||
|
const { dateRange, ...rest } = values || {};
|
||||||
|
const params = { ...rest } as API.CompanyList.Params;
|
||||||
|
if (dateRange?.[0] && dateRange?.[1]) {
|
||||||
|
params.startDate = dateRange[0];
|
||||||
|
params.endDate = dateRange[1];
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
const loadCompanyDetail = async (record: API.CompanyList.Company) => {
|
const loadCompanyDetail = async (record: API.CompanyList.Company) => {
|
||||||
const resp = await getCmsCompanyDetail(record.companyId);
|
const resp = await getCmsCompanyDetail(record.companyId);
|
||||||
const detail = parseCmsCompanyDetailResponse(resp);
|
const detail = parseCmsCompanyDetailResponse(resp);
|
||||||
@@ -82,6 +92,21 @@ function ManagementList() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const columns: ProColumns<API.CompanyList.Company>[] = [
|
const columns: ProColumns<API.CompanyList.Company>[] = [
|
||||||
|
{
|
||||||
|
title: '时间范围',
|
||||||
|
dataIndex: 'dateRange',
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: 'dateRange',
|
||||||
|
fieldProps: {
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
transform: (value) => ({
|
||||||
|
startDate: value[0],
|
||||||
|
endDate: value[1],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '公司名称',
|
title: '公司名称',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -279,7 +304,7 @@ function ManagementList() {
|
|||||||
hidden={!access.hasPerms('system:user:export')}
|
hidden={!access.hasPerms('system:user:export')}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const searchVal = formTableRef.current?.getFieldsValue();
|
const searchVal = formTableRef.current?.getFieldsValue();
|
||||||
handleExport(searchVal as API.CompanyList.Params);
|
handleExport(buildListSearchParams(searchVal || {}));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PlusOutlined />
|
<PlusOutlined />
|
||||||
|
|||||||
@@ -552,19 +552,19 @@ const JobDetailPage: React.FC = () => {
|
|||||||
lineWidth: 2,
|
lineWidth: 2,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
meta={{
|
scale={{
|
||||||
score: {
|
y: {
|
||||||
alias: '评分',
|
domainMin: 0,
|
||||||
min: 0,
|
domainMax: 100,
|
||||||
max: 100,
|
|
||||||
nice: true,
|
nice: true,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
yAxis={{
|
axis={{
|
||||||
|
y: {
|
||||||
label: false,
|
label: false,
|
||||||
tickLine: null,
|
tick: false,
|
||||||
line: null,
|
line: false,
|
||||||
grid: null,
|
},
|
||||||
}}
|
}}
|
||||||
height={300}
|
height={300}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
ArrowLeftOutlined,
|
ArrowLeftOutlined,
|
||||||
CalendarOutlined,
|
CalendarOutlined,
|
||||||
EyeOutlined,
|
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
BankOutlined,
|
BankOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
@@ -140,9 +139,6 @@ const PolicyDetailPage: React.FC = () => {
|
|||||||
<BankOutlined /> {detail.sourceUnit}
|
<BankOutlined /> {detail.sourceUnit}
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
<Text type="secondary">
|
|
||||||
<EyeOutlined /> {detail.viewNum ?? 0} 次浏览
|
|
||||||
</Text>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{detail.zcContent?.trim() ? (
|
{detail.zcContent?.trim() ? (
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {
|
import {
|
||||||
CalendarOutlined,
|
CalendarOutlined,
|
||||||
EyeOutlined,
|
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
SearchOutlined,
|
SearchOutlined,
|
||||||
BankOutlined,
|
BankOutlined,
|
||||||
@@ -125,9 +124,6 @@ const PolicyListPage: React.FC = () => {
|
|||||||
<CalendarOutlined /> {item.publishTime}
|
<CalendarOutlined /> {item.publishTime}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<span>
|
|
||||||
<EyeOutlined /> {item.viewNum ?? 0} 次浏览
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</List.Item>
|
</List.Item>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useRef, useState, useEffect } from 'react';
|
import React, { useRef, useState, useEffect } from 'react';
|
||||||
import { useAccess, history } from '@umijs/max';
|
import { useAccess, history } from '@umijs/max';
|
||||||
import { Button, message, Modal } from 'antd';
|
import { Button, FormInstance, message, Modal } from 'antd';
|
||||||
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
|
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
|
||||||
import { PlusOutlined, DeleteOutlined, FormOutlined, ExportOutlined, EyeOutlined } from '@ant-design/icons';
|
import { PlusOutlined, DeleteOutlined, FormOutlined, ExportOutlined, EyeOutlined } from '@ant-design/icons';
|
||||||
import { getDictValueEnum } from '@/services/system/dict';
|
import { getDictValueEnum } from '@/services/system/dict';
|
||||||
@@ -17,6 +17,7 @@ import EditModal from './components/EditModal';
|
|||||||
|
|
||||||
const PublicJobFairList: React.FC = () => {
|
const PublicJobFairList: React.FC = () => {
|
||||||
const access = useAccess();
|
const access = useAccess();
|
||||||
|
const formRef = useRef<FormInstance>();
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
const [currentRow, setCurrentRow] = useState<API.PublicJobFair.JobFairItem>();
|
const [currentRow, setCurrentRow] = useState<API.PublicJobFair.JobFairItem>();
|
||||||
@@ -44,10 +45,21 @@ const PublicJobFairList: React.FC = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const buildListSearchParams = (values: Record<string, any>): API.PublicJobFair.ListParams => {
|
||||||
|
const { dateRange, current, pageSize, ...rest } = values || {};
|
||||||
|
const params = { ...rest } as API.PublicJobFair.ListParams;
|
||||||
|
if (dateRange?.[0] && dateRange?.[1]) {
|
||||||
|
params.startDate = dateRange[0];
|
||||||
|
params.endDate = dateRange[1];
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
message.loading('正在导出...');
|
message.loading('正在导出...');
|
||||||
try {
|
try {
|
||||||
await exportPublicJobFair();
|
const searchVal = formRef.current?.getFieldsValue();
|
||||||
|
await exportPublicJobFair(buildListSearchParams(searchVal || {}));
|
||||||
message.success('导出成功');
|
message.success('导出成功');
|
||||||
} catch {
|
} catch {
|
||||||
message.error('导出失败');
|
message.error('导出失败');
|
||||||
@@ -55,6 +67,21 @@ const PublicJobFairList: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const columns: ProColumns<API.PublicJobFair.JobFairItem>[] = [
|
const columns: ProColumns<API.PublicJobFair.JobFairItem>[] = [
|
||||||
|
{
|
||||||
|
title: '时间范围',
|
||||||
|
dataIndex: 'dateRange',
|
||||||
|
hideInTable: true,
|
||||||
|
valueType: 'dateRange',
|
||||||
|
fieldProps: {
|
||||||
|
format: 'YYYY-MM-DD',
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
transform: (value) => ({
|
||||||
|
startDate: value[0],
|
||||||
|
endDate: value[1],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '招聘会标题',
|
title: '招聘会标题',
|
||||||
dataIndex: 'jobFairTitle',
|
dataIndex: 'jobFairTitle',
|
||||||
@@ -85,6 +112,12 @@ const PublicJobFairList: React.FC = () => {
|
|||||||
valueType: 'dateTime',
|
valueType: 'dateTime',
|
||||||
hideInSearch: true,
|
hideInSearch: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
valueType: 'dateTime',
|
||||||
|
hideInSearch: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
valueType: 'option',
|
valueType: 'option',
|
||||||
@@ -136,6 +169,7 @@ const PublicJobFairList: React.FC = () => {
|
|||||||
<ProTable<API.PublicJobFair.JobFairItem>
|
<ProTable<API.PublicJobFair.JobFairItem>
|
||||||
headerTitle="公共招聘会列表"
|
headerTitle="公共招聘会列表"
|
||||||
actionRef={actionRef}
|
actionRef={actionRef}
|
||||||
|
formRef={formRef}
|
||||||
rowKey="jobFairId"
|
rowKey="jobFairId"
|
||||||
columns={columns}
|
columns={columns}
|
||||||
scroll={{ x: 'max-content' }}
|
scroll={{ x: 'max-content' }}
|
||||||
@@ -149,6 +183,8 @@ const PublicJobFairList: React.FC = () => {
|
|||||||
pageSize: params.pageSize,
|
pageSize: params.pageSize,
|
||||||
jobFairTitle: params.jobFairTitle,
|
jobFairTitle: params.jobFairTitle,
|
||||||
jobFairType: params.jobFairType,
|
jobFairType: params.jobFairType,
|
||||||
|
startDate: params.startDate,
|
||||||
|
endDate: params.endDate,
|
||||||
});
|
});
|
||||||
return { data: res.rows, total: res.total, success: true };
|
return { data: res.rows, total: res.total, success: true };
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ import {
|
|||||||
exportCmsJob,
|
exportCmsJob,
|
||||||
exportJobApply,
|
exportJobApply,
|
||||||
getCmsJobList,
|
getCmsJobList,
|
||||||
|
importJobRow,
|
||||||
updateCmsJobList,
|
updateCmsJobList,
|
||||||
} from '@/services/Management/list';
|
} from '@/services/Management/list';
|
||||||
import { Button, FormInstance, message, Modal, Switch } from 'antd';
|
import { Button, FormInstance, message, Modal, Switch } from 'antd';
|
||||||
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
|
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
|
||||||
import { AlignLeftOutlined, BarChartOutlined, DeleteOutlined, FormOutlined, PlusOutlined,DownloadOutlined } from '@ant-design/icons';
|
import { AlignLeftOutlined, BarChartOutlined, DeleteOutlined, FormOutlined, PlusOutlined, DownloadOutlined, UploadOutlined } from '@ant-design/icons';
|
||||||
import EditManageRow from './edit';
|
import EditManageRow from './edit';
|
||||||
import { getDictValueEnum } from '@/services/system/dict';
|
import { getDictValueEnum } from '@/services/system/dict';
|
||||||
import DictTag from '@/components/DictTag';
|
import DictTag from '@/components/DictTag';
|
||||||
@@ -76,6 +77,7 @@ function ManagementList() {
|
|||||||
|
|
||||||
const formTableRef = useRef<FormInstance>();
|
const formTableRef = useRef<FormInstance>();
|
||||||
const actionRef = useRef<ActionType>();
|
const actionRef = useRef<ActionType>();
|
||||||
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [educationEnum, setEducationEnum] = useState<any>([]);
|
const [educationEnum, setEducationEnum] = useState<any>([]);
|
||||||
const [experienceEnum, setExperienceEnum] = useState<any>([]);
|
const [experienceEnum, setExperienceEnum] = useState<any>([]);
|
||||||
@@ -120,6 +122,29 @@ function ManagementList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleBatchUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = event.target.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
const hide = message.loading('正在上传');
|
||||||
|
try {
|
||||||
|
const resp = await importJobRow(file);
|
||||||
|
hide();
|
||||||
|
if (resp.code === 200) {
|
||||||
|
message.success('批量上传成功');
|
||||||
|
actionRef.current?.reload();
|
||||||
|
} else {
|
||||||
|
message.error(resp.msg || '上传失败,请重试');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
hide();
|
||||||
|
message.error('上传失败,请重试');
|
||||||
|
}
|
||||||
|
// 清空 input 以便重复选择同一文件
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.value = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns: ProColumns<API.ManagementList.Manage>[] = [
|
const columns: ProColumns<API.ManagementList.Manage>[] = [
|
||||||
{
|
{
|
||||||
title: '时间范围',
|
title: '时间范围',
|
||||||
@@ -390,9 +415,24 @@ function ManagementList() {
|
|||||||
>
|
>
|
||||||
<DownloadOutlined />录用人导出
|
<DownloadOutlined />录用人导出
|
||||||
</Button>,
|
</Button>,
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
key="batchUpload"
|
||||||
|
hidden={!access.hasPerms('manage:List:add')}
|
||||||
|
onClick={() => fileInputRef.current?.click()}
|
||||||
|
>
|
||||||
|
<UploadOutlined /> 批量上传岗位
|
||||||
|
</Button>,
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
ref={fileInputRef}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
accept=".xlsx,.xls"
|
||||||
|
onChange={handleBatchUpload}
|
||||||
|
/>
|
||||||
<EditManageRow
|
<EditManageRow
|
||||||
open={modalVisible}
|
open={modalVisible}
|
||||||
mode={mode}
|
mode={mode}
|
||||||
|
|||||||
@@ -57,6 +57,16 @@ export async function exportCmsJobCandidates(ids: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function importJobRow(file: File) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
return request('/api/app/script/importRow/v2', {
|
||||||
|
method: 'POST',
|
||||||
|
// 不显式设置 Content-Type,交由浏览器按 multipart/form-data 边界自动设置
|
||||||
|
data: formData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function getJobTrend(params) {
|
export async function getJobTrend(params) {
|
||||||
return request(`/api/cms/jobTrend/list`, {
|
return request(`/api/cms/jobTrend/list`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export async function putCmsCompanyList(params?: API.CompanyList.Params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function exportCmsCompanyList(params?: API.CompanyList.Params) {
|
export async function exportCmsCompanyList(params?: API.CompanyList.Params) {
|
||||||
return downLoadXlsx(`/cms/company/export`, { params }, `dict_data_${new Date().getTime()}.xlsx`);
|
return downLoadXlsx(`/api/cms/company/export`, { params }, `dict_data_${new Date().getTime()}.xlsx`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 解析企业详情接口响应(兼容 data 包裹与平铺字段两种格式) */
|
/** 解析企业详情接口响应(兼容 data 包裹与平铺字段两种格式) */
|
||||||
|
|||||||
2
src/types/company/list.d.ts
vendored
2
src/types/company/list.d.ts
vendored
@@ -35,5 +35,7 @@ declare namespace API.CompanyList {
|
|||||||
industry?: string;
|
industry?: string;
|
||||||
scale?: string;
|
scale?: string;
|
||||||
code?: string;
|
code?: string;
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
src/types/jobfair/publicJobFair.d.ts
vendored
3
src/types/jobfair/publicJobFair.d.ts
vendored
@@ -8,6 +8,8 @@ declare namespace API.PublicJobFair {
|
|||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
jobFairTitle?: string;
|
jobFairTitle?: string;
|
||||||
jobFairType?: string;
|
jobFairType?: string;
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 招聘会列表项 */
|
/** 招聘会列表项 */
|
||||||
@@ -29,6 +31,7 @@ declare namespace API.PublicJobFair {
|
|||||||
longitude?: number;
|
longitude?: number;
|
||||||
enterpriseNum?: string;
|
enterpriseNum?: string;
|
||||||
boothNum?: string;
|
boothNum?: string;
|
||||||
|
createTime?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 招聘会列表响应 */
|
/** 招聘会列表响应 */
|
||||||
|
|||||||
Reference in New Issue
Block a user