Files
autoAiWorkSys/api/controller_front/apply.js
张成 54644dbb72 1
2025-12-26 14:22:33 +08:00

372 lines
11 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.
/**
* 投递记录管理控制器(客户端接口)
* 提供客户端调用的投递记录相关接口
*/
const Framework = require("../../framework/node-core-framework.js");
module.exports = {
/**
* @swagger
* /api/apply/list:
* post:
* summary: 获取投递记录列表
* description: 根据设备SN码分页获取投递记录
* tags: [前端-投递管理]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* sn_code:
* type: string
* description: 设备SN码
* seachOption:
* type: object
* description: 搜索条件
* pageOption:
* type: object
* description: 分页选项
* responses:
* 200:
* description: 获取成功
*/
'POST /apply/list': async (ctx) => {
const models = Framework.getModels();
const { apply_records, op } = models;
const body = ctx.getBody();
// 从query或body中获取sn_code优先从query获取
const sn_code = ctx.query?.sn_code || body.sn_code;
if (!sn_code) {
return ctx.fail('请提供设备SN码');
}
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 = { sn_code };
// 平台筛选
if (seachOption.platform) {
where.platform = seachOption.platform;
}
// 投递状态筛选
if (seachOption.applyStatus) {
where.applyStatus = seachOption.applyStatus;
}
// 反馈状态筛选
if (seachOption.feedbackStatus) {
where.feedbackStatus = seachOption.feedbackStatus;
}
// 时间范围筛选
console.log(seachOption.startTime, seachOption.endTime);
if (seachOption.startTime || seachOption.endTime) {
where.create_time = {};
if (seachOption.startTime) {
where.create_time[op.gte] = new Date(seachOption.startTime);
}
if (seachOption.endTime) {
const endTime = new Date(seachOption.endTime);
endTime.setHours(23, 59, 59, 999); // 设置为当天的最后一刻
where.create_time[op.lte] = endTime;
}
}
// 搜索:岗位名称、公司名称
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 {
// 默认搜索岗位名称或公司名称
where[op.or] = [
{ jobTitle: { [op.like]: `%${value}%` } },
{ companyName: { [op.like]: `%${value}%` } }
];
}
}
const result = await apply_records.findAndCountAll({
where,
limit,
offset,
order: [['create_time', 'DESC']]
});
return ctx.success({
count: result.count,
total: result.count,
rows: result.rows,
list: result.rows
});
},
/**
* @swagger
* /api/apply/statistics:
* get:
* summary: 获取投递统计
* description: 根据设备SN码获取投递统计数据包含今日、本周、本月统计支持时间范围筛选
* tags: [前端-投递管理]
* parameters:
* - in: query
* name: sn_code
* required: true
* schema:
* type: string
* description: 设备SN码
* - in: query
* name: startTime
* schema:
* type: string
* format: date-time
* description: 开始时间(可选)
* - in: query
* name: endTime
* schema:
* type: string
* format: date-time
* description: 结束时间(可选)
* responses:
* 200:
* description: 获取成功
*/
'POST /apply/statistics': async (ctx) => {
const models = Framework.getModels();
const { apply_records, op } = models;
const { sn_code, startTime, endTime } = ctx.getBody();
console.log(startTime, endTime);
const final_sn_code = sn_code;
if (!final_sn_code) {
return ctx.fail('请提供设备SN码');
}
// 构建基础查询条件
const baseWhere = { sn_code: final_sn_code };
// 如果提供了时间范围,则添加到查询条件中
if (startTime || endTime) {
baseWhere.create_time = {};
if (startTime) {
baseWhere.create_time[op.gte] = new Date(startTime);
}
if (endTime) {
const endTimeDate = new Date(endTime);
endTimeDate.setHours(23, 59, 59, 999); // 设置为当天的最后一刻
baseWhere.create_time[op.lte] = endTimeDate;
}
}
// 计算时间范围(如果未提供时间范围,则使用默认的今日、本周、本月)
const now = new Date();
// 今天的开始时间00:00:00
const todayStart = new Date(now);
todayStart.setHours(0, 0, 0, 0);
// 本周的开始时间周一00:00:00
const weekStart = new Date(now);
const dayOfWeek = weekStart.getDay();
const diff = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // 周日算作上周
weekStart.setDate(weekStart.getDate() - diff);
weekStart.setHours(0, 0, 0, 0);
// 本月的开始时间1号00:00:00
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
monthStart.setHours(0, 0, 0, 0);
const [
totalCount,
successCount,
failedCount,
pendingCount,
interviewCount,
todayCount,
weekCount,
monthCount,
totalJobCount
] = await Promise.all([
// 总计(如果提供了时间范围,则只统计该范围内的)
apply_records.count({ where: baseWhere }),
apply_records.count({ where: { ...baseWhere, applyStatus: 'success' } }),
apply_records.count({ where: { ...baseWhere, applyStatus: 'failed' } }),
apply_records.count({ where: { ...baseWhere, applyStatus: 'pending' } }),
apply_records.count({ where: { ...baseWhere, feedbackStatus: 'interview' } }),
// 今日如果提供了时间范围则返回0否则统计今日
startTime || endTime ? 0 : apply_records.count({
where: {
sn_code: final_sn_code,
create_time: { [op.gte]: todayStart }
}
}),
// 本周如果提供了时间范围则返回0否则统计本周
startTime || endTime ? 0 : apply_records.count({
where: {
sn_code: final_sn_code,
create_time: { [op.gte]: weekStart }
}
}),
// 本月如果提供了时间范围则返回0否则统计本月
startTime || endTime ? 0 : apply_records.count({
where: {
sn_code: final_sn_code,
create_time: { [op.gte]: monthStart }
}
}),
// 总职位数
job_postings.count({
where: {
sn_code: final_sn_code,
create_time: { [op.gte]: todayStart }
}
}),
]);
return ctx.success({
totalCount,
successCount,
failedCount,
pendingCount,
interviewCount,
todayCount,
weekCount,
monthCount,
totalJobCount,
successRate: totalCount > 0 ? ((successCount / totalCount) * 100).toFixed(2) : 0,
interviewRate: totalCount > 0 ? ((interviewCount / totalCount) * 100).toFixed(2) : 0
});
},
/**
* @swagger
* /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;
// 支持 applyId 和 id 两种参数名(向后兼容)
const recordId = ctx.query.applyId || ctx.query.id;
if (!recordId) {
return ctx.fail('投递记录ID不能为空');
}
// 使用 id 字段查询(数据库主键)
const record = await apply_records.findOne({ where: { id: recordId } });
if (!record) {
return ctx.fail('投递记录不存在');
}
return ctx.success(record);
},
/**
* @swagger
* /api/apply/trend:
* get:
* summary: 获取近7天投递趋势数据
* description: 根据设备SN码获取近7天的投递数量趋势
* tags: [前端-投递管理]
* parameters:
* - in: query
* name: sn_code
* required: true
* schema:
* type: string
* description: 设备SN码
* responses:
* 200:
* description: 获取成功
*/
'GET /apply/trend': async (ctx) => {
const models = Framework.getModels();
const { apply_records, op } = models;
const { sn_code } = ctx.query;
if (!sn_code) {
return ctx.fail('请提供设备SN码');
}
// 计算近7天的日期范围
const today = new Date();
today.setHours(23, 59, 59, 999);
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 6);
sevenDaysAgo.setHours(0, 0, 0, 0);
// 查询近7天的投递记录
const records = await apply_records.findAll({
where: {
sn_code: sn_code,
create_time: {
[op.gte]: sevenDaysAgo,
[op.lte]: today
}
},
attributes: ['create_time'],
raw: true
});
// 生成7天的日期数组
const trendData = [];
for (let i = 6; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
date.setHours(0, 0, 0, 0);
const dateStr = `${date.getMonth() + 1}/${date.getDate()}`;
// 统计当天的投递数量
const count = records.filter(record => {
const recordDate = new Date(record.create_time);
recordDate.setHours(0, 0, 0, 0);
return recordDate.getTime() === date.getTime();
}).length;
trendData.push({
date: dateStr,
value: count
});
}
return ctx.success(trendData);
}
};