Files
jurong_circle_agent_black/routes/auth.js
2025-09-05 16:49:23 +08:00

226 lines
5.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 express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { getDB } = require('../database');
const { logger } = require('../config/logger');
// JWT密钥
const JWT_SECRET = process.env.JWT_SECRET || 'agent_jwt_secret_key_2024';
/**
* 代理登录
* POST /api/auth/login
*/
router.post('/login', async (req, res) => {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({
success: false,
message: '请输入手机号和密码'
});
}
// 查询代理信息
const [agents] = await getDB().execute(`
SELECT
ra.id as agent_id,
ra.user_id,
ra.agent_code,
ra.status as agent_status,
ra.region_id,
u.id as user_id,
u.username,
u.phone,
u.password,
u.real_name,
u.avatar,
zr.city_name,
zr.district_name
FROM regional_agents ra
LEFT JOIN users u ON ra.user_id = u.id
LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id
WHERE u.phone = ? AND ra.status = 'active'
`, [username]);
if (agents.length === 0) {
return res.status(401).json({
success: false,
message: '手机号不存在或代理账号未激活'
});
}
const agent = agents[0];
// 验证密码
const isPasswordValid = await bcrypt.compare(password, agent.password);
if (!isPasswordValid) {
return res.status(401).json({
success: false,
message: '密码错误'
});
}
// 生成JWT token
const token = jwt.sign(
{
userId: agent.user_id,
agentId: agent.agent_id,
phone: agent.phone,
role: 'agent'
},
JWT_SECRET,
{ expiresIn: '24h' }
);
// 记录登录日志
logger.info('代理登录成功', {
agentId: agent.agent_id,
phone: agent.phone,
ip: req.ip
});
// 返回登录成功信息
res.json({
success: true,
message: '登录成功',
data: {
token,
agent: {
id: agent.agent_id,
userId: agent.user_id,
agentCode: agent.agent_code,
phone: agent.phone,
realName: agent.real_name,
avatar: agent.avatar,
region: {
id: agent.region_id,
cityName: agent.city_name,
districtName: agent.district_name
}
}
}
});
} catch (error) {
logger.error('代理登录失败', {
error: error.message,
stack: error.stack,
ip: req.ip
});
res.status(500).json({
success: false,
message: '登录失败,请稍后重试'
});
}
});
/**
* 获取当前代理信息
* GET /api/auth/me
*/
router.get('/me', async (req, res) => {
try {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
message: '未提供认证令牌'
});
}
// 验证token
const decoded = jwt.verify(token, JWT_SECRET);
// 查询代理信息
const [agents] = await getDB().execute(`
SELECT
ra.id as agent_id,
ra.user_id,
ra.agent_code,
ra.status as agent_status,
ra.region_id,
u.phone,
u.real_name,
u.avatar,
zr.city_name,
zr.district_name
FROM regional_agents ra
LEFT JOIN users u ON ra.user_id = u.id
LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id
WHERE ra.id = ? AND ra.status = 'active'
`, [decoded.agentId]);
if (agents.length === 0) {
return res.status(401).json({
success: false,
message: '代理账号不存在或已被禁用'
});
}
const agent = agents[0];
res.json({
success: true,
data: {
agent: {
id: agent.agent_id,
userId: agent.user_id,
agentCode: agent.agent_code,
phone: agent.phone,
realName: agent.real_name,
avatar: agent.avatar,
region: {
id: agent.region_id,
cityName: agent.city_name,
districtName: agent.district_name
}
}
}
});
} catch (error) {
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
success: false,
message: '无效的认证令牌'
});
}
if (error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: '认证令牌已过期'
});
}
logger.error('获取代理信息失败', {
error: error.message,
stack: error.stack
});
res.status(500).json({
success: false,
message: '获取用户信息失败'
});
}
});
/**
* 代理登出
* POST /api/auth/logout
*/
router.post('/logout', (req, res) => {
// 由于使用JWT登出主要在前端处理删除token
// 这里只是提供一个标准的登出接口
res.json({
success: true,
message: '登出成功'
});
});
module.exports = router;