初次提交

This commit is contained in:
2025-09-04 10:49:10 +08:00
commit e704c8abca
26 changed files with 8917 additions and 0 deletions

226
routes/auth.js Normal file
View File

@@ -0,0 +1,226 @@
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 { phone, password } = req.body;
if (!phone || !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'
`, [phone]);
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;