Files
张成 bad9978f53 1
2025-12-18 17:02:54 +08:00

317 lines
8.5 KiB
JavaScript
Raw Permalink 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;
}
// 搜索:岗位名称、公司名称
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: [['applyTime', '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码
* responses:
* 200:
* description: 获取成功
*/
'GET /apply/statistics': async (ctx) => {
const models = Framework.getModels();
const { apply_records, op } = models;
const { sn_code } = ctx.query;
const final_sn_code = sn_code;
if (!final_sn_code) {
return ctx.fail('请提供设备SN码');
}
// 计算时间范围
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
] = await Promise.all([
// 总计
apply_records.count({ where: { sn_code: final_sn_code } }),
apply_records.count({ where: { sn_code: final_sn_code, applyStatus: 'success' } }),
apply_records.count({ where: { sn_code: final_sn_code, applyStatus: 'failed' } }),
apply_records.count({ where: { sn_code: final_sn_code, applyStatus: 'pending' } }),
apply_records.count({ where: { sn_code: final_sn_code, feedbackStatus: 'interview' } }),
// 今日
apply_records.count({
where: {
sn_code: final_sn_code,
applyTime: { [op.gte]: todayStart }
}
}),
// 本周
apply_records.count({
where: {
sn_code: final_sn_code,
applyTime: { [op.gte]: weekStart }
}
}),
// 本月
apply_records.count({
where: {
sn_code: final_sn_code,
applyTime: { [op.gte]: monthStart }
}
})
]);
return ctx.success({
totalCount,
successCount,
failedCount,
pendingCount,
interviewCount,
todayCount,
weekCount,
monthCount,
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,
applyTime: {
[op.gte]: sevenDaysAgo,
[op.lte]: today
}
},
attributes: ['applyTime'],
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.applyTime);
recordDate.setHours(0, 0, 0, 0);
return recordDate.getTime() === date.getTime();
}).length;
trendData.push({
date: dateStr,
value: count
});
}
return ctx.success(trendData);
}
};