feat: 1. 完善起草合同页面的逻辑交互,对接minio的接口操作
This commit is contained in:
@@ -530,247 +530,4 @@ async function callIDaaSLogout(accessToken: string, appId: string): Promise<void
|
||||
console.error("❌ [callIDaaSLogout] 调用IDaaS登出接口失败(非HTTP错误):", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户信息到数据库
|
||||
*
|
||||
* 此函数实现以下逻辑:
|
||||
* 1. 内部生成临时 JWT(user_id 为 'login',仅用于数据库操作)
|
||||
* 2. 根据 userInfo.sub 查询 sso_users 表中是否已存在该用户
|
||||
* 3. 如果存在,则更新用户信息(如果用户已有 area 值则不更新)
|
||||
* 4. 如果不存在,则插入新的用户记录
|
||||
* 5. 返回保存的用户数据和临时 JWT
|
||||
*
|
||||
* @param userInfo - 从 IDaaS 获取的用户信息
|
||||
* @param userRole - 用户角色
|
||||
* @param tokenExpiresIn - Token过期时间(秒)
|
||||
* @param area - 用户所属地区,根据端口号确定
|
||||
* @returns Promise<{success: boolean, data?: SsoUser, tempToken?: string, error?: string}>
|
||||
*/
|
||||
export async function saveUserInfo(
|
||||
userInfo: UserInfo,
|
||||
userRole: UserRole,
|
||||
tokenExpiresIn: number,
|
||||
area?: string
|
||||
): Promise<{success: boolean, data?: SsoUser, tempToken?: string, error?: string}> {
|
||||
try {
|
||||
console.log("开始保存用户信息", userInfo);
|
||||
|
||||
// 验证必要字段
|
||||
if (!userInfo.sub) {
|
||||
return { success: false, error: "用户唯一标识 sub 不能为空" };
|
||||
}
|
||||
|
||||
// 🔒 安全:在服务端生成临时 JWT,user_id 使用占位符 'login'
|
||||
// 这样客户端无法看到真实的 user_id
|
||||
const tempUserInfo: UserInfoForJWT = {
|
||||
sub: userInfo.sub,
|
||||
user_id: 'login', // 使用占位符,避免在客户端暴露真实ID
|
||||
username: 'login',
|
||||
nick_name: userInfo.nick_name || userInfo.nickname || userInfo.name || "未知用户",
|
||||
email: userInfo.email,
|
||||
phone_number: userInfo.phone_number,
|
||||
ou_id: userInfo.ou_id || "default",
|
||||
ou_name: userInfo.ou_name || "未知部门",
|
||||
is_leader: userInfo.is_leader || false,
|
||||
user_role: userRole
|
||||
};
|
||||
|
||||
const tempToken = JWTUtils.generateJWT(tempUserInfo, tokenExpiresIn);
|
||||
|
||||
// 1. 根据 sub 查询是否已存在该用户
|
||||
const existingUserResult = await postgrestGet<SsoUser[]>("sso_users", {
|
||||
filter: {
|
||||
"sub": `eq.${userInfo.sub}`,
|
||||
"deleted_at": "is.null" // 只查询未删除的记录
|
||||
},
|
||||
token: tempToken
|
||||
});
|
||||
|
||||
if (existingUserResult.error) {
|
||||
console.error("查询用户失败:", existingUserResult.error);
|
||||
return { success: false, error: `查询用户失败: ${existingUserResult.error}` };
|
||||
}
|
||||
|
||||
const existingUsers = existingUserResult.data || [];
|
||||
const existingUser = existingUsers.length > 0 ? existingUsers[0] : null;
|
||||
|
||||
// 准备要保存的用户数据
|
||||
// 注意:OAuth返回的字段是nickname,而不是nick_name
|
||||
const userData: Partial<SsoUser> = {
|
||||
sub: userInfo.sub,
|
||||
username: userInfo.username || userInfo.name || userInfo.sub,
|
||||
nick_name: userInfo.nick_name || userInfo.nickname || userInfo.name || "未知用户",
|
||||
phone_number: userInfo.phone_number || undefined,
|
||||
email: userInfo.email || undefined,
|
||||
ou_id: userInfo.ou_id || "default",
|
||||
ou_name: userInfo.ou_name || "未知部门",
|
||||
status: userInfo.status !== undefined ? userInfo.status : 0,
|
||||
is_leader: userInfo.is_leader || false,
|
||||
};
|
||||
|
||||
if (existingUser) {
|
||||
// 2. 用户已存在,执行更新操作
|
||||
console.log("用户已存在,执行更新操作", existingUser.id);
|
||||
|
||||
// 只有在现有用户没有 area 或 area 为空时,才更新 area
|
||||
if (area && !existingUser.area) {
|
||||
userData.area = area;
|
||||
console.log("用户原本无地区信息,更新地区为:", area);
|
||||
} else if (existingUser.area) {
|
||||
console.log("用户已有地区信息:", existingUser.area, "不更新");
|
||||
}
|
||||
|
||||
const updateResult = await postgrestPut<SsoUser[], Partial<SsoUser>>(
|
||||
"sso_users",
|
||||
userData,
|
||||
{ id: existingUser.id! },
|
||||
tempToken
|
||||
);
|
||||
|
||||
if (updateResult.error) {
|
||||
console.error("更新用户失败:", updateResult.error);
|
||||
return { success: false, error: `更新用户失败: ${updateResult.error}` };
|
||||
}
|
||||
|
||||
console.log("用户信息更新成功");
|
||||
return {
|
||||
success: true,
|
||||
data: Array.isArray(updateResult.data) ? updateResult.data[0] : updateResult.data as unknown as SsoUser,
|
||||
tempToken // 返回临时 JWT
|
||||
};
|
||||
} else {
|
||||
// 3. 用户不存在,执行插入操作,设置地区信息
|
||||
console.log("用户不存在,执行插入操作");
|
||||
|
||||
// 新用户直接设置 area
|
||||
if (area) {
|
||||
userData.area = area;
|
||||
console.log("新用户,设置地区为:", area);
|
||||
}
|
||||
|
||||
const insertResult = await postgrestPost<SsoUser[], SsoUser>("sso_users", userData as SsoUser, tempToken);
|
||||
|
||||
if (insertResult.error) {
|
||||
console.error("插入用户失败:", insertResult.error);
|
||||
return { success: false, error: `插入用户失败: ${insertResult.error}` };
|
||||
}
|
||||
|
||||
console.log("用户信息插入成功");
|
||||
|
||||
// 4. 给这个用户默认添加一个角色,角色为common
|
||||
const userData_with_id = Array.isArray(insertResult.data) ? insertResult.data[0] : insertResult.data as unknown as SsoUser;
|
||||
if (userData_with_id?.id) {
|
||||
await addDefaultRole(userData_with_id.id, 2, tempToken);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: userData_with_id,
|
||||
tempToken // 返回临时 JWT
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("保存用户信息时发生错误:", error);
|
||||
return {
|
||||
success: false,
|
||||
error: `保存用户信息失败: ${error instanceof Error ? error.message : String(error)}`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为用户添加默认角色
|
||||
*
|
||||
* @param userId - 用户ID
|
||||
* @param roleId - 角色ID,默认为2(common角色)
|
||||
* @param token - JWT令牌,用于调用postgrest服务
|
||||
* @returns 添加结果
|
||||
*/
|
||||
export async function addDefaultRole(userId: string, roleId: number = 2, token?: string) {
|
||||
try {
|
||||
console.log(`为用户 ${userId} 添加默认角色 ${roleId}`);
|
||||
|
||||
// 检查用户是否已经有此角色
|
||||
const existingRoleResult = await postgrestGet<Array<{id: number, user_id: string, role_id: number}>>("user_role", {
|
||||
filter: {
|
||||
user_id: `eq.${userId}`,
|
||||
role_id: `eq.${roleId}`
|
||||
},
|
||||
token
|
||||
});
|
||||
|
||||
if (existingRoleResult.error) {
|
||||
console.error("查询用户角色失败:", existingRoleResult.error);
|
||||
return { success: false, error: `查询用户角色失败: ${existingRoleResult.error}` };
|
||||
}
|
||||
|
||||
const existingRoles = existingRoleResult.data || [];
|
||||
if (existingRoles.length > 0) {
|
||||
console.log("用户已经拥有此角色,跳过添加");
|
||||
return { success: true, data: existingRoles[0] };
|
||||
}
|
||||
|
||||
// 添加角色
|
||||
const addRoleResult = await postgrestPost<Array<{id: number, user_id: string, role_id: number}>, {user_id: string, role_id: number}>("user_role", {
|
||||
user_id: userId,
|
||||
role_id: roleId
|
||||
}, token);
|
||||
|
||||
if (addRoleResult.error) {
|
||||
console.error("添加用户角色失败:", addRoleResult.error);
|
||||
return { success: false, error: `添加用户角色失败: ${addRoleResult.error}` };
|
||||
}
|
||||
|
||||
console.log("用户角色添加成功");
|
||||
return {
|
||||
success: true,
|
||||
data: Array.isArray(addRoleResult.data) ? addRoleResult.data[0] : addRoleResult.data
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("添加用户角色时发生错误:", error);
|
||||
return {
|
||||
success: false,
|
||||
error: `添加用户角色失败: ${error instanceof Error ? error.message : String(error)}`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过用户sub获取用户信息
|
||||
*
|
||||
* @param sub - 用户的唯一标识
|
||||
* @returns 用户信息
|
||||
*/
|
||||
export async function getUserBySub(sub: string) {
|
||||
try {
|
||||
// console.log(`查询用户: ${sub}`);
|
||||
|
||||
const userResult = await postgrestGet<SsoUser[]>("sso_users", {
|
||||
filter: {
|
||||
sub: `eq.${sub}`
|
||||
}
|
||||
});
|
||||
|
||||
if (userResult.error) {
|
||||
console.error("查询用户失败:", userResult.error);
|
||||
return { success: false, error: `查询用户失败: ${userResult.error}` };
|
||||
}
|
||||
|
||||
const users = userResult.data || [];
|
||||
const user = users.length > 0 ? users[0] : null;
|
||||
|
||||
if (!user) {
|
||||
return { success: false, error: "用户不存在" };
|
||||
}
|
||||
|
||||
return { success: true, data: user };
|
||||
} catch (error) {
|
||||
console.error("查询用户时发生错误:", error);
|
||||
return {
|
||||
success: false,
|
||||
error: `查询用户失败: ${error instanceof Error ? error.message : String(error)}`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user