Files
autoAiWorkSys/api/controller_front/user.js
张成 4443d43ec1 1
2025-12-15 22:03:01 +08:00

161 lines
5.2 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/user/login:
* post:
* summary: 用户登录
* description: 通过手机号和密码登录返回token、device_id和用户信息
* tags: [前端-用户管理]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - phone
* - password
* properties:
* phone:
* type: string
* description: 手机号(登录名)
* example: '13800138000'
* password:
* type: string
* description: 密码
* example: 'password123'
* responses:
* 200:
* description: 登录成功
* content:
* application/json:
* schema:
* type: object
* properties:
* code:
* type: integer
* description: 状态码0表示成功
* example: 0
* message:
* type: string
* description: 响应消息
* example: 'success'
* data:
* type: object
* properties:
* token:
* type: string
* description: 认证token
* example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
* device_id:
* type: string
* description: 设备ID
* example: 'device_123456'
* user:
* type: object
* description: 用户信息
* 400:
* description: 参数错误或用户不存在
* content:
* application/json:
* schema:
* type: object
* properties:
* code:
* type: integer
* example: 400
* message:
* type: string
* example: '用户不存在或密码错误'
*/
"POST /user/login": async (ctx) => {
const { phone, password } = ctx.getBody();
const dayjs = require('dayjs');
const crypto = require('crypto');
// 验证参数
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如果不存在基于手机号和机器特征生成
let device_id = user.device_id;
if (!device_id) {
// 生成唯一设备ID
const machineInfo = `${phone}_${Date.now()}_${Math.random()}`;
device_id = crypto.createHash('sha256').update(machineInfo).digest('hex').substring(0, 32);
// 保存设备ID到账号表
await pla_account.update(
{ device_id: device_id },
{ where: { id: user.id } }
);
}
// 创建token
const token = Framework.getServices().tokenService.create({
sn_code: user.sn_code,
device_id: device_id,
user_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
});
}
}