269 lines
7.3 KiB
JavaScript
269 lines
7.3 KiB
JavaScript
/**
|
||
* 投递记录管理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: '投递记录删除成功' });
|
||
|
||
}
|
||
};
|
||
|