优化组织和用户创建逻辑,简化插入数据结构并处理可选描述字段
This commit is contained in:
@@ -178,7 +178,16 @@ export class Org {
|
||||
* 创建组织
|
||||
*/
|
||||
static async create(data: { username: string; description?: string; users: OrgUser[] }): Promise<Org> {
|
||||
const inserted = await db.insert(orgsTable).values(data).returning();
|
||||
const insertData: any = {
|
||||
username: data.username,
|
||||
users: data.users,
|
||||
};
|
||||
|
||||
if (data.description !== undefined && data.description !== null) {
|
||||
insertData.description = data.description;
|
||||
}
|
||||
|
||||
const inserted = await db.insert(orgsTable).values(insertData).returning();
|
||||
return new Org(inserted[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -259,13 +259,19 @@ export class UserSecret {
|
||||
userId = tokenUser.uid;
|
||||
orgId = tokenUser.id;
|
||||
}
|
||||
const inserted = await db.insert(userSecretsTable).values({
|
||||
|
||||
const insertData: Partial<typeof userSecretsTable.$inferInsert> = {
|
||||
userId,
|
||||
orgId,
|
||||
token,
|
||||
title: tokenUser.title || randomString(6),
|
||||
expiredTime: UserSecret.getExpiredTime(expireDays).toISOString(),
|
||||
}).returning();
|
||||
};
|
||||
|
||||
if (orgId !== null && orgId !== undefined) {
|
||||
insertData.orgId = orgId;
|
||||
}
|
||||
|
||||
const inserted = await db.insert(userSecretsTable).values(insertData).returning();
|
||||
|
||||
return new UserSecret(inserted[0]);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import { oauth } from '../oauth/auth.ts';
|
||||
import { cryptPwd } from '../oauth/salt.ts';
|
||||
import { OauthUser } from '../oauth/oauth.ts';
|
||||
import { db } from '../../modules/db.ts';
|
||||
import { Org } from './org.ts';
|
||||
|
||||
import { cfUser, cfOrgs, cfUserSecrets } from '../../db/drizzle/schema.ts';
|
||||
import { eq, sql, InferSelectModel, InferInsertModel } from 'drizzle-orm';
|
||||
|
||||
@@ -167,13 +169,13 @@ export class User {
|
||||
*/
|
||||
static async findOne(where: { username?: string; id?: string }): Promise<User | null> {
|
||||
let query = db.select().from(usersTable);
|
||||
|
||||
|
||||
if (where.username) {
|
||||
query = query.where(eq(usersTable.username, where.username)) as any;
|
||||
} else if (where.id) {
|
||||
query = query.where(eq(usersTable.id, where.id)) as any;
|
||||
}
|
||||
|
||||
|
||||
const users = await query.limit(1);
|
||||
return users.length > 0 ? new User(users[0]) : null;
|
||||
}
|
||||
@@ -187,18 +189,31 @@ export class User {
|
||||
let needChangePassword = !password;
|
||||
password = password || '123456';
|
||||
const cPassword = cryptPwd(password, salt);
|
||||
|
||||
const inserted = await db.insert(usersTable).values({
|
||||
|
||||
const insertData: any = {
|
||||
username,
|
||||
password: cPassword,
|
||||
description,
|
||||
salt,
|
||||
needChangePassword,
|
||||
}).returning();
|
||||
|
||||
return new User(inserted[0]);
|
||||
};
|
||||
|
||||
// 只在需要时才设置非默认值
|
||||
if (needChangePassword) {
|
||||
insertData.needChangePassword = true;
|
||||
}
|
||||
|
||||
if (description !== undefined && description !== null) {
|
||||
insertData.description = description;
|
||||
}
|
||||
try {
|
||||
const inserted = await db.insert(usersTable).values(insertData).returning();
|
||||
return new User(inserted[0]);
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
throw e
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static async createOrg(username: string, owner: string, description?: string) {
|
||||
const user = await User.findOne({ username });
|
||||
if (user) {
|
||||
@@ -211,18 +226,23 @@ export class User {
|
||||
if (me.type !== 'user') {
|
||||
throw new CustomError('Owner type is not user');
|
||||
}
|
||||
|
||||
const { Org } = await import('./org.ts');
|
||||
|
||||
const org = await Org.create({ username, description, users: [{ uid: owner, role: 'owner' }] });
|
||||
const inserted = await db.insert(usersTable).values({
|
||||
|
||||
const insertData: any = {
|
||||
username,
|
||||
password: '',
|
||||
description,
|
||||
type: 'org',
|
||||
owner,
|
||||
orgId: org.id,
|
||||
}).returning();
|
||||
|
||||
};
|
||||
|
||||
if (description !== undefined && description !== null) {
|
||||
insertData.description = description;
|
||||
}
|
||||
|
||||
const inserted = await db.insert(usersTable).values(insertData).returning();
|
||||
|
||||
// owner add
|
||||
await redis.del(`user:${me.id}:orgs`);
|
||||
return new User(inserted[0]);
|
||||
@@ -234,7 +254,7 @@ export class User {
|
||||
await db.update(usersTable).set({ password: cPassword }).where(eq(usersTable.id, this.id));
|
||||
return cPassword;
|
||||
}
|
||||
|
||||
|
||||
checkPassword(password: string) {
|
||||
const salt = this.salt;
|
||||
const cPassword = cryptPwd(password, salt);
|
||||
@@ -304,6 +324,7 @@ export class User {
|
||||
*/
|
||||
async getOrgs() {
|
||||
let id = this.id;
|
||||
console.log('type', this.type, this.tokenUser)
|
||||
if (this.type === 'org') {
|
||||
if (this.tokenUser && this.tokenUser.uid) {
|
||||
id = this.tokenUser.uid;
|
||||
@@ -315,14 +336,14 @@ export class User {
|
||||
if (cache) {
|
||||
return JSON.parse(cache) as string[];
|
||||
}
|
||||
|
||||
|
||||
// 使用 Drizzle 的 SQL 查询来检查 JSONB 数组
|
||||
const orgs = await db
|
||||
.select()
|
||||
.from(orgsTable)
|
||||
.where(sql`${orgsTable.users} @> ${JSON.stringify([{ uid: id }])}::jsonb`)
|
||||
.orderBy(sql`${orgsTable.updatedAt} DESC`);
|
||||
|
||||
|
||||
const orgNames = orgs.map((org) => org.username);
|
||||
if (orgNames.length > 0) {
|
||||
await redis.set(`user:${id}:orgs`, JSON.stringify(orgNames), 'EX', 60 * 60); // 1 hour
|
||||
@@ -349,11 +370,11 @@ export class User {
|
||||
*/
|
||||
static async findAll(options: { where?: any; attributes?: string[] }) {
|
||||
let query = db.select().from(usersTable);
|
||||
|
||||
|
||||
if (options.where?.id?.in) {
|
||||
query = query.where(sql`${usersTable.id} = ANY(${options.where.id.in})`) as any;
|
||||
}
|
||||
|
||||
|
||||
const users = await query;
|
||||
return users.map(u => new User(u));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user