11
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
CodeQL / Analyze (javascript) (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
CodeQL / Analyze (javascript) (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:
371
src/services/jobportal/indoorJobFair.ts
Normal file
371
src/services/jobportal/indoorJobFair.ts
Normal file
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
* 室内固定摊位招聘会管理 - 假数据服务
|
||||
*/
|
||||
|
||||
import type { API as IndoorJobFairAPI } from '@/types/jobfair/indoorJobFair';
|
||||
|
||||
// ==================== 模拟数据 ====================
|
||||
|
||||
// 模块1: 场地信息
|
||||
const MOCK_VENUES: API.IndoorJobFair.VenueItem[] = [
|
||||
{ id: 1, venueName: '石河子大学体育馆', employmentAgency: '石河子大学就业指导中心', venueType: '室内', venueAddress: '石河子市北三路石河子大学内', contactPerson: '王老师', contactPhone: '0993-2058999', boothCount: 60, status: 'active', createTime: '2026-01-15 10:00:00' },
|
||||
{ id: 2, venueName: '第八师人力资源市场', employmentAgency: '第八师人力资源和社会保障局', venueType: '室内', venueAddress: '石河子市北四路人社局大楼', contactPerson: '李主任', contactPhone: '0993-2012345', boothCount: 40, status: 'active', createTime: '2026-02-01 09:00:00' },
|
||||
{ id: 3, venueName: '阿拉尔市人才交流中心', employmentAgency: '第一师阿拉尔市人力资源和社会保障局', venueType: '室内', venueAddress: '阿拉尔市胜利大道人力资源市场', contactPerson: '张经理', contactPhone: '0997-6390001', boothCount: 50, status: 'active', createTime: '2026-02-20 14:30:00' },
|
||||
{ id: 4, venueName: '图木舒克市职业介绍所', employmentAgency: '第三师图木舒克市人力资源和社会保障局', venueType: '室内', venueAddress: '图木舒克市团结路12号', contactPerson: '刘所长', contactPhone: '0998-6302001', boothCount: 35, status: 'inactive', createTime: '2026-03-01 08:00:00' },
|
||||
];
|
||||
let nextVenueId = 5;
|
||||
|
||||
// 模块2: 摊位信息
|
||||
const MOCK_BOOTHS: API.IndoorJobFair.BoothItem[] = [
|
||||
{ id: 1, venueId: 1, boothNumber: 'A01', companyId: 1001, companyName: '新疆天业(集团)有限公司', status: 'reserved', operator: '张三', operateTime: '2026-03-10 09:00:00', remark: '' },
|
||||
{ id: 2, venueId: 1, boothNumber: 'A02', companyId: 1002, companyName: '石河子经济技术开发区管委会', status: 'fixed', operator: '李四', operateTime: '2026-03-10 09:30:00', remark: '固定展位' },
|
||||
{ id: 3, venueId: 1, boothNumber: 'A03', companyId: undefined, companyName: undefined, status: 'available', operator: undefined, operateTime: undefined, remark: '' },
|
||||
{ id: 4, venueId: 1, boothNumber: 'A04', companyId: 1003, companyName: '新疆西部牧业股份有限公司', status: 'reserved', operator: '王五', operateTime: '2026-03-11 10:00:00', remark: '' },
|
||||
{ id: 5, venueId: 2, boothNumber: 'B01', companyId: undefined, companyName: undefined, status: 'available', operator: undefined, operateTime: undefined, remark: '' },
|
||||
{ id: 6, venueId: 2, boothNumber: 'B02', companyId: 1004, companyName: '兵团水利水电工程集团', status: 'fixed', operator: '赵六', operateTime: '2026-03-12 08:00:00', remark: '长期固定' },
|
||||
{ id: 7, venueId: 2, boothNumber: 'B03', companyId: undefined, companyName: undefined, status: 'locked', operator: '系统', operateTime: '2026-03-12 12:00:00', remark: '预留中' },
|
||||
{ id: 8, venueId: 3, boothNumber: 'C01', companyId: 1005, companyName: '阿拉尔新爵纺织有限公司', status: 'reserved', operator: '钱七', operateTime: '2026-03-13 14:00:00', remark: '' },
|
||||
];
|
||||
let nextBoothId = 9;
|
||||
|
||||
// 模块3: 招聘会信息
|
||||
const MOCK_JOBFAIRS: API.IndoorJobFair.JobFairItem[] = [
|
||||
{ id: 1, fairName: '2026年石河子市春季室内招聘会', venueId: 1, venueName: '石河子大学体育馆', startDate: '2026-03-20', endDate: '2026-03-22', status: 'ongoing', boothUseCount: 45, createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 2, fairName: '2026年高校毕业生就业服务月专场', venueId: 1, venueName: '石河子大学体育馆', startDate: '2026-04-10', endDate: '2026-04-12', status: 'pending', boothUseCount: 0, createTime: '2026-03-15 09:00:00' },
|
||||
{ id: 3, fairName: '2026年阿拉尔市春风行动招聘会', venueId: 3, venueName: '阿拉尔市人才交流中心', startDate: '2026-03-25', endDate: '2026-03-26', status: 'ongoing', boothUseCount: 30, createTime: '2026-03-10 14:00:00' },
|
||||
{ id: 4, fairName: '2026年图木舒克市退役军人专场', venueId: 4, venueName: '图木舒克市职业介绍所', startDate: '2026-05-01', endDate: '2026-05-01', status: 'pending', boothUseCount: 0, createTime: '2026-03-20 11:00:00' },
|
||||
];
|
||||
let nextFairId = 5;
|
||||
|
||||
// 模块4: 参会单位查询
|
||||
const MOCK_COMPANIES: API.IndoorJobFair.CompanyQueryItem[] = [
|
||||
{ id: 1, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1001, companyName: '新疆天业(集团)有限公司', industry: '化工', scale: '1000人以上', contactPerson: '张经理', contactPhone: '13909930001', registrationTime: '2026-03-05 10:00:00' },
|
||||
{ id: 2, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1002, companyName: '石河子经济技术开发区管委会', industry: '政府/公共事业', scale: '500-1000人', contactPerson: '李主任', contactPhone: '13909930002', registrationTime: '2026-03-06 14:00:00' },
|
||||
{ id: 3, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1003, companyName: '新疆西部牧业股份有限公司', industry: '农业/畜牧', scale: '500-1000人', contactPerson: '王部长', contactPhone: '13909930003', registrationTime: '2026-03-07 09:00:00' },
|
||||
{ id: 4, fairId: 3, fairName: '2026年阿拉尔市春风行动招聘会', companyId: 1005, companyName: '阿拉尔新爵纺织有限公司', industry: '纺织/服装', scale: '200-500人', contactPerson: '陈经理', contactPhone: '13709930005', registrationTime: '2026-03-12 11:00:00' },
|
||||
];
|
||||
let nextCompanyQueryId = 5;
|
||||
|
||||
// 模块5: 参会岗位查询
|
||||
const MOCK_JOBS: API.IndoorJobFair.JobQueryItem[] = [
|
||||
{ id: 1, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1001, companyName: '新疆天业(集团)有限公司', jobTitle: '化工工程师', minSalary: 8000, maxSalary: 12000, education: '本科', experience: '3-5年', vacancies: 5, status: 'open' },
|
||||
{ id: 2, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1001, companyName: '新疆天业(集团)有限公司', jobTitle: '安全主管', minSalary: 10000, maxSalary: 15000, education: '本科', experience: '5年以上', vacancies: 2, status: 'open' },
|
||||
{ id: 3, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1002, companyName: '石河子经济技术开发区管委会', jobTitle: '产业招商专员', minSalary: 6000, maxSalary: 9000, education: '本科', experience: '1-3年', vacancies: 10, status: 'open' },
|
||||
{ id: 4, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1003, companyName: '新疆西部牧业股份有限公司', jobTitle: '畜牧技术员', minSalary: 5000, maxSalary: 8000, education: '大专', experience: '1-3年', vacancies: 8, status: 'open' },
|
||||
{ id: 5, fairId: 3, fairName: '2026年阿拉尔市春风行动招聘会', companyId: 1005, companyName: '阿拉尔新爵纺织有限公司', jobTitle: '纺织操作工', minSalary: 4000, maxSalary: 6000, education: '初中', experience: '不限', vacancies: 50, status: 'open' },
|
||||
];
|
||||
let nextJobQueryId = 6;
|
||||
|
||||
// 模块6: 参会单位审核
|
||||
const MOCK_COMPANY_REVIEWS: API.IndoorJobFair.CompanyReviewItem[] = [
|
||||
{ id: 1, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1001, companyName: '新疆天业(集团)有限公司', industry: '化工', scale: '1000人以上', contactPerson: '张经理', contactPhone: '13909930001', reservationStart: '2026-03-01', reservationEnd: '2026-03-10', reviewStatus: 'approved', reviewTime: '2026-03-08 10:00:00', reviewRemark: '' },
|
||||
{ id: 2, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1002, companyName: '石河子经济技术开发区管委会', industry: '政府/公共事业', scale: '500-1000人', contactPerson: '李主任', contactPhone: '13909930002', reservationStart: '2026-03-01', reservationEnd: '2026-03-10', reviewStatus: 'approved', reviewTime: '2026-03-08 11:00:00', reviewRemark: '' },
|
||||
{ id: 3, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1009, companyName: '兵团水利水电工程集团', industry: '建筑/工程', scale: '1000人以上', contactPerson: '刘部长', contactPhone: '13609930001', reservationStart: '2026-03-05', reservationEnd: '2026-03-12', reviewStatus: 'pending', reviewTime: undefined, reviewRemark: '' },
|
||||
{ id: 4, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1010, companyName: '新疆通用航空有限责任公司', industry: '航空/交通', scale: '200-500人', contactPerson: '陈经理', contactPhone: '13809930001', reservationStart: '2026-03-06', reservationEnd: '2026-03-15', reviewStatus: 'pending', reviewTime: undefined, reviewRemark: '' },
|
||||
{ id: 5, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1012, companyName: '兵团棉麻公司', industry: '农业/贸易', scale: '200-500人', contactPerson: '彭经理', contactPhone: '13509930001', reservationStart: '2026-03-03', reservationEnd: '2026-03-08', reviewStatus: 'rejected', reviewTime: '2026-03-09 15:00:00', reviewRemark: '资料不全,请补充企业营业执照' },
|
||||
];
|
||||
let nextCompanyReviewId = 6;
|
||||
|
||||
// 模块7: 退订信息管理
|
||||
const MOCK_UNSUBSCRIBES: API.IndoorJobFair.UnsubscribeItem[] = [
|
||||
{ id: 1, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1006, companyName: '新疆天山铝业有限公司', boothNumber: 'A10', contactPerson: '吴主管', contactPhone: '13909930006', unsubscribeTime: '2026-03-15 10:00:00', reason: '公司行程冲突' },
|
||||
{ id: 2, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1007, companyName: '兵团棉麻公司', boothNumber: 'A15', contactPerson: '彭经理', contactPhone: '13509930001', unsubscribeTime: '2026-03-14 14:30:00', reason: '招聘计划调整' },
|
||||
{ id: 3, fairId: 3, fairName: '2026年阿拉尔市春风行动招聘会', companyId: 1008, companyName: '阿拉尔永固建筑公司', boothNumber: 'C05', contactPerson: '黄总', contactPhone: '13809930008', unsubscribeTime: '2026-03-20 09:00:00', reason: '人员不足' },
|
||||
];
|
||||
let nextUnsubscribeId = 4;
|
||||
|
||||
// 模块8: 单位参会查询
|
||||
const MOCK_COMPANY_RECORDS: API.IndoorJobFair.CompanyRecordItem[] = [
|
||||
{ id: 1, companyId: 1001, companyName: '新疆天业(集团)有限公司', industry: '化工', scale: '1000人以上', contactPerson: '张经理', contactPhone: '13909930001', status: 'normal', creditStatus: 'good', fairCount: 5, createTime: '2025-06-01 10:00:00' },
|
||||
{ id: 2, companyId: 1002, companyName: '石河子经济技术开发区管委会', industry: '政府/公共事业', scale: '500-1000人', contactPerson: '李主任', contactPhone: '13909930002', status: 'normal', creditStatus: 'good', fairCount: 8, createTime: '2025-01-15 09:00:00' },
|
||||
{ id: 3, companyId: 1003, companyName: '新疆西部牧业股份有限公司', industry: '农业/畜牧', scale: '500-1000人', contactPerson: '王部长', contactPhone: '13909930003', status: 'normal', creditStatus: 'good', fairCount: 3, createTime: '2025-08-20 14:00:00' },
|
||||
{ id: 4, companyId: 1011, companyName: '石河子市公共交通有限责任公司', industry: '交通/运输', scale: '500-1000人', contactPerson: '马科长', contactPhone: '13709930001', status: 'abnormal', creditStatus: 'poor', fairCount: 2, createTime: '2025-11-10 11:00:00' },
|
||||
];
|
||||
let nextCompanyRecordId = 5;
|
||||
|
||||
// 模块9: 招聘会岗位审核
|
||||
const MOCK_JOB_REVIEWS: API.IndoorJobFair.JobReviewItem[] = [
|
||||
{ id: 1, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1001, companyName: '新疆天业(集团)有限公司', jobId: 1, jobTitle: '化工工程师', education: '本科', experience: '3-5年', vacancies: 5, reviewStatus: 'approved', reviewTime: '2026-03-08 10:00:00', reviewRemark: '' },
|
||||
{ id: 2, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1001, companyName: '新疆天业(集团)有限公司', jobId: 2, jobTitle: '安全主管', education: '本科', experience: '5年以上', vacancies: 2, reviewStatus: 'approved', reviewTime: '2026-03-08 10:30:00', reviewRemark: '' },
|
||||
{ id: 3, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1002, companyName: '石河子经济技术开发区管委会', jobId: 3, jobTitle: '产业招商专员', education: '本科', experience: '1-3年', vacancies: 10, reviewStatus: 'pending', reviewTime: undefined, reviewRemark: '' },
|
||||
{ id: 4, fairId: 1, fairName: '2026年石河子市春季室内招聘会', companyId: 1003, companyName: '新疆西部牧业股份有限公司', jobId: 4, jobTitle: '畜牧技术员', education: '大专', experience: '1-3年', vacancies: 8, reviewStatus: 'pending', reviewTime: undefined, reviewRemark: '' },
|
||||
];
|
||||
let nextJobReviewId = 5;
|
||||
|
||||
// 模块10: 预留操作记录
|
||||
const MOCK_RESERVATION_RECORDS: API.IndoorJobFair.ReservationRecordItem[] = [
|
||||
{ id: 1, fairId: 1, fairName: '2026年石河子市春季室内招聘会', boothNumber: 'A01', companyName: '新疆天业(集团)有限公司', operator: '张三', operateTime: '2026-03-10 09:00:00', operateType: '预留', remark: '' },
|
||||
{ id: 2, fairId: 1, fairName: '2026年石河子市春季室内招聘会', boothNumber: 'A04', companyName: '新疆西部牧业股份有限公司', operator: '王五', operateTime: '2026-03-11 10:00:00', operateType: '预留', remark: '' },
|
||||
{ id: 3, fairId: 1, fairName: '2026年石河子市春季室内招聘会', boothNumber: 'B02', companyName: '兵团水利水电工程集团', operator: '李四', operateTime: '2026-03-12 08:00:00', operateType: '固定', remark: '长期固定' },
|
||||
{ id: 4, fairId: 1, fairName: '2026年石河子市春季室内招聘会', boothNumber: 'C01', companyName: '阿拉尔新爵纺织有限公司', operator: '钱七', operateTime: '2026-03-13 14:00:00', operateType: '预留', remark: '' },
|
||||
];
|
||||
let nextReservationRecordId = 5;
|
||||
|
||||
// ==================== 工具函数 ====================
|
||||
|
||||
function paginate<T>(arr: T[], current: number, pageSize: number) {
|
||||
const start = (current - 1) * pageSize;
|
||||
return arr.slice(start, start + pageSize);
|
||||
}
|
||||
|
||||
// ==================== 模块1: 场地信息管理 API ====================
|
||||
|
||||
export async function getVenueList(params?: API.IndoorJobFair.VenueListParams) {
|
||||
let list = [...MOCK_VENUES];
|
||||
if (params?.employmentAgency) list = list.filter(v => v.employmentAgency.includes(params.employmentAgency!));
|
||||
if (params?.venueName) list = list.filter(v => v.venueName.includes(params.venueName!));
|
||||
if (params?.venueType) list = list.filter(v => v.venueType === params.venueType);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
export async function addVenue(data: API.IndoorJobFair.VenueForm) {
|
||||
const venue: API.IndoorJobFair.VenueItem = {
|
||||
...data,
|
||||
id: nextVenueId++,
|
||||
status: 'active',
|
||||
createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
};
|
||||
MOCK_VENUES.unshift(venue);
|
||||
return { code: 200, msg: '添加成功', data: venue };
|
||||
}
|
||||
|
||||
export async function updateVenue(data: API.IndoorJobFair.VenueForm) {
|
||||
const idx = MOCK_VENUES.findIndex(v => v.id === data.id);
|
||||
if (idx !== -1) { MOCK_VENUES[idx] = { ...MOCK_VENUES[idx], ...data }; return { code: 200, msg: '修改成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
export async function deleteVenue(id: number) {
|
||||
const idx = MOCK_VENUES.findIndex(v => v.id === id);
|
||||
if (idx !== -1) { MOCK_VENUES.splice(idx, 1); return { code: 200, msg: '删除成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
// ==================== 模块2: 摊位信息管理 API ====================
|
||||
|
||||
export async function getBoothList(params?: API.IndoorJobFair.BoothListParams) {
|
||||
let list = [...MOCK_BOOTHS];
|
||||
if (params?.venueId) list = list.filter(b => b.venueId === params.venueId);
|
||||
if (params?.boothNumber) list = list.filter(b => b.boothNumber.includes(params.boothNumber!));
|
||||
if (params?.companyName) list = list.filter(b => b.companyName?.includes(params.companyName!));
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
export async function addBooth(data: API.IndoorJobFair.BoothForm) {
|
||||
const booth: API.IndoorJobFair.BoothItem = {
|
||||
...data,
|
||||
id: nextBoothId++,
|
||||
status: 'available',
|
||||
operator: undefined,
|
||||
operateTime: undefined,
|
||||
remark: '',
|
||||
};
|
||||
MOCK_BOOTHS.unshift(booth);
|
||||
return { code: 200, msg: '添加成功', data: booth };
|
||||
}
|
||||
|
||||
export async function updateBooth(data: API.IndoorJobFair.BoothForm) {
|
||||
const idx = MOCK_BOOTHS.findIndex(b => b.id === data.id);
|
||||
if (idx !== -1) { MOCK_BOOTHS[idx] = { ...MOCK_BOOTHS[idx], ...data }; return { code: 200, msg: '修改成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
export async function fixBooth(id: number, operator: string) {
|
||||
const booth = MOCK_BOOTHS.find(b => b.id === id);
|
||||
if (!booth) return { code: 404, msg: '未找到' };
|
||||
booth.status = 'fixed';
|
||||
booth.operator = operator;
|
||||
booth.operateTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
return { code: 200, msg: '固定成功' };
|
||||
}
|
||||
|
||||
export async function reserveBooth(id: number, operator: string) {
|
||||
const booth = MOCK_BOOTHS.find(b => b.id === id);
|
||||
if (!booth) return { code: 404, msg: '未找到' };
|
||||
booth.status = 'reserved';
|
||||
booth.operator = operator;
|
||||
booth.operateTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
return { code: 200, msg: '预留成功' };
|
||||
}
|
||||
|
||||
export async function releaseBooth(id: number) {
|
||||
const booth = MOCK_BOOTHS.find(b => b.id === id);
|
||||
if (!booth) return { code: 404, msg: '未找到' };
|
||||
booth.status = 'available';
|
||||
booth.companyId = undefined;
|
||||
booth.companyName = undefined;
|
||||
booth.operator = undefined;
|
||||
booth.operateTime = undefined;
|
||||
return { code: 200, msg: '解除成功' };
|
||||
}
|
||||
|
||||
// ==================== 模块3: 招聘会管理 API ====================
|
||||
|
||||
export async function getJobFairList(params?: API.IndoorJobFair.JobFairListParams) {
|
||||
let list = [...MOCK_JOBFAIRS];
|
||||
if (params?.fairName) list = list.filter(f => f.fairName.includes(params.fairName!));
|
||||
if (params?.startDate) list = list.filter(f => f.startDate >= params.startDate!);
|
||||
if (params?.endDate) list = list.filter(f => f.endDate <= params.endDate!);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
export async function addJobFair(data: API.IndoorJobFair.JobFairForm) {
|
||||
const jobfair: API.IndoorJobFair.JobFairItem = {
|
||||
...data,
|
||||
id: nextFairId++,
|
||||
status: 'pending',
|
||||
boothUseCount: 0,
|
||||
createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
};
|
||||
MOCK_JOBFAIRS.unshift(jobfair);
|
||||
return { code: 200, msg: '添加成功', data: jobfair };
|
||||
}
|
||||
|
||||
export async function updateJobFair(data: API.IndoorJobFair.JobFairForm) {
|
||||
const idx = MOCK_JOBFAIRS.findIndex(f => f.id === data.id);
|
||||
if (idx !== -1) { MOCK_JOBFAIRS[idx] = { ...MOCK_JOBFAIRS[idx], ...data }; return { code: 200, msg: '修改成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
export async function deleteJobFair(id: number) {
|
||||
const idx = MOCK_JOBFAIRS.findIndex(f => f.id === id);
|
||||
if (idx !== -1) { MOCK_JOBFAIRS.splice(idx, 1); return { code: 200, msg: '删除成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
// ==================== 模块4: 参会单位查询 API ====================
|
||||
|
||||
export async function getCompanyQueryList(params?: API.IndoorJobFair.CompanyQueryParams) {
|
||||
let list = [...MOCK_COMPANIES];
|
||||
if (params?.fairName) list = list.filter(c => c.fairName.includes(params.fairName!));
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
// ==================== 模块5: 参会岗位查询 API ====================
|
||||
|
||||
export async function getJobQueryList(params?: API.IndoorJobFair.JobQueryParams) {
|
||||
let list = [...MOCK_JOBS];
|
||||
if (params?.fairName) list = list.filter(j => j.fairName.includes(params.fairName!));
|
||||
if (params?.companyName) list = list.filter(j => j.companyName?.includes(params.companyName!));
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
// ==================== 模块6: 参会单位审核 API ====================
|
||||
|
||||
export async function getCompanyReviewList(params?: API.IndoorJobFair.CompanyReviewParams) {
|
||||
let list = [...MOCK_COMPANY_REVIEWS];
|
||||
if (params?.fairName) list = list.filter(c => c.fairName.includes(params.fairName!));
|
||||
if (params?.companyName) list = list.filter(c => c.companyName?.includes(params.companyName!));
|
||||
if (params?.reviewStatus) list = list.filter(c => c.reviewStatus === params.reviewStatus);
|
||||
if (params?.reservationStart) list = list.filter(c => c.reservationStart >= params.reservationStart!);
|
||||
if (params?.reservationEnd) list = list.filter(c => c.reservationEnd <= params.reservationEnd!);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
export async function batchApproveCompany(ids: number[]) {
|
||||
ids.forEach(id => {
|
||||
const item = MOCK_COMPANY_REVIEWS.find(c => c.id === id);
|
||||
if (item) { item.reviewStatus = 'approved'; item.reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19); }
|
||||
});
|
||||
return { code: 200, msg: '批量审核成功' };
|
||||
}
|
||||
|
||||
export async function batchRejectCompany(ids: number[]) {
|
||||
ids.forEach(id => {
|
||||
const item = MOCK_COMPANY_REVIEWS.find(c => c.id === id);
|
||||
if (item) { item.reviewStatus = 'rejected'; item.reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19); }
|
||||
});
|
||||
return { code: 200, msg: '批量审核失败' };
|
||||
}
|
||||
|
||||
// ==================== 模块7: 退订信息管理 API ====================
|
||||
|
||||
export async function getUnsubscribeList(params?: API.IndoorJobFair.UnsubscribeParams) {
|
||||
let list = [...MOCK_UNSUBSCRIBES];
|
||||
if (params?.fairName) list = list.filter(u => u.fairName.includes(params.fairName!));
|
||||
if (params?.companyName) list = list.filter(u => u.companyName?.includes(params.companyName!));
|
||||
if (params?.boothNumber) list = list.filter(u => u.boothNumber.includes(params.boothNumber!));
|
||||
if (params?.contactPerson) list = list.filter(u => u.contactPerson.includes(params.contactPerson!));
|
||||
if (params?.contactPhone) list = list.filter(u => u.contactPhone.includes(params.contactPhone!));
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
// ==================== 模块8: 单位参会查询 API ====================
|
||||
|
||||
export async function getCompanyRecordList(params?: API.IndoorJobFair.CompanyRecordParams) {
|
||||
let list = [...MOCK_COMPANY_RECORDS];
|
||||
if (params?.companyName) list = list.filter(c => c.companyName.includes(params.companyName!));
|
||||
if (params?.contactPerson) list = list.filter(c => c.contactPerson.includes(params.contactPerson!));
|
||||
if (params?.contactPhone) list = list.filter(c => c.contactPhone.includes(params.contactPhone!));
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
export async function updateCompanyRecordStatus(id: number, status: string) {
|
||||
const record = MOCK_COMPANY_RECORDS.find(c => c.id === id);
|
||||
if (!record) return { code: 404, msg: '未找到' };
|
||||
record.status = status;
|
||||
return { code: 200, msg: '状态修改成功' };
|
||||
}
|
||||
|
||||
export async function updateCompanyCreditStatus(id: number, creditStatus: string) {
|
||||
const record = MOCK_COMPANY_RECORDS.find(c => c.id === id);
|
||||
if (!record) return { code: 404, msg: '未找到' };
|
||||
record.creditStatus = creditStatus;
|
||||
return { code: 200, msg: '失信记录更新成功' };
|
||||
}
|
||||
|
||||
// ==================== 模块9: 招聘会岗位审核 API ====================
|
||||
|
||||
export async function getJobReviewList(params?: API.IndoorJobFair.JobReviewParams) {
|
||||
let list = [...MOCK_JOB_REVIEWS];
|
||||
if (params?.companyName) list = list.filter(j => j.companyName?.includes(params.companyName!));
|
||||
if (params?.jobTitle) list = list.filter(j => j.jobTitle.includes(params.jobTitle!));
|
||||
if (params?.reviewStatus) list = list.filter(j => j.reviewStatus === params.reviewStatus);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
export async function approveJob(id: number, remark?: string) {
|
||||
const job = MOCK_JOB_REVIEWS.find(j => j.id === id);
|
||||
if (!job) return { code: 404, msg: '未找到' };
|
||||
job.reviewStatus = 'approved';
|
||||
job.reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
if (remark) job.reviewRemark = remark;
|
||||
return { code: 200, msg: '审核通过' };
|
||||
}
|
||||
|
||||
export async function rejectJob(id: number, remark?: string) {
|
||||
const job = MOCK_JOB_REVIEWS.find(j => j.id === id);
|
||||
if (!job) return { code: 404, msg: '未找到' };
|
||||
job.reviewStatus = 'rejected';
|
||||
job.reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
if (remark) job.reviewRemark = remark;
|
||||
return { code: 200, msg: '审核不通过' };
|
||||
}
|
||||
|
||||
// ==================== 模块10: 预留操作记录 API ====================
|
||||
|
||||
export async function getReservationRecordList(params?: API.IndoorJobFair.ReservationRecordParams) {
|
||||
let list = [...MOCK_RESERVATION_RECORDS];
|
||||
if (params?.operator) list = list.filter(r => r.operator.includes(params.operator!));
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
@@ -74,8 +74,6 @@ export interface CmsLiveForm {
|
||||
description?: string;
|
||||
startTime?: string;
|
||||
endTime?: string;
|
||||
companyId?: string;
|
||||
companyName?: string;
|
||||
}
|
||||
|
||||
/** 获取直播带岗管理列表 GET /api/cms/live/list */
|
||||
|
||||
288
src/services/jobportal/outdoorFair.ts
Normal file
288
src/services/jobportal/outdoorFair.ts
Normal file
@@ -0,0 +1,288 @@
|
||||
import { request } from '@umijs/max';
|
||||
|
||||
/** 户外招聘会列表项 */
|
||||
export interface OutdoorFairItem {
|
||||
id: number;
|
||||
/** 招聘会标题 */
|
||||
title: string;
|
||||
/** 举办单位 */
|
||||
hostUnit: string;
|
||||
/** 招聘会类型 */
|
||||
fairType: string;
|
||||
/** 举办区域 */
|
||||
region: string;
|
||||
/** 举办地址 */
|
||||
address: string;
|
||||
/** 展位数量 */
|
||||
boothCount: number;
|
||||
/** 举办时间 */
|
||||
holdTime: string;
|
||||
/** 截止时间 */
|
||||
endTime: string;
|
||||
/** 开放申请 */
|
||||
applyStartTime: string;
|
||||
/** 截止申请 */
|
||||
applyEndTime: string;
|
||||
/** 是否开启线上申请 */
|
||||
onlineApply: boolean;
|
||||
/** 招聘会照片 */
|
||||
photoUrl: string;
|
||||
createTime?: string;
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
/** 户外招聘会查询参数 */
|
||||
export interface OutdoorFairListParams {
|
||||
title?: string;
|
||||
hostUnit?: string;
|
||||
fairType?: string;
|
||||
current?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
/** 户外招聘会列表响应 */
|
||||
export interface OutdoorFairListResult {
|
||||
code: number;
|
||||
msg?: string;
|
||||
total: number;
|
||||
rows: OutdoorFairItem[];
|
||||
}
|
||||
|
||||
/** 户外招聘会新增/编辑表单 */
|
||||
export interface OutdoorFairForm {
|
||||
id?: number;
|
||||
title: string;
|
||||
hostUnit: string;
|
||||
fairType: string;
|
||||
region: string;
|
||||
address: string;
|
||||
boothCount: number;
|
||||
holdTime: string;
|
||||
endTime: string;
|
||||
applyStartTime: string;
|
||||
applyEndTime: string;
|
||||
onlineApply: boolean;
|
||||
photoUrl: string;
|
||||
}
|
||||
|
||||
/** 通用响应 */
|
||||
export interface OutdoorFairCommonResult {
|
||||
code: number;
|
||||
msg?: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
// ==================== 静态假数据 ====================
|
||||
|
||||
const MOCK_DATA: OutdoorFairItem[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: '2026年石河子市春季户外招聘会',
|
||||
hostUnit: '第八师石河子市人力资源和社会保障局',
|
||||
fairType: '综合类',
|
||||
region: '第八师(石河子市)',
|
||||
address: '石河子市北三路石河子大学中区图书馆前广场',
|
||||
boothCount: 80,
|
||||
holdTime: '2026-03-15 09:00:00',
|
||||
endTime: '2026-03-15 17:00:00',
|
||||
applyStartTime: '2026-03-01 00:00:00',
|
||||
applyEndTime: '2026-03-10 23:59:59',
|
||||
onlineApply: true,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor1/400/300',
|
||||
createTime: '2026-02-20 10:30:00',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '2026年阿拉尔市高校户外专场招聘会',
|
||||
hostUnit: '第一师阿拉尔市人力资源和社会保障局',
|
||||
fairType: '校园招聘',
|
||||
region: '第一师(阿拉尔市)',
|
||||
address: '阿拉尔市塔里木大道塔里木大学综合教学楼前广场',
|
||||
boothCount: 60,
|
||||
holdTime: '2026-04-20 09:00:00',
|
||||
endTime: '2026-04-20 16:00:00',
|
||||
applyStartTime: '2026-04-01 00:00:00',
|
||||
applyEndTime: '2026-04-15 23:59:59',
|
||||
onlineApply: true,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor2/400/300',
|
||||
createTime: '2026-03-01 14:00:00',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '2026年图木舒克市制造业户外招聘会',
|
||||
hostUnit: '第三师图木舒克市人力资源和社会保障局',
|
||||
fairType: '行业专场',
|
||||
region: '第三师(图木舒克市)',
|
||||
address: '图木舒克市迎宾大道市政广场',
|
||||
boothCount: 120,
|
||||
holdTime: '2026-05-10 08:30:00',
|
||||
endTime: '2026-05-10 17:30:00',
|
||||
applyStartTime: '2026-04-25 00:00:00',
|
||||
applyEndTime: '2026-05-05 23:59:59',
|
||||
onlineApply: false,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor3/400/300',
|
||||
createTime: '2026-03-10 09:00:00',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '2026年可克达拉市高新技术户外招聘会',
|
||||
hostUnit: '第四师可克达拉市人力资源和社会保障局',
|
||||
fairType: '高新技术专场',
|
||||
region: '第四师(可克达拉市)',
|
||||
address: '可克达拉市镇江路市民服务中心广场',
|
||||
boothCount: 50,
|
||||
holdTime: '2026-06-18 09:00:00',
|
||||
endTime: '2026-06-18 16:30:00',
|
||||
applyStartTime: '2026-06-01 00:00:00',
|
||||
applyEndTime: '2026-06-12 23:59:59',
|
||||
onlineApply: true,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor4/400/300',
|
||||
createTime: '2026-03-20 11:00:00',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '2026年双河市农业行业户外招聘会',
|
||||
hostUnit: '第五师双河市人力资源和社会保障局',
|
||||
fairType: '行业专场',
|
||||
region: '第五师(双河市)',
|
||||
address: '双河市人民路双河市文化广场',
|
||||
boothCount: 40,
|
||||
holdTime: '2026-07-08 09:00:00',
|
||||
endTime: '2026-07-08 17:00:00',
|
||||
applyStartTime: '2026-06-20 00:00:00',
|
||||
applyEndTime: '2026-07-03 23:59:59',
|
||||
onlineApply: false,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor5/400/300',
|
||||
createTime: '2026-04-01 08:30:00',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: '2026年五家渠市电子产业户外招聘会',
|
||||
hostUnit: '第六师五家渠市人力资源和社会保障局',
|
||||
fairType: '行业专场',
|
||||
region: '第六师(五家渠市)',
|
||||
address: '五家渠市长安东街五家渠市人民广场',
|
||||
boothCount: 70,
|
||||
holdTime: '2026-08-15 08:30:00',
|
||||
endTime: '2026-08-15 17:30:00',
|
||||
applyStartTime: '2026-08-01 00:00:00',
|
||||
applyEndTime: '2026-08-10 23:59:59',
|
||||
onlineApply: true,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor6/400/300',
|
||||
createTime: '2026-04-15 10:00:00',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: '2026年胡杨河市智能制造户外招聘会',
|
||||
hostUnit: '第七师胡杨河市人力资源和社会保障局',
|
||||
fairType: '智能制造专场',
|
||||
region: '第七师(胡杨河市)',
|
||||
address: '胡杨河市团结路胡杨河市创业广场',
|
||||
boothCount: 55,
|
||||
holdTime: '2026-09-12 09:00:00',
|
||||
endTime: '2026-09-12 16:00:00',
|
||||
applyStartTime: '2026-08-25 00:00:00',
|
||||
applyEndTime: '2026-09-05 23:59:59',
|
||||
onlineApply: true,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor7/400/300',
|
||||
createTime: '2026-05-01 09:30:00',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
title: '2026年北屯市文旅行业户外招聘会',
|
||||
hostUnit: '第十师北屯市人力资源和社会保障局',
|
||||
fairType: '文旅专场',
|
||||
region: '第十师(北屯市)',
|
||||
address: '北屯市博望路北屯市文化广场',
|
||||
boothCount: 35,
|
||||
holdTime: '2026-10-20 09:00:00',
|
||||
endTime: '2026-10-20 17:00:00',
|
||||
applyStartTime: '2026-10-01 00:00:00',
|
||||
applyEndTime: '2026-10-15 23:59:59',
|
||||
onlineApply: false,
|
||||
photoUrl: 'https://picsum.photos/seed/outdoor8/400/300',
|
||||
createTime: '2026-05-10 16:00:00',
|
||||
},
|
||||
];
|
||||
|
||||
// 模拟自增 ID
|
||||
let nextId = MOCK_DATA.length + 1;
|
||||
|
||||
// ==================== API 接口(使用假数据) ====================
|
||||
|
||||
const CMS_OUTDOOR_FAIR_BASE = '/api/cms/outdoor-fair';
|
||||
|
||||
/**
|
||||
* 获取户外招聘会管理列表
|
||||
* GET /api/cms/outdoor-fair/list
|
||||
*/
|
||||
export async function getOutdoorFairList(params?: OutdoorFairListParams) {
|
||||
let filtered = [...MOCK_DATA];
|
||||
|
||||
if (params?.title) {
|
||||
filtered = filtered.filter((item) => item.title.includes(params.title!));
|
||||
}
|
||||
if (params?.hostUnit) {
|
||||
filtered = filtered.filter((item) => item.hostUnit.includes(params.hostUnit!));
|
||||
}
|
||||
if (params?.fairType) {
|
||||
filtered = filtered.filter((item) => item.fairType.includes(params.fairType!));
|
||||
}
|
||||
|
||||
const total = filtered.length;
|
||||
const current = params?.current || 1;
|
||||
const pageSize = params?.pageSize || 10;
|
||||
const start = (current - 1) * pageSize;
|
||||
const rows = filtered.slice(start, start + pageSize);
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
msg: '操作成功',
|
||||
total,
|
||||
rows,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增户外招聘会
|
||||
* POST /api/cms/outdoor-fair
|
||||
*/
|
||||
export async function addOutdoorFair(data: OutdoorFairForm) {
|
||||
const newItem: OutdoorFairItem = {
|
||||
...data,
|
||||
id: nextId++,
|
||||
createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
};
|
||||
MOCK_DATA.unshift(newItem);
|
||||
return { code: 200, msg: '新增成功', data: newItem };
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改户外招聘会
|
||||
* PUT /api/cms/outdoor-fair
|
||||
*/
|
||||
export async function updateOutdoorFair(data: OutdoorFairForm) {
|
||||
const index = MOCK_DATA.findIndex((item) => item.id === data.id);
|
||||
if (index !== -1) {
|
||||
MOCK_DATA[index] = {
|
||||
...MOCK_DATA[index],
|
||||
...data,
|
||||
updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
};
|
||||
return { code: 200, msg: '修改成功', data: MOCK_DATA[index] };
|
||||
}
|
||||
return { code: 404, msg: '未找到该记录' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除户外招聘会
|
||||
* DELETE /api/cms/outdoor-fair/{id}
|
||||
*/
|
||||
export async function deleteOutdoorFair(id: number) {
|
||||
const index = MOCK_DATA.findIndex((item) => item.id === id);
|
||||
if (index !== -1) {
|
||||
MOCK_DATA.splice(index, 1);
|
||||
return { code: 200, msg: '删除成功' };
|
||||
}
|
||||
return { code: 404, msg: '未找到该记录' };
|
||||
}
|
||||
526
src/services/jobportal/outdoorFairDetail.ts
Normal file
526
src/services/jobportal/outdoorFairDetail.ts
Normal file
@@ -0,0 +1,526 @@
|
||||
/**
|
||||
* 户外招聘会详情管理 - 假数据服务
|
||||
* 包含模块1-6的全部 mock API
|
||||
*/
|
||||
|
||||
import type {
|
||||
API as OutdoorFairDetailAPI,
|
||||
} from '@/types/jobfair/outdoorFairDetail'; // eslint-disable-line
|
||||
|
||||
type ParticipatingCompany = API.OutdoorFairDetail.ParticipatingCompany;
|
||||
type PostedJob = API.OutdoorFairDetail.PostedJob;
|
||||
type BoothItem = API.OutdoorFairDetail.BoothItem;
|
||||
type BoothAssignParams = API.OutdoorFairDetail.BoothAssignParams;
|
||||
type CompanyRegistration = API.OutdoorFairDetail.CompanyRegistration;
|
||||
type RegisteredJob = API.OutdoorFairDetail.RegisteredJob;
|
||||
type AttendeeItem = API.OutdoorFairDetail.AttendeeItem;
|
||||
type InterviewTrackParams = API.OutdoorFairDetail.InterviewTrackParams;
|
||||
type DeviceItem = API.OutdoorFairDetail.DeviceItem;
|
||||
type GateStatus = API.OutdoorFairDetail.GateStatus;
|
||||
type GateEntryLog = API.OutdoorFairDetail.GateEntryLog;
|
||||
type FairStatistics = API.OutdoorFairDetail.FairStatistics;
|
||||
|
||||
// ==================== 模块1: 招聘会管理 假数据 ====================
|
||||
|
||||
const MOCK_COMPANIES: ParticipatingCompany[] = [
|
||||
{ id: 1, fairId: 1, companyId: 1001, companyName: '新疆天业(集团)有限公司', industry: '化工', scale: '1000人以上', contactPerson: '张经理', contactPhone: '13909930001', boothId: 1, boothNumber: 'A01', jobList: [
|
||||
{ id: 1, fairId: 1, companyId: 1001, jobTitle: '化工工程师', minSalary: 8000, maxSalary: 12000, education: '本科', experience: '3-5年', vacancies: 5, status: 'active' },
|
||||
{ id: 2, fairId: 1, companyId: 1001, jobTitle: '安全主管', minSalary: 10000, maxSalary: 15000, education: '本科', experience: '5年以上', vacancies: 2, status: 'active' },
|
||||
]},
|
||||
{ id: 2, fairId: 1, companyId: 1002, companyName: '石河子经济技术开发区管委会', industry: '政府/公共事业', scale: '500-1000人', contactPerson: '李主任', contactPhone: '13909930002', boothId: 2, boothNumber: 'A02', jobList: [
|
||||
{ id: 3, fairId: 1, companyId: 1002, jobTitle: '产业招商专员', minSalary: 6000, maxSalary: 9000, education: '本科', experience: '1-3年', vacancies: 10, status: 'active' },
|
||||
]},
|
||||
{ id: 3, fairId: 1, companyId: 1003, companyName: '新疆西部牧业股份有限公司', industry: '农业/畜牧', scale: '500-1000人', contactPerson: '王部长', contactPhone: '13909930003', boothId: 3, boothNumber: 'A03', jobList: [
|
||||
{ id: 4, fairId: 1, companyId: 1003, jobTitle: '畜牧技术员', minSalary: 5000, maxSalary: 8000, education: '大专', experience: '1-3年', vacancies: 8, status: 'active' },
|
||||
{ id: 5, fairId: 1, companyId: 1003, jobTitle: '兽医', minSalary: 7000, maxSalary: 11000, education: '本科', experience: '3-5年', vacancies: 3, status: 'active' },
|
||||
]},
|
||||
{ id: 4, fairId: 1, companyId: 1004, companyName: '新疆生产建设兵团第八师医院', industry: '医疗/卫生', scale: '1000人以上', contactPerson: '赵处长', contactPhone: '13909930004', jobList: [
|
||||
{ id: 6, fairId: 1, companyId: 1004, jobTitle: '临床医生', minSalary: 10000, maxSalary: 18000, education: '硕士', experience: '不限', vacancies: 15, status: 'active' },
|
||||
{ id: 7, fairId: 1, companyId: 1004, jobTitle: '护士', minSalary: 5000, maxSalary: 8000, education: '大专', experience: '1-3年', vacancies: 20, status: 'active' },
|
||||
]},
|
||||
{ id: 5, fairId: 1, companyId: 1005, companyName: '石河子大学', industry: '教育/科研', scale: '1000人以上', contactPerson: '周老师', contactPhone: '13909930005', jobList: [
|
||||
{ id: 8, fairId: 1, companyId: 1005, jobTitle: '讲师', minSalary: 9000, maxSalary: 13000, education: '博士', experience: '不限', vacancies: 5, status: 'active' },
|
||||
]},
|
||||
{ id: 6, fairId: 1, companyId: 1006, companyName: '新疆天山铝业有限公司', industry: '制造/能源', scale: '1000人以上', contactPerson: '吴主管', contactPhone: '13909930006', boothId: 6, boothNumber: 'A06', jobList: [
|
||||
{ id: 9, fairId: 1, companyId: 1006, jobTitle: '电气工程师', minSalary: 8000, maxSalary: 14000, education: '本科', experience: '3-5年', vacancies: 6, status: 'active' },
|
||||
{ id: 10, fairId: 1, companyId: 1006, jobTitle: '操作工', minSalary: 4500, maxSalary: 7000, education: '高中', experience: '不限', vacancies: 30, status: 'active' },
|
||||
]},
|
||||
];
|
||||
|
||||
let nextCompanyId = 7;
|
||||
let nextPostedJobId = 11;
|
||||
|
||||
// ==================== 模块2: 展位管理 假数据 ====================
|
||||
|
||||
const MOCK_BOOTHS: BoothItem[] = [
|
||||
{ id: 1, fairId: 1, boothNumber: 'A01', companyId: 1001, companyName: '新疆天业(集团)有限公司', jobCount: 2, reviewStatus: 'approved', assignedTime: '2026-03-10 09:00:00', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 2, fairId: 1, boothNumber: 'A02', companyId: 1002, companyName: '石河子经济技术开发区管委会', jobCount: 1, reviewStatus: 'approved', assignedTime: '2026-03-10 09:30:00', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 3, fairId: 1, boothNumber: 'A03', companyId: 1003, companyName: '新疆西部牧业股份有限公司', jobCount: 2, reviewStatus: 'approved', assignedTime: '2026-03-10 10:00:00', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 4, fairId: 1, boothNumber: 'A04', companyId: 1004, companyName: '新疆生产建设兵团第八师医院', jobCount: 2, reviewStatus: 'approved', assignedTime: '2026-03-10 10:30:00', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 5, fairId: 1, boothNumber: 'A05', companyId: undefined, companyName: undefined, jobCount: 0, reviewStatus: 'pending', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 6, fairId: 1, boothNumber: 'A06', companyId: 1006, companyName: '新疆天山铝业有限公司', jobCount: 2, reviewStatus: 'approved', assignedTime: '2026-03-11 09:00:00', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 7, fairId: 1, boothNumber: 'A07', companyId: undefined, companyName: undefined, jobCount: 0, reviewStatus: 'pending', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 8, fairId: 1, boothNumber: 'A08', companyId: undefined, companyName: undefined, jobCount: 0, reviewStatus: 'pending', createTime: '2026-03-01 10:00:00' },
|
||||
{ id: 9, fairId: 1, boothNumber: 'B01', companyId: 1007, companyName: '兵团棉麻公司', jobCount: 1, reviewStatus: 'pending', createTime: '2026-03-02 10:00:00' },
|
||||
{ id: 10, fairId: 1, boothNumber: 'B02', companyId: undefined, companyName: undefined, jobCount: 0, reviewStatus: 'pending', createTime: '2026-03-02 10:00:00' },
|
||||
{ id: 11, fairId: 1, boothNumber: 'B03', companyId: undefined, companyName: undefined, jobCount: 0, reviewStatus: 'pending', createTime: '2026-03-02 10:00:00' },
|
||||
{ id: 12, fairId: 1, boothNumber: 'B04', companyId: 1008, companyName: '新疆西部绿珠果蔬有限公司', jobCount: 3, reviewStatus: 'pending', createTime: '2026-03-03 10:00:00' },
|
||||
];
|
||||
|
||||
let nextBoothId = 13;
|
||||
|
||||
// ==================== 模块3: 参会单位管理 假数据 ====================
|
||||
|
||||
const MOCK_REGISTRATIONS: CompanyRegistration[] = [
|
||||
{ id: 1, fairId: 1, companyId: 1001, companyName: '新疆天业(集团)有限公司', industry: '化工', scale: '1000人以上', contactPerson: '张经理', contactPhone: '13909930001', reviewStatus: 'approved', reviewTime: '2026-03-12 10:00:00', qrCheckInStatus: 'checked_in', checkInTime: '2026-03-15 08:30:00', registeredJobs: [
|
||||
{ id: 1, regId: 1, jobTitle: '化工工程师', minSalary: 8000, maxSalary: 12000, education: '本科', vacancies: 5, reviewStatus: 'approved' },
|
||||
{ id: 2, regId: 1, jobTitle: '安全主管', minSalary: 10000, maxSalary: 15000, education: '本科', vacancies: 2, reviewStatus: 'approved' },
|
||||
]},
|
||||
{ id: 2, fairId: 1, companyId: 1002, companyName: '石河子经济技术开发区管委会', industry: '政府/公共事业', scale: '500-1000人', contactPerson: '李主任', contactPhone: '13909930002', reviewStatus: 'approved', reviewTime: '2026-03-12 11:00:00', qrCheckInStatus: 'checked_in', checkInTime: '2026-03-15 08:45:00', registeredJobs: [
|
||||
{ id: 3, regId: 2, jobTitle: '产业招商专员', minSalary: 6000, maxSalary: 9000, education: '本科', vacancies: 10, reviewStatus: 'approved' },
|
||||
]},
|
||||
{ id: 3, fairId: 1, companyId: 1009, companyName: '兵团水利水电工程集团', industry: '建筑/工程', scale: '1000人以上', contactPerson: '刘部长', contactPhone: '13609930001', reviewStatus: 'pending', qrCheckInStatus: 'not_checked_in', registeredJobs: [
|
||||
{ id: 4, regId: 3, jobTitle: '水利工程师', minSalary: 9000, maxSalary: 14000, education: '本科', vacancies: 8, reviewStatus: 'pending' },
|
||||
{ id: 5, regId: 3, jobTitle: '造价员', minSalary: 6000, maxSalary: 10000, education: '大专', vacancies: 3, reviewStatus: 'pending' },
|
||||
]},
|
||||
{ id: 4, fairId: 1, companyId: 1010, companyName: '新疆通用航空有限责任公司', industry: '航空/交通', scale: '200-500人', contactPerson: '陈经理', contactPhone: '13809930001', reviewStatus: 'pending', qrCheckInStatus: 'not_checked_in', registeredJobs: [
|
||||
{ id: 6, regId: 4, jobTitle: '飞机维修工程师', minSalary: 12000, maxSalary: 18000, education: '本科', vacancies: 4, reviewStatus: 'pending' },
|
||||
]},
|
||||
{ id: 5, fairId: 1, companyId: 1011, companyName: '石河子市公共交通有限责任公司', industry: '交通/运输', scale: '500-1000人', contactPerson: '马科长', contactPhone: '13709930001', reviewStatus: 'pending', qrCheckInStatus: 'not_checked_in', registeredJobs: [
|
||||
{ id: 7, regId: 5, jobTitle: '调度员', minSalary: 4500, maxSalary: 6500, education: '大专', vacancies: 5, reviewStatus: 'pending' },
|
||||
]},
|
||||
{ id: 6, fairId: 1, companyId: 1012, companyName: '兵团棉麻公司', industry: '农业/贸易', scale: '200-500人', contactPerson: '彭经理', contactPhone: '13509930001', reviewStatus: 'rejected', reviewTime: '2026-03-13 15:00:00', reviewRemark: '资料不全,请补充企业营业执照', qrCheckInStatus: 'not_checked_in', registeredJobs: []},
|
||||
];
|
||||
|
||||
let nextRegId = 7;
|
||||
let nextRegJobId = 8;
|
||||
|
||||
// ==================== 模块4: 参会人员管理 假数据 ====================
|
||||
|
||||
const MOCK_ATTENDEES: AttendeeItem[] = [
|
||||
{ id: 1, fairId: 1, name: '阿依古丽·买买提', gender: '女', phone: '15009930001', idCard: '659001199805010012', education: '本科', graduationSchool: '石河子大学', major: '化学工程', checkInTime: '2026-03-15 08:30:00', checkInMethod: 'qr_scan', targetCompanies: '新疆天业(集团)有限公司', mobileInteraction: true, resumeUrl: 'http://example.com/resume/1', interviewStatus: 'passed', interviewCompany: '新疆天业(集团)有限公司', interviewTime: '2026-03-15 14:00:00', interviewResult: '通过,已发offer' },
|
||||
{ id: 2, fairId: 1, name: '张伟', gender: '男', phone: '15009930002', idCard: '659001199706150018', education: '硕士', graduationSchool: '新疆大学', major: '经济学', checkInTime: '2026-03-15 08:35:00', checkInMethod: 'qr_scan', targetCompanies: '石河子经济技术开发区管委会', mobileInteraction: true, interviewStatus: 'completed', interviewCompany: '石河子经济技术开发区管委会', interviewTime: '2026-03-15 15:30:00', interviewResult: '二面待通知' },
|
||||
{ id: 3, fairId: 1, name: '李军', gender: '男', phone: '15009930003', idCard: '659001199409200011', education: '大专', graduationSchool: '新疆石河子职业技术学院', major: '畜牧兽医', checkInTime: '2026-03-15 08:40:00', checkInMethod: 'id_card', targetCompanies: '新疆西部牧业股份有限公司', mobileInteraction: false, interviewStatus: 'scheduled', interviewCompany: '新疆西部牧业股份有限公司', interviewTime: '2026-03-15 16:00:00' },
|
||||
{ id: 4, fairId: 1, name: '王芳', gender: '女', phone: '15009930004', idCard: '659001200005280022', education: '本科', graduationSchool: '石河子大学', major: '临床医学', checkInTime: '2026-03-15 08:50:00', checkInMethod: 'qr_scan', targetCompanies: '新疆生产建设兵团第八师医院', mobileInteraction: true, interviewStatus: 'in_progress', interviewCompany: '新疆生产建设兵团第八师医院', interviewTime: '2026-03-15 11:00:00' },
|
||||
{ id: 5, fairId: 1, name: '赵强', gender: '男', phone: '15009930005', idCard: '659001199301100016', education: '本科', graduationSchool: '塔里木大学', major: '电气工程', checkInTime: '2026-03-15 09:00:00', checkInMethod: 'manual', targetCompanies: '新疆天山铝业有限公司', mobileInteraction: false, interviewStatus: 'none' },
|
||||
{ id: 6, fairId: 1, name: '热娜古丽·艾山', gender: '女', phone: '15009930006', idCard: '659001199812030020', education: '硕士', graduationSchool: '新疆大学', major: '会计学', checkInTime: '2026-03-15 09:10:00', checkInMethod: 'qr_scan', targetCompanies: '新疆天业(集团)有限公司', mobileInteraction: true, resumeUrl: 'http://example.com/resume/6', interviewStatus: 'scheduled', interviewCompany: '新疆天业(集团)有限公司', interviewTime: '2026-03-15 15:00:00' },
|
||||
{ id: 7, fairId: 1, name: '陈明', gender: '男', phone: '15009930007', idCard: '659001199510150013', education: '大专', graduationSchool: '新疆石河子职业技术学院', major: '机电一体化', checkInTime: '2026-03-15 09:20:00', checkInMethod: 'qr_scan', targetCompanies: '新疆天山铝业有限公司', mobileInteraction: true, interviewStatus: 'completed', interviewCompany: '新疆天山铝业有限公司', interviewTime: '2026-03-15 10:30:00', interviewResult: '待定' },
|
||||
{ id: 8, fairId: 1, name: '孙丽', gender: '女', phone: '15009930008', idCard: '659001199908220025', education: '本科', graduationSchool: '石河子大学', major: '市场营销', checkInTime: undefined, checkInMethod: 'qr_scan', targetCompanies: '石河子经济技术开发区管委会', mobileInteraction: false, interviewStatus: 'none' },
|
||||
{ id: 9, fairId: 1, name: '周亮', gender: '男', phone: '15009930009', idCard: '659001200103150019', education: '本科', graduationSchool: '石河子大学', major: '金融学', checkInTime: undefined, checkInMethod: 'id_card', targetCompanies: '石河子经济技术开发区管委会', mobileInteraction: false, interviewStatus: 'none' },
|
||||
{ id: 10, fairId: 1, name: '吴娜', gender: '女', phone: '15009930010', idCard: '659001199704080026', education: '硕士', graduationSchool: '新疆大学', major: '药学', checkInTime: '2026-03-15 09:30:00', checkInMethod: 'qr_scan', targetCompanies: '新疆生产建设兵团第八师医院', mobileInteraction: true, resumeUrl: 'http://example.com/resume/10', interviewStatus: 'in_progress', interviewCompany: '新疆生产建设兵团第八师医院', interviewTime: '2026-03-15 14:30:00' },
|
||||
{ id: 11, fairId: 1, name: '郑涛', gender: '男', phone: '15009930011', idCard: '659001199305120010', education: '本科', graduationSchool: '塔里木大学', major: '农学', checkInTime: '2026-03-15 09:40:00', checkInMethod: 'manual', targetCompanies: '新疆西部牧业股份有限公司', mobileInteraction: false, interviewStatus: 'failed', interviewCompany: '新疆西部牧业股份有限公司', interviewTime: '2026-03-15 11:30:00', interviewResult: '岗位不匹配' },
|
||||
{ id: 12, fairId: 1, name: '马丽娜', gender: '女', phone: '15009930012', idCard: '659001199906180028', education: '本科', graduationSchool: '石河子大学', major: '人力资源管理', checkInTime: '2026-03-15 09:50:00', checkInMethod: 'qr_scan', targetCompanies: '新疆通用航空有限责任公司', mobileInteraction: true, interviewStatus: 'scheduled', interviewCompany: '新疆通用航空有限责任公司', interviewTime: '2026-03-15 16:30:00' },
|
||||
];
|
||||
|
||||
let nextAttendeeId = 13;
|
||||
|
||||
// ==================== 模块5: 入场设备管理 假数据 ====================
|
||||
|
||||
const MOCK_DEVICES: DeviceItem[] = [
|
||||
{ id: 1, fairId: 1, type: 'mobile_terminal', deviceName: '移动终端-01', deviceCode: 'MT-20260315-001', assignedBoothId: 1, assignedBoothNumber: 'A01', assignedCompanyName: '新疆天业(集团)有限公司', status: 'online', lastActiveTime: '2026-03-15 10:30:00' },
|
||||
{ id: 2, fairId: 1, type: 'mobile_terminal', deviceName: '移动终端-02', deviceCode: 'MT-20260315-002', assignedBoothId: 2, assignedBoothNumber: 'A02', assignedCompanyName: '石河子经济技术开发区管委会', status: 'online', lastActiveTime: '2026-03-15 10:25:00' },
|
||||
{ id: 3, fairId: 1, type: 'mobile_terminal', deviceName: '移动终端-03', deviceCode: 'MT-20260315-003', assignedBoothId: 3, assignedBoothNumber: 'A03', assignedCompanyName: '新疆西部牧业股份有限公司', status: 'online', lastActiveTime: '2026-03-15 10:20:00' },
|
||||
{ id: 4, fairId: 1, type: 'mobile_terminal', deviceName: '移动终端-04', deviceCode: 'MT-20260315-004', assignedBoothId: 6, assignedBoothNumber: 'A06', assignedCompanyName: '新疆天山铝业有限公司', status: 'offline', lastActiveTime: '2026-03-15 09:00:00' },
|
||||
{ id: 5, fairId: 1, type: 'mobile_terminal', deviceName: '移动终端-05', deviceCode: 'MT-20260315-005', status: 'offline' },
|
||||
{ id: 6, fairId: 1, type: 'mobile_terminal', deviceName: '移动终端-06', deviceCode: 'MT-20260315-006', status: 'offline' },
|
||||
{ id: 7, fairId: 1, type: 'qr_sticker', deviceName: '展位二维码-A01', deviceCode: 'QR-20260315-A01', assignedBoothId: 1, assignedBoothNumber: 'A01', assignedCompanyName: '新疆天业(集团)有限公司', status: 'online' },
|
||||
{ id: 8, fairId: 1, type: 'qr_sticker', deviceName: '展位二维码-A02', deviceCode: 'QR-20260315-A02', assignedBoothId: 2, assignedBoothNumber: 'A02', assignedCompanyName: '石河子经济技术开发区管委会', status: 'online' },
|
||||
{ id: 9, fairId: 1, type: 'qr_sticker', deviceName: '展位二维码-A03', deviceCode: 'QR-20260315-A03', assignedBoothId: 3, assignedBoothNumber: 'A03', assignedCompanyName: '新疆西部牧业股份有限公司', status: 'online' },
|
||||
{ id: 10, fairId: 1, type: 'qr_sticker', deviceName: '展位二维码-A04', deviceCode: 'QR-20260315-A04', assignedBoothId: 4, assignedBoothNumber: 'A04', assignedCompanyName: '新疆生产建设兵团第八师医院', status: 'online' },
|
||||
{ id: 11, fairId: 1, type: 'qr_sticker', deviceName: '展位二维码-A05', deviceCode: 'QR-20260315-A05', status: 'offline' },
|
||||
{ id: 12, fairId: 1, type: 'qr_sticker', deviceName: '展位二维码-A06', deviceCode: 'QR-20260315-A06', assignedBoothId: 6, assignedBoothNumber: 'A06', assignedCompanyName: '新疆天山铝业有限公司', status: 'online' },
|
||||
];
|
||||
|
||||
let nextDeviceId = 13;
|
||||
|
||||
const MOCK_GATE_STATUSES: GateStatus[] = [
|
||||
{ id: 1, fairId: 1, gateName: '主入口闸机', isOpen: true, totalScans: 45 },
|
||||
{ id: 2, fairId: 1, gateName: '侧入口闸机', isOpen: false, totalScans: 12 },
|
||||
];
|
||||
|
||||
const MOCK_GATE_LOGS: GateEntryLog[] = [
|
||||
{ id: 1, fairId: 1, attendeeName: '阿依古丽·买买提', scanTime: '2026-03-15 08:30:00', gateName: '主入口闸机', scanMethod: 'qr' },
|
||||
{ id: 2, fairId: 1, attendeeName: '张伟', scanTime: '2026-03-15 08:35:00', gateName: '主入口闸机', scanMethod: 'qr' },
|
||||
{ id: 3, fairId: 1, attendeeName: '李军', scanTime: '2026-03-15 08:40:00', gateName: '主入口闸机', scanMethod: 'id_card' },
|
||||
{ id: 4, fairId: 1, attendeeName: '王芳', scanTime: '2026-03-15 08:50:00', gateName: '侧入口闸机', scanMethod: 'qr' },
|
||||
{ id: 5, fairId: 1, attendeeName: '赵强', scanTime: '2026-03-15 09:00:00', gateName: '主入口闸机', scanMethod: 'id_card' },
|
||||
{ id: 6, fairId: 1, attendeeName: '热娜古丽·艾山', scanTime: '2026-03-15 09:10:00', gateName: '主入口闸机', scanMethod: 'qr' },
|
||||
{ id: 7, fairId: 1, attendeeName: '陈明', scanTime: '2026-03-15 09:20:00', gateName: '侧入口闸机', scanMethod: 'qr' },
|
||||
{ id: 8, fairId: 1, attendeeName: '吴娜', scanTime: '2026-03-15 09:30:00', gateName: '主入口闸机', scanMethod: 'qr' },
|
||||
];
|
||||
|
||||
let nextGateLogId = 9;
|
||||
|
||||
// ==================== 模块6: 数据统计 假数据 ====================
|
||||
|
||||
const MOCK_STATISTICS: Record<number, FairStatistics> = {
|
||||
1: {
|
||||
fairId: 1,
|
||||
companyCount: 25,
|
||||
jobCount: 86,
|
||||
demandCount: 520,
|
||||
intentionCount: 180,
|
||||
industryDistribution: [
|
||||
{ industry: '化工', count: 5 }, { industry: '政府', count: 2 }, { industry: '农业', count: 4 },
|
||||
{ industry: '医疗', count: 3 }, { industry: '教育', count: 3 }, { industry: '制造', count: 4 },
|
||||
{ industry: '建筑', count: 2 }, { industry: '航空', count: 1 }, { industry: '交通', count: 1 },
|
||||
],
|
||||
jobTypeDistribution: [
|
||||
{ type: '技术类', count: 30 }, { type: '管理类', count: 15 }, { type: '销售类', count: 12 },
|
||||
{ type: '行政类', count: 10 }, { type: '一线工人', count: 14 }, { type: '其他', count: 5 },
|
||||
],
|
||||
dailyAttendees: [
|
||||
{ date: '2026-03-15', count: 320 },
|
||||
],
|
||||
timeSlotDistribution: [
|
||||
{ slot: '08:00-09:00', count: 80 }, { slot: '09:00-10:00', count: 120 },
|
||||
{ slot: '10:00-11:00', count: 65 }, { slot: '11:00-12:00', count: 30 },
|
||||
{ slot: '12:00-13:00', count: 10 }, { slot: '13:00-14:00', count: 5 },
|
||||
{ slot: '14:00-15:00', count: 5 }, { slot: '15:00-16:00', count: 5 },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
// ==================== 通用工具函数 ====================
|
||||
|
||||
function paginate<T>(arr: T[], current: number, pageSize: number) {
|
||||
const start = (current - 1) * pageSize;
|
||||
return arr.slice(start, start + pageSize);
|
||||
}
|
||||
|
||||
// ==================== 模块1: 招聘会管理 API ====================
|
||||
|
||||
/** 获取参会企业列表 */
|
||||
export async function getParticipatingCompanies(fairId: number, params?: { current?: number; pageSize?: number; companyName?: string }) {
|
||||
let list = MOCK_COMPANIES.filter(c => c.fairId === fairId);
|
||||
if (params?.companyName) {
|
||||
list = list.filter(c => c.companyName.includes(params.companyName!));
|
||||
}
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
/** 添加参会企业 */
|
||||
export async function addParticipatingCompany(data: { fairId: number; companyId: number; companyName: string; industry: string; scale: string; contactPerson: string; contactPhone: string }) {
|
||||
const company: ParticipatingCompany = {
|
||||
...data,
|
||||
id: nextCompanyId++,
|
||||
jobList: [],
|
||||
};
|
||||
MOCK_COMPANIES.unshift(company);
|
||||
return { code: 200, msg: '添加成功', data: company };
|
||||
}
|
||||
|
||||
/** 移除参会企业 */
|
||||
export async function removeParticipatingCompany(id: number) {
|
||||
const idx = MOCK_COMPANIES.findIndex(c => c.id === id);
|
||||
if (idx !== -1) { MOCK_COMPANIES.splice(idx, 1); return { code: 200, msg: '移除成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
/** 替企业发布岗位 */
|
||||
export async function addJobForCompany(data: { fairId: number; companyId: number; jobTitle: string; minSalary: number; maxSalary: number; education: string; experience: string; vacancies: number }) {
|
||||
const company = MOCK_COMPANIES.find(c => c.id === data.companyId);
|
||||
if (!company) return { code: 404, msg: '企业未找到' };
|
||||
const job: PostedJob = {
|
||||
...data,
|
||||
id: nextPostedJobId++,
|
||||
status: 'active',
|
||||
};
|
||||
company.jobList.push(job);
|
||||
return { code: 200, msg: '岗位添加成功', data: job };
|
||||
}
|
||||
|
||||
/** 编辑岗位 */
|
||||
export async function updateJobForCompany(data: PostedJob) {
|
||||
for (const c of MOCK_COMPANIES) {
|
||||
const idx = c.jobList.findIndex(j => j.id === data.id);
|
||||
if (idx !== -1) { c.jobList[idx] = { ...c.jobList[idx], ...data }; return { code: 200, msg: '修改成功' }; }
|
||||
}
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
/** 删除岗位 */
|
||||
export async function removeJobFromCompany(jobId: number) {
|
||||
for (const c of MOCK_COMPANIES) {
|
||||
const idx = c.jobList.findIndex(j => j.id === jobId);
|
||||
if (idx !== -1) { c.jobList.splice(idx, 1); return { code: 200, msg: '删除成功' }; }
|
||||
}
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
// ==================== 模块2: 展位管理 API ====================
|
||||
|
||||
/** 获取展位列表 */
|
||||
export async function getBoothList(fairId: number, params?: { current?: number; pageSize?: number; boothNumber?: string; reviewStatus?: string }) {
|
||||
let list = MOCK_BOOTHS.filter(b => b.fairId === fairId);
|
||||
if (params?.boothNumber) list = list.filter(b => b.boothNumber.includes(params.boothNumber!));
|
||||
if (params?.reviewStatus) list = list.filter(b => b.reviewStatus === params.reviewStatus);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
/** 新增展位 */
|
||||
export async function addBooth(data: { fairId: number; boothNumber: string }) {
|
||||
const booth: BoothItem = {
|
||||
id: nextBoothId++,
|
||||
fairId: data.fairId,
|
||||
boothNumber: data.boothNumber,
|
||||
companyId: undefined,
|
||||
companyName: undefined,
|
||||
jobCount: 0,
|
||||
reviewStatus: 'pending',
|
||||
createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
};
|
||||
MOCK_BOOTHS.push(booth);
|
||||
return { code: 200, msg: '新增成功', data: booth };
|
||||
}
|
||||
|
||||
/** 修改展位 */
|
||||
export async function updateBooth(data: { id: number; boothNumber: string }) {
|
||||
const idx = MOCK_BOOTHS.findIndex(b => b.id === data.id);
|
||||
if (idx !== -1) { MOCK_BOOTHS[idx].boothNumber = data.boothNumber; return { code: 200, msg: '修改成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
/** 删除展位 */
|
||||
export async function deleteBooth(id: number) {
|
||||
const idx = MOCK_BOOTHS.findIndex(b => b.id === id);
|
||||
if (idx !== -1) { MOCK_BOOTHS.splice(idx, 1); return { code: 200, msg: '删除成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
/** 审核展位 */
|
||||
export async function reviewBooth(id: number, status: string) {
|
||||
const booth = MOCK_BOOTHS.find(b => b.id === id);
|
||||
if (!booth) return { code: 404, msg: '未找到' };
|
||||
booth.reviewStatus = status;
|
||||
if (status === 'approved') booth.assignedTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
return { code: 200, msg: status === 'approved' ? '审核通过' : '审核拒绝' };
|
||||
}
|
||||
|
||||
/** 分配展位给企业 */
|
||||
export async function assignBooth(params: BoothAssignParams) {
|
||||
const booth = MOCK_BOOTHS.find(b => b.id === params.boothId);
|
||||
if (!booth) return { code: 404, msg: '展位未找到' };
|
||||
booth.companyId = params.companyId;
|
||||
booth.companyName = MOCK_REGISTRATIONS.find(r => r.companyId === params.companyId)?.companyName || '';
|
||||
booth.boothNumber = params.boothNumber;
|
||||
booth.assignedTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
return { code: 200, msg: '展位分配成功' };
|
||||
}
|
||||
|
||||
// ==================== 模块3: 参会单位管理 API ====================
|
||||
|
||||
/** 获取单位报名列表 */
|
||||
export async function getCompanyRegistrationList(fairId: number, params?: { current?: number; pageSize?: number; companyName?: string; reviewStatus?: string }) {
|
||||
let list = MOCK_REGISTRATIONS.filter(r => r.fairId === fairId);
|
||||
if (params?.companyName) list = list.filter(r => r.companyName.includes(params.companyName!));
|
||||
if (params?.reviewStatus) list = list.filter(r => r.reviewStatus === params.reviewStatus);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
/** 审核参会单位 */
|
||||
export async function reviewCompanyRegistration(id: number, status: string, remark?: string) {
|
||||
const reg = MOCK_REGISTRATIONS.find(r => r.id === id);
|
||||
if (!reg) return { code: 404, msg: '未找到' };
|
||||
reg.reviewStatus = status;
|
||||
reg.reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
if (remark) reg.reviewRemark = remark;
|
||||
return { code: 200, msg: status === 'approved' ? '审核通过' : '审核拒绝' };
|
||||
}
|
||||
|
||||
/** 审核岗位 */
|
||||
export async function reviewRegisteredJob(regId: number, jobId: number, status: string) {
|
||||
const reg = MOCK_REGISTRATIONS.find(r => r.id === regId);
|
||||
if (!reg) return { code: 404, msg: '未找到报名记录' };
|
||||
const job = reg.registeredJobs.find(j => j.id === jobId);
|
||||
if (!job) return { code: 404, msg: '岗位未找到' };
|
||||
job.reviewStatus = status;
|
||||
return { code: 200, msg: status === 'approved' ? '岗位审核通过' : '岗位审核拒绝' };
|
||||
}
|
||||
|
||||
/** 模拟扫码签到 */
|
||||
export async function qrCheckIn(regId: number) {
|
||||
const reg = MOCK_REGISTRATIONS.find(r => r.id === regId);
|
||||
if (!reg) return { code: 404, msg: '未找到' };
|
||||
reg.qrCheckInStatus = 'checked_in';
|
||||
reg.checkInTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
|
||||
return { code: 200, msg: '签到成功' };
|
||||
}
|
||||
|
||||
// ==================== 模块4: 参会人员管理 API ====================
|
||||
|
||||
/** 获取参会人员列表 */
|
||||
export async function getAttendeeList(fairId: number, params?: { current?: number; pageSize?: number; name?: string; phone?: string; interviewStatus?: string }) {
|
||||
let list = MOCK_ATTENDEES.filter(a => a.fairId === fairId);
|
||||
if (params?.name) list = list.filter(a => a.name.includes(params.name!));
|
||||
if (params?.phone) list = list.filter(a => a.phone.includes(params.phone!));
|
||||
if (params?.interviewStatus) list = list.filter(a => a.interviewStatus === params.interviewStatus);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
/** 模拟扫码入场 */
|
||||
export async function scanAttendeeEntry(data: { name: string; phone: string; idCard: string; checkInMethod: string }) {
|
||||
const attendee: AttendeeItem = {
|
||||
id: nextAttendeeId++,
|
||||
fairId: 1,
|
||||
name: data.name,
|
||||
gender: '男',
|
||||
phone: data.phone,
|
||||
idCard: data.idCard,
|
||||
education: '本科',
|
||||
graduationSchool: '',
|
||||
major: '',
|
||||
checkInTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
checkInMethod: data.checkInMethod,
|
||||
targetCompanies: '',
|
||||
mobileInteraction: false,
|
||||
interviewStatus: 'none',
|
||||
};
|
||||
MOCK_ATTENDEES.unshift(attendee);
|
||||
return { code: 200, msg: '入场登记成功', data: attendee };
|
||||
}
|
||||
|
||||
/** 编辑参会人员简历 */
|
||||
export async function updateAttendeeResume(id: number, data: { education: string; graduationSchool: string; major: string; resumeContent: string }) {
|
||||
const attendee = MOCK_ATTENDEES.find(a => a.id === id);
|
||||
if (!attendee) return { code: 404, msg: '未找到' };
|
||||
Object.assign(attendee, data);
|
||||
return { code: 200, msg: '简历更新成功' };
|
||||
}
|
||||
|
||||
/** 面试跟踪 */
|
||||
export async function trackInterview(params: InterviewTrackParams) {
|
||||
const attendee = MOCK_ATTENDEES.find(a => a.id === params.attendeeId);
|
||||
if (!attendee) return { code: 404, msg: '未找到' };
|
||||
attendee.interviewStatus = params.interviewStatus;
|
||||
attendee.interviewCompany = params.interviewCompany;
|
||||
attendee.interviewTime = params.interviewTime;
|
||||
if (params.interviewResult) attendee.interviewResult = params.interviewResult;
|
||||
return { code: 200, msg: '面试信息更新成功' };
|
||||
}
|
||||
|
||||
// ==================== 模块5: 入场设备管理 API ====================
|
||||
|
||||
/** 获取设备列表 */
|
||||
export async function getDeviceList(fairId: number, params?: { current?: number; pageSize?: number; type?: string }) {
|
||||
let list = MOCK_DEVICES.filter(d => d.fairId === fairId);
|
||||
if (params?.type) list = list.filter(d => d.type === params.type);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
/** 新增设备 */
|
||||
export async function addDevice(data: { fairId: number; type: string; deviceName: string; deviceCode: string }) {
|
||||
const device: DeviceItem = {
|
||||
id: nextDeviceId++,
|
||||
fairId: data.fairId,
|
||||
type: data.type,
|
||||
deviceName: data.deviceName,
|
||||
deviceCode: data.deviceCode,
|
||||
status: 'offline',
|
||||
};
|
||||
MOCK_DEVICES.push(device);
|
||||
return { code: 200, msg: '新增成功', data: device };
|
||||
}
|
||||
|
||||
/** 修改设备 */
|
||||
export async function updateDevice(data: { id: number; deviceName: string; deviceCode: string }) {
|
||||
const idx = MOCK_DEVICES.findIndex(d => d.id === data.id);
|
||||
if (idx !== -1) { MOCK_DEVICES[idx].deviceName = data.deviceName; MOCK_DEVICES[idx].deviceCode = data.deviceCode; return { code: 200, msg: '修改成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
/** 删除设备 */
|
||||
export async function deleteDevice(id: number) {
|
||||
const idx = MOCK_DEVICES.findIndex(d => d.id === id);
|
||||
if (idx !== -1) { MOCK_DEVICES.splice(idx, 1); return { code: 200, msg: '删除成功' }; }
|
||||
return { code: 404, msg: '未找到' };
|
||||
}
|
||||
|
||||
/** 分配设备到展位 */
|
||||
export async function assignDevice(deviceId: number, boothId: number, boothNumber: string, companyName: string) {
|
||||
const device = MOCK_DEVICES.find(d => d.id === deviceId);
|
||||
if (!device) return { code: 404, msg: '设备未找到' };
|
||||
device.assignedBoothId = boothId;
|
||||
device.assignedBoothNumber = boothNumber;
|
||||
device.assignedCompanyName = companyName;
|
||||
return { code: 200, msg: '设备分配成功' };
|
||||
}
|
||||
|
||||
/** 切换设备状态 */
|
||||
export async function toggleDeviceStatus(id: number) {
|
||||
const device = MOCK_DEVICES.find(d => d.id === id);
|
||||
if (!device) return { code: 404, msg: '设备未找到' };
|
||||
device.status = device.status === 'online' ? 'offline' : 'online';
|
||||
device.lastActiveTime = device.status === 'online' ? new Date().toISOString().replace('T', ' ').substring(0, 19) : undefined;
|
||||
return { code: 200, msg: device.status === 'online' ? '设备已启用' : '设备已禁用' };
|
||||
}
|
||||
|
||||
/** 获取闸机状态 */
|
||||
export async function getGateStatuses(fairId: number) {
|
||||
return { code: 200, rows: MOCK_GATE_STATUSES.filter(g => g.fairId === fairId) };
|
||||
}
|
||||
|
||||
/** 切换闸机开关 */
|
||||
export async function toggleGate(id: number) {
|
||||
const gate = MOCK_GATE_STATUSES.find(g => g.id === id);
|
||||
if (!gate) return { code: 404, msg: '闸机未找到' };
|
||||
gate.isOpen = !gate.isOpen;
|
||||
return { code: 200, msg: gate.isOpen ? '闸机已开启' : '闸机已关闭' };
|
||||
}
|
||||
|
||||
/** 获取闸机入场日志 */
|
||||
export async function getGateEntryLogs(fairId: number, params?: { current?: number; pageSize?: number }) {
|
||||
const list = MOCK_GATE_LOGS.filter(l => l.fairId === fairId);
|
||||
const total = list.length;
|
||||
const rows = paginate(list, params?.current || 1, params?.pageSize || 10);
|
||||
return { code: 200, total, rows };
|
||||
}
|
||||
|
||||
/** 模拟闸机扫码 */
|
||||
export async function simulateGateScan(data: { fairId: number; gateName: string; attendeeName: string; scanMethod: string }) {
|
||||
const gate = MOCK_GATE_STATUSES.find(g => g.fairId === data.fairId && g.gateName === data.gateName);
|
||||
if (!gate) return { code: 404, msg: '闸机未找到' };
|
||||
if (!gate.isOpen) return { code: 400, msg: '闸机未开启' };
|
||||
gate.totalScans++;
|
||||
const log: GateEntryLog = {
|
||||
id: nextGateLogId++,
|
||||
fairId: data.fairId,
|
||||
attendeeName: data.attendeeName,
|
||||
scanTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
|
||||
gateName: data.gateName,
|
||||
scanMethod: data.scanMethod,
|
||||
};
|
||||
MOCK_GATE_LOGS.unshift(log);
|
||||
return { code: 200, msg: '扫码成功,闸机已放行', data: log };
|
||||
}
|
||||
|
||||
// ==================== 模块6: 数据统计 API ====================
|
||||
|
||||
/** 获取招聘会统计数据 */
|
||||
export async function getFairStatistics(fairId: number) {
|
||||
const data = MOCK_STATISTICS[fairId];
|
||||
if (data) return { code: 200, data };
|
||||
// 如果没有该招聘会统计,生成默认数据
|
||||
const defaultData: FairStatistics = {
|
||||
fairId,
|
||||
companyCount: 0,
|
||||
jobCount: 0,
|
||||
demandCount: 0,
|
||||
intentionCount: 0,
|
||||
industryDistribution: [],
|
||||
jobTypeDistribution: [],
|
||||
dailyAttendees: [],
|
||||
timeSlotDistribution: [],
|
||||
};
|
||||
return { code: 200, data: defaultData };
|
||||
}
|
||||
Reference in New Issue
Block a user