/** * 岗位信息管理API - 后台管理 * 提供岗位信息的查询和管理功能 */ const Framework = require("../../framework/node-core-framework.js"); const jobManager = require("../middleware/job/jobManager.js"); module.exports = { /** * @swagger * /admin_api/job/list: * post: * summary: 获取岗位列表 * description: 分页获取所有岗位信息 * tags: [后台-岗位管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * properties: * page: * type: integer * description: 页码 * pageSize: * type: integer * description: 每页数量 * platform: * type: string * description: 平台(可选) * isOutsourcing: * type: boolean * description: 是否外包(可选) * responses: * 200: * description: 获取成功 */ 'POST /job/list': async (ctx) => { const models = Framework.getModels(); const { job_postings, op } = models; const body = ctx.getBody(); const { platform, isOutsourcing, minSalary, maxSalary, searchText } = ctx.getBody(); // 获取分页参数 const { limit, offset } = ctx.getPageSize(); const where = {}; if (platform) { where.platform = platform; } if (isOutsourcing) { where.isOutsourcing = isOutsourcing; } // 薪资范围筛选 if (minSalary) { where.salaryMin = { [op.gte]: minSalary }; } if (maxSalary) { where.salaryMax = { [op.lte]: maxSalary }; } // 支持搜索岗位名称、公司名称 if (searchText) { where[op.or] = [ { jobTitle: { [op.like]: `%${searchText}%` } }, { companyName: { [op.like]: `%${searchText}%` } } ]; } const result = await job_postings.findAndCountAll({ where, limit, offset, order: [ ['aiMatchScore', 'DESC'], ['id', 'DESC'] ] }); return ctx.success(result); }, /** * @swagger * /admin_api/job/statistics: * get: * summary: 获取岗位统计 * description: 获取岗位信息的统计数据 * tags: [后台-岗位管理] * responses: * 200: * description: 获取成功 */ 'GET /job/statistics': async (ctx) => { const models = Framework.getModels(); const { job_postings } = models; const [ totalJobs, outsourcingJobs, directJobs, highMatchJobs ] = await Promise.all([ job_postings.count(), job_postings.count({ where: { isOutsourcing: true } }), job_postings.count({ where: { isOutsourcing: false } }), job_postings.count({ where: { aiMatchScore: { [models.op.gte]: 80 } } }) ]); // 按平台统计 const platformStats = await job_postings.findAll({ attributes: [ 'platform', [models.sequelize.fn('COUNT', models.sequelize.col('*')), 'count'] ], group: ['platform'], raw: true }); // 平均匹配度 const avgMatchScore = await job_postings.findAll({ attributes: [ [models.sequelize.fn('AVG', models.sequelize.col('aiMatchScore')), 'avgScore'] ], raw: true }); // 薪资统计 const salaryStats = await job_postings.findAll({ attributes: [ [models.sequelize.fn('AVG', models.sequelize.col('salaryMin')), 'avgMinSalary'], [models.sequelize.fn('AVG', models.sequelize.col('salaryMax')), 'avgMaxSalary'], [models.sequelize.fn('MAX', models.sequelize.col('salaryMax')), 'maxSalary'], [models.sequelize.fn('MIN', models.sequelize.col('salaryMin')), 'minSalary'] ], raw: true }); return ctx.success({ totalJobs, outsourcingJobs, directJobs, highMatchJobs, outsourcingRate: totalJobs > 0 ? ((outsourcingJobs / totalJobs) * 100).toFixed(2) : 0, averageMatchScore: parseFloat(avgMatchScore[0]?.avgScore || 0).toFixed(2), platformStats, salaryStats: salaryStats[0] || {} }); }, /** * @swagger * /admin_api/job/detail: * get: * summary: 获取岗位详情 * description: 根据岗位ID获取详细信息 * tags: [后台-岗位管理] * parameters: * - in: query * name: jobId * required: true * schema: * type: string * description: 岗位ID * responses: * 200: * description: 获取成功 */ 'GET /job/detail': async (ctx) => { const models = Framework.getModels(); const { job_postings } = models; const { jobId } = ctx.query; if (!jobId) { return ctx.fail('岗位ID不能为空'); } const job = await job_postings.findOne({ where: { jobId } }); if (!job) { return ctx.fail('岗位不存在'); } return ctx.success(job); }, /** * @swagger * /admin_api/job/delete: * post: * summary: 删除岗位 * description: 删除指定的岗位信息 * tags: [后台-岗位管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - jobId * properties: * jobId: * type: string * description: 岗位ID * responses: * 200: * description: 删除成功 */ 'POST /job/delete': async (ctx) => { const models = Framework.getModels(); const { job_postings } = models; const body = ctx.getBody(); const { jobId } = body; if (!jobId) { return ctx.fail('岗位ID不能为空'); } const result = await job_postings.destroy({ where: { jobId } }); if (result === 0) { return ctx.fail('岗位不存在'); } return ctx.success({ message: '岗位删除成功' }); }, /** * @swagger * /admin_api/job/greet: * post: * summary: 职位打招呼 * description: 向指定职位的HR打招呼(通过MQTT发送指令到boss-automation-nodejs) * tags: [后台-岗位管理] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - sn_code * - encryptJobId * properties: * sn_code: * type: string * description: 设备SN码 * encryptJobId: * type: string * description: 加密的职位ID * securityId: * type: string * description: 安全ID(可选) * brandName: * type: string * description: 公司名称 * platform: * type: string * description: 平台(默认boss) * responses: * 200: * description: 打招呼成功 */ 'POST /job/greet': async (ctx) => { const body = ctx.getBody(); const { sn_code, encryptJobId, securityId, brandName, platform = 'boss' } = body; const result = await jobManager.job_greet({ sn_code, encryptJobId, securityId, brandName, platform }); return ctx.success(result); } };