Files
autoAiWorkSys/api/controller_admin/apply_records.js
张成 5d7444cd65 1
2025-11-24 13:23:42 +08:00

269 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 投递记录管理API - 后台管理
* 提供投递记录的查询和管理功能
*/
const Framework = require("../../framework/node-core-framework.js");
module.exports = {
/**
* @swagger
* /admin_api/apply/list:
* post:
* summary: 获取投递记录列表
* description: 分页获取所有投递记录
* tags: [后台-投递管理]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* seachOption:
* type: object
* description: 搜索条件
* properties:
* key:
* type: string
* description: 搜索字段(jobTitle/companyName/sn_code)
* value:
* type: string
* description: 搜索值
* platform:
* type: string
* description: 平台筛选(boss/liepin)
* applyStatus:
* type: string
* description: 投递状态筛选
* feedbackStatus:
* type: string
* description: 反馈状态筛选
* pageOption:
* type: object
* description: 分页选项
* properties:
* page:
* type: integer
* description: 页码
* pageSize:
* type: integer
* description: 每页数量
* responses:
* 200:
* description: 获取成功
*/
'POST /apply/list': async (ctx) => {
const models = Framework.getModels();
const { apply_records, op } = models;
const body = ctx.getBody();
const seachOption = body.seachOption || {};
const pageOption = body.pageOption || {};
// 获取分页参数
const page = pageOption.page || 1;
const pageSize = pageOption.pageSize || 20;
const limit = pageSize;
const offset = (page - 1) * pageSize;
const where = {};
// 平台筛选
if (seachOption.platform) {
where.platform = seachOption.platform;
}
// 投递状态筛选
if (seachOption.applyStatus) {
where.applyStatus = seachOption.applyStatus;
}
// 反馈状态筛选
if (seachOption.feedbackStatus) {
where.feedbackStatus = seachOption.feedbackStatus;
}
// 搜索岗位名称、公司名称、设备SN码
if (seachOption.key && seachOption.value) {
const key = seachOption.key;
const value = seachOption.value;
if (key === 'jobTitle') {
where.jobTitle = { [op.like]: `%${value}%` };
} else if (key === 'companyName') {
where.companyName = { [op.like]: `%${value}%` };
} else if (key === 'sn_code') {
where.sn_code = { [op.like]: `%${value}%` };
} else {
// 默认搜索岗位名称或公司名称
where[op.or] = [
{ jobTitle: { [op.like]: `%${value}%` } },
{ companyName: { [op.like]: `%${value}%` } }
];
}
}
const result = await apply_records.findAndCountAll({
where,
limit,
offset,
order: [['applyTime', 'DESC']]
});
return ctx.success(result);
},
/**
* @swagger
* /admin_api/apply/statistics:
* get:
* summary: 获取投递统计
* description: 获取投递记录的统计数据
* tags: [后台-投递管理]
* responses:
* 200:
* description: 获取成功
*/
'GET /apply/statistics': async (ctx) => {
const models = Framework.getModels();
const { apply_records } = models;
const [
totalApply,
pendingApply,
successApply,
failedApply,
hasInterviewCount,
hasOfferCount
] = await Promise.all([
apply_records.count(),
apply_records.count({ where: { applyStatus: 'pending' } }),
apply_records.count({ where: { applyStatus: 'success' } }),
apply_records.count({ where: { applyStatus: 'failed' } }),
apply_records.count({ where: { hasInterview: true } }),
apply_records.count({ where: { hasOffer: true } })
]);
// 按平台统计
const platformStats = await apply_records.findAll({
attributes: [
'platform',
[models.sequelize.fn('COUNT', models.sequelize.col('*')), 'count']
],
group: ['platform'],
raw: true
});
// 按状态统计
const statusStats = await apply_records.findAll({
attributes: [
'applyStatus',
[models.sequelize.fn('COUNT', models.sequelize.col('*')), 'count']
],
group: ['applyStatus'],
raw: true
});
return ctx.success({
totalApply,
pendingApply,
successApply,
failedApply,
hasInterviewCount,
hasOfferCount,
successRate: totalApply > 0 ? ((successApply / totalApply) * 100).toFixed(2) : 0,
interviewRate: totalApply > 0 ? ((hasInterviewCount / totalApply) * 100).toFixed(2) : 0,
offerRate: totalApply > 0 ? ((hasOfferCount / totalApply) * 100).toFixed(2) : 0,
platformStats,
statusStats
});
},
/**
* @swagger
* /admin_api/apply/detail:
* get:
* summary: 获取投递记录详情
* description: 根据投递ID获取详细信息
* tags: [后台-投递管理]
* parameters:
* - in: query
* name: applyId
* required: true
* schema:
* type: string
* description: 投递记录ID
* responses:
* 200:
* description: 获取成功
*/
'GET /apply/detail': async (ctx) => {
const models = Framework.getModels();
const { apply_records } = models;
const { applyId } = ctx.query;
if (!applyId) {
return ctx.fail('投递记录ID不能为空');
}
const record = await apply_records.findOne({ where: { applyId } });
if (!record) {
return ctx.fail('投递记录不存在');
}
return ctx.success(record);
},
/**
* @swagger
* /admin_api/apply/delete:
* post:
* summary: 删除投递记录
* description: 删除指定的投递记录
* tags: [后台-投递管理]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - applyId
* properties:
* applyId:
* type: string
* description: 投递记录ID
* responses:
* 200:
* description: 删除成功
*/
'POST /apply/delete': async (ctx) => {
const models = Framework.getModels();
const { apply_records } = models;
const body = ctx.getBody();
const { applyId } = body;
if (!applyId) {
return ctx.fail('投递记录ID不能为空');
}
const result = await apply_records.destroy({ where: { applyId } });
if (result === 0) {
return ctx.fail('投递记录不存在');
}
return ctx.success({ message: '投递记录删除成功' });
}
};