13 changed files with 396 additions and 58 deletions
Binary file not shown.
@ -0,0 +1,85 @@ |
|||
import { dbGlobal } from "drizzle-pkg/lib/db"; |
|||
import { users } from "drizzle-pkg/lib/schema/auth"; |
|||
import { eq } from "drizzle-orm"; |
|||
import { UNAUTHORIZED_MESSAGE } from "#server/constants/auth"; |
|||
import { toPublicAuthError } from "#server/service/auth/errors"; |
|||
|
|||
export default defineWrappedResponseHandler(async (event) => { |
|||
try { |
|||
const user = await event.context.auth.requireUser(); |
|||
if (!user) { |
|||
throw createError({ |
|||
statusCode: 401, |
|||
statusMessage: UNAUTHORIZED_MESSAGE, |
|||
}); |
|||
} |
|||
|
|||
const body = await readBody<{ |
|||
username?: string; |
|||
email?: string; |
|||
nickname?: string; |
|||
}>(event); |
|||
|
|||
if (!body || Object.keys(body).length === 0) { |
|||
throw createError({ |
|||
statusCode: 400, |
|||
statusMessage: "请提供要更新的字段", |
|||
}); |
|||
} |
|||
|
|||
const updateData: Partial<{ |
|||
username: string; |
|||
email: string | null; |
|||
nickname: string | null; |
|||
}> = {}; |
|||
|
|||
if (body.username !== undefined) { |
|||
if (typeof body.username !== "string" || body.username.trim().length === 0) { |
|||
throw createError({ statusCode: 400, statusMessage: "用户名不能为空" }); |
|||
} |
|||
if (body.username.length < 2 || body.username.length > 50) { |
|||
throw createError({ statusCode: 400, statusMessage: "用户名长度需在2-50字符之间" }); |
|||
} |
|||
updateData.username = body.username.trim(); |
|||
} |
|||
|
|||
if (body.email !== undefined) { |
|||
if (body.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(body.email)) { |
|||
throw createError({ statusCode: 400, statusMessage: "邮箱格式不正确" }); |
|||
} |
|||
updateData.email = body.email?.trim() || null; |
|||
} |
|||
|
|||
if (body.nickname !== undefined) { |
|||
updateData.nickname = body.nickname?.trim() || null; |
|||
} |
|||
|
|||
if (Object.keys(updateData).length > 0) { |
|||
await dbGlobal |
|||
.update(users) |
|||
.set(updateData) |
|||
.where(eq(users.id, user.id)); |
|||
|
|||
// Invalidate me cache
|
|||
await event.context.cache.del(`auth:me:${user.id}`); |
|||
} |
|||
|
|||
// Fetch updated user data
|
|||
const [row] = await dbGlobal |
|||
.select({ |
|||
id: users.id, |
|||
username: users.username, |
|||
email: users.email, |
|||
role: users.role, |
|||
nickname: users.nickname, |
|||
avatar: users.avatar, |
|||
}) |
|||
.from(users) |
|||
.where(eq(users.id, user.id)) |
|||
.limit(1); |
|||
|
|||
return R.success({ user: row }); |
|||
} catch (err) { |
|||
throw toPublicAuthError(err); |
|||
} |
|||
}); |
|||
@ -0,0 +1,13 @@ |
|||
import { deleteExecution } from "#server/service/scheduler"; |
|||
|
|||
export default defineWrappedResponseHandler(async (event) => { |
|||
const id = getRouterParam(event, "id"); |
|||
if (!id) return R.throwError(400, "Missing id", null); |
|||
|
|||
const deleted = await deleteExecution(id); |
|||
|
|||
await event.context.cache.del('scheduler:executions:1:20:all:all') |
|||
await event.context.cache.del('scheduler:stats') |
|||
|
|||
return R.success({ deleted }); |
|||
}); |
|||
@ -0,0 +1,13 @@ |
|||
import { deleteAllExecutions } from "#server/service/scheduler"; |
|||
|
|||
export default defineWrappedResponseHandler(async (event) => { |
|||
const query = getQuery(event); |
|||
const taskId = query.taskId as string | undefined; |
|||
|
|||
const deleted = await deleteAllExecutions(taskId); |
|||
|
|||
await event.context.cache.del('scheduler:executions:1:20:all:all') |
|||
await event.context.cache.del('scheduler:stats') |
|||
|
|||
return R.success({ deleted }); |
|||
}); |
|||
Loading…
Reference in new issue