From f98238574cb4048a3e07da32c10e72292602ff85 Mon Sep 17 00:00:00 2001 From: ma-zhongxu Date: Tue, 4 Mar 2025 10:01:08 +0800 Subject: [PATCH] =?UTF-8?q?user=E6=96=B0=E5=A2=9E=E6=97=B6=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E6=9C=BA=E6=9E=84=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/endpoints/admin.js | 31 ++++++++----- server/models/deptUsers.js | 91 ++++++++++++++++++++++++++++++++------ server/models/eventLogs.js | 20 +++++++++ server/models/user.js | 48 ++++++++++++++++++++ 4 files changed, 166 insertions(+), 24 deletions(-) diff --git a/server/endpoints/admin.js b/server/endpoints/admin.js index 3d5a31e..46e2d27 100644 --- a/server/endpoints/admin.js +++ b/server/endpoints/admin.js @@ -96,24 +96,35 @@ function adminEndpoints(app) { return response.status(400).json({ error: roleValidation.error }); } - await prisma.$transaction(async () => { + await prisma.$transaction(async (prisma) => { try { - const { user: newUser, error } = await User.create(newUserParams); + // 创建新用户(使用事务中的 prisma 实例) + const { user: newUser, error } = await User.createNew(newUserParams, prisma); console.log("newUser", newUser); - - const deptUser = await DeptUsers.create({ + console.log("error", error); + if (error) { + throw new Error(`用户创建失败: ${error}`); + } + console.log("newUser===================", newUser); + + // 创建部门用户关联(使用事务中的 prisma 实例) + const deptUser = await DeptUsers.createNew({ data: { userId: newUser.id, deptId: deptId }, - }); - - await EventLogs.logEvent( + }, prisma); + console.log("deptUser:================", deptUser); + // 记录事件日志(使用事务中的 prisma 实例) + await EventLogs.logEventNew( "user_created", { userName: newUser.username, createdBy: currUser.username }, - currUser.id + currUser.id, + prisma ); - response.status(200).json({ user: newUser, error }); + // 返回成功响应 + response.status(200).json({ user: newUser, error: null }); } catch (error) { - throw new Error(`Transaction failed: ${error.message}`); + console.error("事务内部错误:", error.message); + throw error; // 重新抛出错误,确保事务回滚 } }); } catch (e) { diff --git a/server/models/deptUsers.js b/server/models/deptUsers.js index 908d77f..f0c7c11 100644 --- a/server/models/deptUsers.js +++ b/server/models/deptUsers.js @@ -1,4 +1,6 @@ const prisma = require("../utils/prisma"); +const { User } = require("../models/user"); +const { Dept } = require("../models/dept"); /** * @typedef {Object} DeptUser @@ -43,31 +45,92 @@ const DeptUsers = { * @returns {Promise<{ deptUser: DeptUser | null, error: string | null }>} */ create: async function (data) { - console.log("55555555555555555", data); try { - const validatedData = {}; - for (const key of this.writable) { - if (data[key] !== undefined) { - if (this.validations[key]) { - validatedData[key] = this.validations[key](data[key]); - } else { - validatedData[key] = this.castColumnValue(key, data[key]); - } - } + const { userId, deptId } = data.data; + console.log("创建组织机构用户关联:", userId); + console.log("创建组织机构用户关联:", deptId); + + // 检查 userId 和 deptId 是否存在 + const userExists = await User.get({ + id: userId + }); + if (!userExists) { + throw new Error(`用户 ID ${userId} 不存在`); + } + + const deptExists = await Dept.get({ + deptId: parseInt(deptId) + }); + if (!deptExists) { + throw new Error(`部门 ID ${deptId} 不存在`); } + // 创建 dept_users 记录 + const deptUser = await prisma.dept_users.create({ + data: { + // userId: userId, + // deptId: parseInt(deptId), + createdAt: new Date(), + updatedAt: new Date(), + user: { + connect: { + id: userId, + }, + }, + dept: { + connect: { + deptId: parseInt(deptId), + }, + }, + }, + }); + + return deptUser; + } catch (error) { + console.error("创建 dept_users 记录时出错:", error.message); + throw error; + } + }, + createNew: async function (data,prisma) { + try { + const { userId, deptId } = data.data; + // 检查 userId 和 deptId 是否存在 + const userExists = await User.getNew({ + id: userId, + },prisma); + if (!userExists) { + throw new Error(`用户 ID ${userId} 不存在`); + } + const deptExists = await Dept.get({ + deptId: parseInt(deptId), + }); + if (!deptExists) { + throw new Error(`部门 ID ${deptId} 不存在`); + } + // 创建 dept_users 记录 const deptUser = await prisma.dept_users.create({ data: { - ...validatedData, + // userId: userId, + // deptId: parseInt(deptId), createdAt: new Date(), updatedAt: new Date(), + user: { + connect: { + id: userId, + }, + }, + dept: { + connect: { + deptId: parseInt(deptId), + }, + }, }, }); - return { deptUser, error: null }; + return deptUser; } catch (error) { - console.error("FAILED TO CREATE DEPT USER.", error.message); - return { deptUser: null, error: error.message }; + console.error("创建 dept_users 记录时出错:", error.message); + throw error; } }, diff --git a/server/models/eventLogs.js b/server/models/eventLogs.js index 5124043..e8aa01f 100644 --- a/server/models/eventLogs.js +++ b/server/models/eventLogs.js @@ -21,6 +21,26 @@ const EventLogs = { return { eventLog: null, message: error.message }; } }, + logEventNew: async function (event, metadata = {}, userId = null,prisma) { + try { + const eventLog = await prisma.event_logs.create({ + data: { + event, + metadata: metadata ? JSON.stringify(metadata) : null, + userId: userId ? Number(userId) : null, + occurredAt: new Date(), + }, + }); + console.log(`\x1b[32m[Event Logged]\x1b[0m - ${event}`); + return { eventLog, message: null }; + } catch (error) { + console.error( + `\x1b[31m[Event Logging Failed]\x1b[0m - ${event}`, + error.message + ); + return { eventLog: null, message: error.message }; + } + }, getByEvent: async function (event, limit = null, orderBy = null) { try { diff --git a/server/models/user.js b/server/models/user.js index f122e85..f899014 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,5 +1,6 @@ const prisma = require("../utils/prisma"); const { EventLogs } = require("./eventLogs"); +const bcrypt = require("bcrypt"); /** * @typedef {Object} User @@ -109,6 +110,44 @@ const User = { return { user: null, error: error.message }; } }, + createNew: async function ({ + username, + password, + role = "default", + dailyMessageLimit = null, + },prisma) { + const passwordCheck = this.checkPasswordComplexity(password); + console.log("6666666666",passwordCheck) + if (!passwordCheck.checkedOK) { + return { user: null, error: passwordCheck.error }; + } + + try { + // Do not allow new users to bypass validation + if (!this.usernameRegex.test(username)) + throw new Error( + "Username must only contain lowercase letters, numbers, underscores, and hyphens with no spaces" + ); + + const bcrypt = require("bcrypt"); + const hashedPassword = bcrypt.hashSync(password, 10); + const user = await prisma.users.create({ + data: { + username: this.validations.username(username), + password: hashedPassword, + role: this.validations.role(role), + dailyMessageLimit: + this.validations.dailyMessageLimit(dailyMessageLimit), + }, + }); + // const vue = this.filterFields(user); + console.log("6666666666",user); + return { user: this.filterFields(user), error: null }; + } catch (error) { + console.error("FAILED TO CREATE USER.", error.message); + return { user: null, error: error.message }; + } + }, // Log the changes to a user object, but omit sensitive fields // that are not meant to be logged. loggedChanges: function (updates, prev = {}) { @@ -218,6 +257,15 @@ const User = { return null; } }, + getNew: async function (clause = {},prisma) { + try { + const user = await prisma.users.findFirst({ where: clause }); + return user ? this.filterFields({ ...user }) : null; + } catch (error) { + console.error(error.message); + return null; + } + }, // Returns user object with all fields _get: async function (clause = {}) { try {