diff --git a/api/controller_front/user.js b/api/controller_front/user.js index 15a3160..b55e12e 100644 --- a/api/controller_front/user.js +++ b/api/controller_front/user.js @@ -74,166 +74,103 @@ module.exports = { * type: string * example: '用户不存在或密码错误' */ - "POST /user/login": async (ctx) => { - const { phone, password, device_id: client_device_id } = ctx.getBody(); - const dayjs = require('dayjs'); + "POST /user/login": async (ctx) => { + const { phone, password, device_id: client_device_id } = ctx.getBody(); + const dayjs = require('dayjs'); - // 验证参数 - if (!phone || !password) { - 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); + // 验证参数 + if (!phone || !password) { + 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: + * /api/user/delivery-config/get: * post: - * summary: 保存投递配置 - * description: 根据设备SN码保存用户的投递配置 + * summary: 获取投递配置 + * description: 根据设备SN码获取用户的投递配置,返回 account_config 表中的 auto_deliver_config 对象 * tags: [前端-用户管理] * requestBody: * required: true @@ -247,62 +184,180 @@ module.exports = { * sn_code: * type: string * description: 设备SN码 - * config: - * type: object - * description: 投递配置 * responses: * 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 { - console.log('[User Controller] 收到保存投递配置请求'); + console.log('[User Controller] 收到获取投递配置请求'); const body = ctx.getBody(); - const { sn_code, config } = body; - console.log('[User Controller] sn_code:', sn_code, 'config:', JSON.stringify(config)); + const { sn_code } = body; + console.log('[User Controller] sn_code:', sn_code); if (!sn_code) { return ctx.fail('请提供设备SN码'); } - if (!config) { - return ctx.fail('请提供配置信息'); - } + const { pla_account, account_config } = await Framework.getModels(); - const { pla_account } = await Framework.getModels(); - const user = await pla_account.findOne({ - where: { sn_code } + // 根据 sn_code 查找账号 + const user = await pla_account.findOne({ + where: { sn_code } }); if (!user) { return ctx.fail('用户不存在'); } - // 转换前端配置格式为数据库格式 - const deliverConfig = { - deliver_interval: config.interval || 30, - 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 - } - }; + // 从 account_config 表获取配置 + const accountConfig = await account_config.findOne({ + where: { account_id: user.id } + }); - // 更新数据库 + // 直接返回 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( - { - auto_deliver: config.autoDelivery ? 1 : 0, - deliver_config: deliverConfig - }, - { where: { sn_code } } + { auto_deliver: auto_deliver_config.autoDelivery ? 1 : 0 }, + { where: { id: user.id } } ); + return ctx.success({ message: '配置保存成功' }); } catch (error) { console.error('保存投递配置失败:', error); diff --git a/api/model/account_config.js b/api/model/account_config.js index 0b30fec..ce897d0 100644 --- a/api/model/account_config.js +++ b/api/model/account_config.js @@ -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; };