Browse Source

user新增时绑定机构的事务问题

master
ma-zhongxu 10 months ago
parent
commit
f98238574c
  1. 29
      server/endpoints/admin.js
  2. 89
      server/models/deptUsers.js
  3. 20
      server/models/eventLogs.js
  4. 48
      server/models/user.js

29
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);
console.log("error", error);
if (error) {
throw new Error(`用户创建失败: ${error}`);
}
console.log("newUser===================", newUser);
const deptUser = await DeptUsers.create({
// 创建部门用户关联(使用事务中的 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) {

89
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;
}
},

20
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 {

48
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 {

Loading…
Cancel
Save