-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
durunsong
committed
Nov 25, 2024
1 parent
f7ed278
commit c334e5a
Showing
12 changed files
with
667 additions
and
569 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
# 这里放置一些配置信息 | ||
PORT = 4000 | ||
PORT = 4000 | ||
# JWT 刷新令牌KEY | ||
JWT_SECRET = 'f7d623cd21149c493d7304960edaf2e10ad147528dbaf183520184fc0a0f64cb' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// 控制器模块 | ||
const { connection } = require("../config/db-connection.js"); | ||
|
||
// 获取删除的用户列表接口 | ||
const getDeletedUsers = (req, res) => { | ||
const { pageNum, pageSize, keywords, startTime, endTime } = req.query; | ||
const offset = (pageNum - 1) * pageSize; | ||
let query = "SELECT * FROM users WHERE is_delete = 1"; | ||
let countQuery = "SELECT COUNT(*) AS total FROM users WHERE is_delete = 1"; | ||
const queryParams = []; | ||
|
||
if (keywords) { | ||
query += " AND (user_name LIKE ? OR description LIKE ?)"; | ||
countQuery += " AND (user_name LIKE ? OR description LIKE ?)"; | ||
const keywordPattern = `%${keywords}%`; | ||
queryParams.push(keywordPattern, keywordPattern); | ||
} | ||
|
||
if (startTime && endTime) { | ||
query += " AND create_time BETWEEN ? AND ?"; | ||
countQuery += " AND create_time BETWEEN ? AND ?"; | ||
queryParams.push(startTime, endTime); | ||
} | ||
|
||
query += " LIMIT ?, ?"; | ||
queryParams.push(parseInt(offset), parseInt(pageSize)); | ||
|
||
connection.query(query, queryParams, (err, results) => { | ||
if (err) { | ||
console.error(err); | ||
res.status(500).json({ status: 500, message: "查询用户失败" }); | ||
return; | ||
} | ||
// 时间格式转化 | ||
const formattedResults = results.map((user) => { | ||
user.update_time = user.update_time | ||
.toISOString() | ||
.slice(0, 19) | ||
.replace("T", " "); | ||
user.create_time = user.create_time | ||
.toISOString() | ||
.slice(0, 19) | ||
.replace("T", " "); | ||
return user; | ||
}); | ||
connection.query( | ||
countQuery, | ||
queryParams.slice(0, queryParams.length - 2), | ||
(countErr, countResults) => { | ||
if (countErr) { | ||
console.error(countErr); | ||
res.status(500).json({ status: 500, message: "查询用户总数失败" }); | ||
return; | ||
} | ||
const total = countResults[0].total; | ||
res.status(200).json({ | ||
status: 200, | ||
message: "查询成功", | ||
page: parseInt(pageNum), | ||
pageSize: parseInt(pageSize), | ||
total, | ||
data: formattedResults, | ||
}); | ||
}, | ||
); | ||
}); | ||
}; | ||
|
||
// 完全删除用户接口 | ||
const permanentDeleteUser = (req, res) => { | ||
const { id } = req.params; | ||
const query = "DELETE FROM users WHERE id = ?"; | ||
connection.query(query, [id], (err, results) => { | ||
if (err) { | ||
console.error(err); | ||
res.status(500).json({ status: 500, message: "删除用户失败" }); | ||
return; | ||
} | ||
if (results.affectedRows === 0) { | ||
res.status(404).json({ status: 404, message: "用户不存在" }); | ||
} else { | ||
res.status(200).json({ status: 200, message: "用户删除成功" }); | ||
} | ||
}); | ||
}; | ||
|
||
// 还原删除用户接口 | ||
const restoreUserApi = (req, res) => { | ||
const { id } = req.params; | ||
const query = "UPDATE users SET is_delete = 0 WHERE id = ?"; | ||
connection.query(query, [id], (err, results) => { | ||
if (err) { | ||
console.error(err); | ||
res.status(500).json({ status: 500, message: "还原用户失败" }); | ||
return; | ||
} | ||
if (results.affectedRows === 0) { | ||
res | ||
.status(404) | ||
.json({ status: 404, message: "用户不存在或已被永久删除" }); | ||
} else { | ||
res.status(200).json({ status: 200, message: "用户还原成功" }); | ||
} | ||
}); | ||
}; | ||
|
||
module.exports = { | ||
getDeletedUsers, | ||
permanentDeleteUser, | ||
restoreUserApi, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// 加密现有用户的密码(如果密码没有加密) | ||
const { hashPassword } = require("../utils/utils.js"); | ||
const { connection } = require("../config/db-connection.js"); | ||
|
||
// 加密现有用户的密码(如果密码没有加密) | ||
const hashExistingPasswords = () => { | ||
connection.query("SELECT * FROM users", async (err, results) => { | ||
if (err) { | ||
console.error("Error fetching users:", err); | ||
return; | ||
} | ||
for (const user of results) { | ||
if (user.password && !user.password.startsWith("$2b$")) { | ||
try { | ||
// 使用 utils.js 中的 hashPassword 方法 | ||
const hashedPassword = await hashPassword(user.password); | ||
const updateUserQuery = "UPDATE users SET password = ? WHERE id = ?"; | ||
|
||
connection.query( | ||
updateUserQuery, | ||
[hashedPassword, user.id], | ||
(err) => { | ||
if (err) { | ||
console.error( | ||
"Error updating password for user:", | ||
user.user_name, | ||
); | ||
} else { | ||
console.log("Password updated for user:", user.user_name); | ||
} | ||
}, | ||
); | ||
} catch (error) { | ||
console.error( | ||
`Error hashing password for user ${user.user_name}:`, | ||
error.message, | ||
); | ||
} | ||
} | ||
} | ||
}); | ||
}; | ||
|
||
module.exports = { | ||
hashExistingPasswords, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
const { | ||
comparePassword, | ||
formatTime, | ||
generateToken, | ||
} = require("../utils/utils.js"); | ||
const { connection } = require("../config/db-connection.js"); | ||
|
||
const loginUser = (req, res) => { | ||
const { user_name, password } = req.body; | ||
|
||
if (!user_name || !password) { | ||
return res | ||
.status(400) | ||
.json({ status: 400, message: "账号和密码都是必需的" }); | ||
} | ||
|
||
const findUserQuery = | ||
"SELECT * FROM users WHERE user_name = ? AND is_delete = 0"; | ||
|
||
connection.query(findUserQuery, [user_name], async (err, results) => { | ||
if (err) { | ||
console.error(err); | ||
return res.status(500).json({ status: 500, message: "查询用户失败" }); | ||
} | ||
|
||
if (results.length === 0) { | ||
return res.status(404).json({ status: 404, message: "用户不存在" }); | ||
} | ||
|
||
const user = results[0]; | ||
const hashFromDb = user.password; | ||
|
||
// 验证密码 | ||
const passWordMatch = await comparePassword(password, hashFromDb); | ||
if (!passWordMatch) { | ||
return res.status(409).json({ status: 409, message: "用户名或密码错误" }); | ||
} | ||
|
||
// 生成 JWT | ||
const token = generateToken({ id: user.id, user_name: user.user_name }); | ||
|
||
// 登录时间 | ||
const login_time = formatTime(); | ||
res.status(200).json({ | ||
message: "登录成功", | ||
status: 200, | ||
token, | ||
login_time, | ||
}); | ||
}); | ||
}; | ||
|
||
module.exports = { | ||
loginUser, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const { generateToken, verifyToken } = require("../utils/utils.js"); | ||
|
||
// 刷新 JWT 接口 | ||
const refreshToken = (req, res) => { | ||
const { refreshToken } = req.body; | ||
if (!refreshToken) { | ||
return res.status(400).json({ message: "刷新令牌是必需的" }); | ||
} | ||
try { | ||
// 验证刷新令牌 | ||
const decoded = verifyToken(refreshToken); | ||
// 根据解码后的信息生成新的 JWT | ||
const newToken = generateToken({ | ||
userId: decoded.userId, | ||
user_name: decoded.user_name, | ||
}); | ||
res.status(200).json({ token: newToken }); | ||
} catch (err) { | ||
console.error("Error verifying refresh token:", err.message); | ||
res.status(403).json({ message: "无效的刷新令牌" }); | ||
} | ||
}; | ||
|
||
module.exports = { | ||
refreshToken, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
const { hashPassword, formatTime, generateUUID } = require("../utils/utils.js"); | ||
const { connection } = require("../config/db-connection.js"); | ||
|
||
const registerUser = (req, res) => { | ||
const { user_name, password, confirmPassword, description, roles } = req.body; | ||
|
||
// 检查必填字段 | ||
if (!user_name || !password || !confirmPassword) { | ||
return res | ||
.status(400) | ||
.json({ status: 400, message: "用户名、密码和确认密码为必填项" }); | ||
} | ||
|
||
// 检查密码是否一致 | ||
if (password !== confirmPassword) { | ||
return res | ||
.status(400) | ||
.json({ status: 400, message: "密码和确认密码不一致" }); | ||
} | ||
// 生成 UUID | ||
const uuid = generateUUID(); | ||
// 检查用户是否已存在 | ||
const checkUserQuery = "SELECT * FROM users WHERE user_name = ?"; | ||
connection.query(checkUserQuery, [user_name], async (err, results) => { | ||
if (err) { | ||
return res | ||
.status(500) | ||
.json({ status: 500, message: "数据库查询失败", error: err }); | ||
} | ||
|
||
if (results.length > 0) { | ||
return res | ||
.status(409) | ||
.json({ status: 409, message: "该用户名已被注册,请选择其他用户名" }); | ||
} | ||
|
||
// 默认值 | ||
const create_time = formatTime(); | ||
const update_time = formatTime(); | ||
const account = user_name; | ||
const is_delete = 0; | ||
const nick_name = "新用户"; // 默认昵称 | ||
const role_ids = [201]; // 普通用户角色ID | ||
const avatar = | ||
"https://img1.baidu.com/it/u=1248484120,3563242407&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=800"; | ||
|
||
// 密码加密 | ||
try { | ||
const hashedPassword = await hashPassword(password); | ||
|
||
// 插入用户数据 | ||
const insertUserQuery = ` | ||
INSERT INTO users | ||
(uuid, account, create_time, is_delete, password, update_time, description, user_name, nick_name, role_ids, avatar, roles) | ||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`; | ||
|
||
const values = [ | ||
uuid, | ||
account, | ||
create_time, | ||
is_delete, | ||
hashedPassword, | ||
update_time, | ||
description || "", | ||
user_name, | ||
nick_name, | ||
JSON.stringify(role_ids), | ||
avatar, | ||
JSON.stringify(roles || []), | ||
]; | ||
|
||
connection.query(insertUserQuery, values, (err, results) => { | ||
if (err) { | ||
console.error(err); | ||
return res | ||
.status(500) | ||
.json({ status: 500, message: "注册失败", error: err }); | ||
} | ||
res | ||
.status(200) | ||
.json({ status: 200, message: "注册成功", data: results }); | ||
}); | ||
} catch (error) { | ||
console.error(error); | ||
res | ||
.status(500) | ||
.json({ status: 500, message: "注册过程中发生错误", error }); | ||
} | ||
}); | ||
}; | ||
|
||
module.exports = { | ||
registerUser, | ||
}; |
Oops, something went wrong.