Files
autoAiWorkSys/api/controller_front/apply.js
张成 815b5d18b1 1
2025-12-16 07:58:43 +08:00

289 lines
8.1 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) => {
try {
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
});
} catch (error) {
console.error('获取投递记录列表失败:', error);
return ctx.fail('获取投递记录列表失败: ' + error.message);
}
},
/**
* @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) => {
try {
const models = Framework.getModels();
const { apply_records } = models;
const { sn_code } = ctx.query;
const final_sn_code = sn_code;
if (!final_sn_code) {
return ctx.fail('请提供设备SN码');
}
const [
totalCount,
successCount,
failedCount,
pendingCount,
interviewCount
] = 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' } })
]);
return ctx.success({
totalCount,
successCount,
failedCount,
pendingCount,
interviewCount,
successRate: totalCount > 0 ? ((successCount / totalCount) * 100).toFixed(2) : 0,
interviewRate: totalCount > 0 ? ((interviewCount / totalCount) * 100).toFixed(2) : 0
});
} catch (error) {
console.error('获取投递统计失败:', error);
return ctx.fail('获取投递统计失败: ' + error.message);
}
},
/**
* @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) => {
try {
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);
} catch (error) {
console.error('获取投递记录详情失败:', error);
return ctx.fail('获取投递记录详情失败: ' + error.message);
}
},
/**
* @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) => {
try {
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);
} catch (error) {
console.error('获取投递趋势数据失败:', error);
return ctx.fail('获取投递趋势数据失败: ' + error.message);
}
}
};