This commit is contained in:
张成
2025-12-16 12:56:32 +08:00
parent 4d712f8332
commit 968fedac03
2 changed files with 246 additions and 189 deletions

View File

@@ -74,166 +74,103 @@ module.exports = {
* type: string * type: string
* example: '用户不存在或密码错误' * example: '用户不存在或密码错误'
*/ */
"POST /user/login": async (ctx) => { "POST /user/login": async (ctx) => {
const { phone, password, device_id: client_device_id } = ctx.getBody(); const { phone, password, device_id: client_device_id } = ctx.getBody();
const dayjs = require('dayjs'); const dayjs = require('dayjs');
// 验证参数 // 验证参数
if (!phone || !password) { if (!phone || !password) {
return ctx.fail('手机号和密码不能为空'); return ctx.fail('手机号和密码不能为空');
}
const { pla_account } = await Framework.getModels();
// 根据手机号login_name和密码查找用户
const user = await pla_account.findOne({
where: {
login_name: phone,
pwd: password
}
});
if (!user) {
return ctx.fail('手机号或密码错误');
}
// 检查账号是否启用
if (!user.is_enabled) {
return ctx.fail('账号已被禁用');
}
// 检查授权状态
const userData = user.toJSON();
const authDate = userData.authorization_date;
const authDays = userData.authorization_days || 0;
if (authDate && authDays > 0) {
const startDate = dayjs(authDate);
const endDate = startDate.add(authDays, 'day');
const now = dayjs();
const remaining = endDate.diff(now, 'day', true);
const remaining_days = Math.max(0, Math.ceil(remaining));
if (remaining_days <= 0) {
return ctx.fail('账号授权已过期,请联系管理员续费');
}
}
// 处理设备ID优先使用客户端传递的 device_id如果没有则使用数据库中的
let device_id = client_device_id || user.device_id;
// 如果客户端提供了 device_id 且与数据库中的不同,则更新数据库
if (client_device_id && client_device_id !== user.device_id) {
await pla_account.update(
{ device_id: client_device_id },
{ where: { id: user.id } }
);
device_id = client_device_id;
}
// 如果既没有客户端传递的,数据库中也为空,则返回错误(不应该发生,因为客户端会生成)
if (!device_id) {
return ctx.fail('设备ID不能为空请重新登录');
}
// 创建token
const token = Framework.getServices().tokenService.create({
sn_code: user.sn_code,
device_id: device_id,
id: user.id
});
// 计算剩余天数
let remaining_days = 0;
if (authDate && authDays > 0) {
const startDate = dayjs(authDate);
const endDate = startDate.add(authDays, 'day');
const now = dayjs();
const remaining = endDate.diff(now, 'day', true);
remaining_days = Math.max(0, Math.ceil(remaining));
}
const userInfo = user.toJSON();
userInfo.remaining_days = remaining_days;
// 不返回密码
delete userInfo.pwd;
return ctx.success({
token,
device_id,
user: userInfo
});
},
/**
* @swagger
* /api/user/delivery-config:
* get:
* summary: 获取投递配置
* description: 根据设备SN码获取用户的投递配置
* tags: [前端-用户管理]
* parameters:
* - in: query
* name: sn_code
* required: true
* schema:
* type: string
* description: 设备SN码
* responses:
* 200:
* description: 获取成功
*/
'GET /user/delivery-config': async (ctx) => {
try {
console.log('[User Controller] 收到获取投递配置请求');
const { sn_code } = ctx.query;
console.log('[User Controller] sn_code:', sn_code);
if (!sn_code) {
return ctx.fail('请提供设备SN码');
}
const { pla_account } = await Framework.getModels();
const user = await pla_account.findOne({
where: { sn_code }
});
if (!user) {
return ctx.fail('用户不存在');
}
// 从数据库获取配置
const autoDelivery = user.auto_deliver === 1;
const deliverConfig = user.deliver_config || {};
// 转换配置格式为前端需要的格式
const config = {
autoDelivery: autoDelivery,
interval: deliverConfig.deliver_interval || 30,
minSalary: deliverConfig.min_salary || 0,
maxSalary: deliverConfig.max_salary || 0,
scrollPages: deliverConfig.page_count || 3,
maxPerBatch: deliverConfig.max_deliver || 10,
filterKeywords: deliverConfig.filter_keywords || [],
excludeKeywords: deliverConfig.exclude_keywords || [],
startTime: deliverConfig.time_range?.start_time || '09:00',
endTime: deliverConfig.time_range?.end_time || '18:00',
workdaysOnly: deliverConfig.time_range?.workdays_only === 1 || deliverConfig.time_range?.workdays_only === true
};
return ctx.success(config);
} catch (error) {
console.error('获取投递配置失败:', error);
return ctx.fail('获取投递配置失败: ' + error.message);
} }
const { pla_account } = await Framework.getModels();
// 根据手机号login_name和密码查找用户
const user = await pla_account.findOne({
where: {
login_name: phone,
pwd: password
}
});
if (!user) {
return ctx.fail('手机号或密码错误');
}
// 检查账号是否启用
if (!user.is_enabled) {
return ctx.fail('账号已被禁用');
}
// 检查授权状态
const userData = user.toJSON();
const authDate = userData.authorization_date;
const authDays = userData.authorization_days || 0;
if (authDate && authDays > 0) {
const startDate = dayjs(authDate);
const endDate = startDate.add(authDays, 'day');
const now = dayjs();
const remaining = endDate.diff(now, 'day', true);
const remaining_days = Math.max(0, Math.ceil(remaining));
if (remaining_days <= 0) {
return ctx.fail('账号授权已过期,请联系管理员续费');
}
}
// 处理设备ID优先使用客户端传递的 device_id如果没有则使用数据库中的
let device_id = client_device_id || user.device_id;
// 如果客户端提供了 device_id 且与数据库中的不同,则更新数据库
if (client_device_id && client_device_id !== user.device_id) {
await pla_account.update(
{ device_id: client_device_id },
{ where: { id: user.id } }
);
device_id = client_device_id;
}
// 如果既没有客户端传递的,数据库中也为空,则返回错误(不应该发生,因为客户端会生成)
if (!device_id) {
return ctx.fail('设备ID不能为空请重新登录');
}
// 创建token
const token = Framework.getServices().tokenService.create({
sn_code: user.sn_code,
device_id: device_id,
id: user.id
});
// 计算剩余天数
let remaining_days = 0;
if (authDate && authDays > 0) {
const startDate = dayjs(authDate);
const endDate = startDate.add(authDays, 'day');
const now = dayjs();
const remaining = endDate.diff(now, 'day', true);
remaining_days = Math.max(0, Math.ceil(remaining));
}
const userInfo = user.toJSON();
userInfo.remaining_days = remaining_days;
// 不返回密码
delete userInfo.pwd;
return ctx.success({
token,
device_id,
user: userInfo
});
}, },
/** /**
* @swagger * @swagger
* /api/user/delivery-config: * /api/user/delivery-config/get:
* post: * post:
* summary: 保存投递配置 * summary: 获取投递配置
* description: 根据设备SN码保存用户的投递配置 * description: 根据设备SN码获取用户的投递配置,返回 account_config 表中的 auto_deliver_config 对象
* tags: [前端-用户管理] * tags: [前端-用户管理]
* requestBody: * requestBody:
* required: true * required: true
@@ -247,29 +184,42 @@ module.exports = {
* sn_code: * sn_code:
* type: string * type: string
* description: 设备SN码 * description: 设备SN码
* config:
* type: object
* description: 投递配置
* responses: * responses:
* 200: * 200:
* description: 保存成功 * description: 获取成功
* content:
* application/json:
* schema:
* type: object
* properties:
* code:
* type: integer
* example: 0
* message:
* type: string
* example: 'success'
* data:
* type: object
* properties:
* auto_deliver_config:
* type: object
* description: 自动投递配置对象,如果不存在则返回 null
* nullable: true
*/ */
'POST /user/delivery-config': async (ctx) => { 'POST /user/delivery-config/get': async (ctx) => {
try { try {
console.log('[User Controller] 收到保存投递配置请求'); console.log('[User Controller] 收到获取投递配置请求');
const body = ctx.getBody(); const body = ctx.getBody();
const { sn_code, config } = body; const { sn_code } = body;
console.log('[User Controller] sn_code:', sn_code, 'config:', JSON.stringify(config)); console.log('[User Controller] sn_code:', sn_code);
if (!sn_code) { if (!sn_code) {
return ctx.fail('请提供设备SN码'); return ctx.fail('请提供设备SN码');
} }
if (!config) { const { pla_account, account_config } = await Framework.getModels();
return ctx.fail('请提供配置信息');
}
const { pla_account } = await Framework.getModels(); // 根据 sn_code 查找账号
const user = await pla_account.findOne({ const user = await pla_account.findOne({
where: { sn_code } where: { sn_code }
}); });
@@ -278,31 +228,136 @@ module.exports = {
return ctx.fail('用户不存在'); return ctx.fail('用户不存在');
} }
// 转换前端配置格式为数据库格式 // 从 account_config 表获取配置
const deliverConfig = { const accountConfig = await account_config.findOne({
deliver_interval: config.interval || 30, where: { account_id: user.id }
min_salary: config.minSalary || 0, });
max_salary: config.maxSalary || 0,
page_count: config.scrollPages || 3,
max_deliver: config.maxPerBatch || 10,
filter_keywords: config.filterKeywords || [],
exclude_keywords: config.excludeKeywords || [],
time_range: {
start_time: config.startTime || '09:00',
end_time: config.endTime || '18:00',
workdays_only: config.workdaysOnly ? 1 : 0
}
};
// 更新数据库 // 直接返回 auto_deliver_config 对象
const auto_deliver_config = accountConfig?.auto_deliver_config || null;
return ctx.success({ auto_deliver_config });
} catch (error) {
console.error('获取投递配置失败:', error);
return ctx.fail('获取投递配置失败: ' + error.message);
}
},
/**
* @swagger
* /api/user/delivery-config/save:
* post:
* summary: 保存投递配置
* description: 根据设备SN码保存用户的投递配置到 account_config 表的 auto_deliver_config 字段
* tags: [前端-用户管理]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - sn_code
* - auto_deliver_config
* properties:
* sn_code:
* type: string
* description: 设备SN码
* auto_deliver_config:
* type: object
* description: 自动投递配置对象
* properties:
* auto_delivery:
* type: boolean
* description: 是否启用自动投递
* interval:
* type: integer
* description: 投递间隔(分钟)
* min_salary:
* type: integer
* description: 最低薪资
* max_salary:
* type: integer
* description: 最高薪资
* scroll_pages:
* type: integer
* description: 滚动页数
* max_per_batch:
* type: integer
* description: 每批最多投递数
* filter_keywords:
* type: string
* description: 过滤关键词
* exclude_keywords:
* type: string
* description: 排除关键词
* start_time:
* type: string
* description: 开始时间格式HH:mm
* end_time:
* type: string
* description: 结束时间格式HH:mm
* workdays_only:
* type: boolean
* description: 仅工作日
* responses:
* 200:
* description: 保存成功
*/
'POST /user/delivery-config/save': async (ctx) => {
try {
console.log('[User Controller] 收到保存投递配置请求');
const body = ctx.getBody();
const { sn_code, auto_deliver_config } = body;
console.log('[User Controller] sn_code:', sn_code, 'auto_deliver_config:', JSON.stringify(auto_deliver_config));
if (!sn_code) {
return ctx.fail('请提供设备SN码');
}
if (!auto_deliver_config) {
return ctx.fail('请提供 auto_deliver_config 配置对象');
}
const { pla_account, account_config } = await Framework.getModels();
// 根据 sn_code 查找账号
const user = await pla_account.findOne({
where: { sn_code }
});
if (!user) {
return ctx.fail('用户不存在');
}
// 查找或创建 account_config 记录
const accountConfig = await account_config.findOne({
where: { account_id: user.id }
});
if (accountConfig) {
// 更新现有配置
await account_config.update(
{ auto_deliver_config: auto_deliver_config },
{ where: { account_id: user.id } }
);
} else {
// 创建新配置
await account_config.create({
account_id: user.id,
platform_type: user.platform_type || 'boss',
auto_deliver_config: auto_deliver_config
});
}
// 更新 pla_account 表的 auto_deliver 字段
await pla_account.update( await pla_account.update(
{ { auto_deliver: auto_deliver_config.autoDelivery ? 1 : 0 },
auto_deliver: config.autoDelivery ? 1 : 0, { where: { id: user.id } }
deliver_config: deliverConfig
},
{ where: { sn_code } }
); );
return ctx.success({ message: '配置保存成功' }); return ctx.success({ message: '配置保存成功' });
} catch (error) { } catch (error) {
console.error('保存投递配置失败:', error); console.error('保存投递配置失败:', error);

View File

@@ -1,4 +1,4 @@
const Sequelize = require('sequelize'); const Sequelize = require('sequelize');
/** /**
* 账号配置表模型 * 账号配置表模型
@@ -153,6 +153,8 @@ module.exports = (db) => {
] ]
}); });
// account_config.sync({ alter: true });
return account_config; return account_config;
}; };