refactor: P1-2 actions 层 DB 操作下沉到 data-access (exams/homework/questions/announcements)
This commit is contained in:
@@ -2,16 +2,21 @@
|
||||
|
||||
import { revalidatePath } from "next/cache"
|
||||
import { createId } from "@paralleldrive/cuid2"
|
||||
import { eq } from "drizzle-orm"
|
||||
|
||||
import { requireAuth, requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
|
||||
import { Permissions } from "@/shared/types/permissions"
|
||||
import { db } from "@/shared/db"
|
||||
import { announcements } from "@/shared/db/schema"
|
||||
import type { ActionState } from "@/shared/types/action-state"
|
||||
|
||||
import { CreateAnnouncementSchema, UpdateAnnouncementSchema } from "./schema"
|
||||
import { getAnnouncements, getAnnouncementById } from "./data-access"
|
||||
import {
|
||||
getAnnouncements,
|
||||
getAnnouncementById,
|
||||
insertAnnouncement,
|
||||
updateAnnouncementById,
|
||||
deleteAnnouncementById,
|
||||
publishAnnouncementById,
|
||||
archiveAnnouncementById,
|
||||
} from "./data-access"
|
||||
import type { GetAnnouncementsParams, Announcement } from "./types"
|
||||
|
||||
export async function createAnnouncementAction(
|
||||
@@ -49,9 +54,8 @@ export async function createAnnouncementAction(
|
||||
? new Date(input.publishedAt)
|
||||
: null
|
||||
|
||||
const id = createId()
|
||||
await db.insert(announcements).values({
|
||||
id,
|
||||
const id = await insertAnnouncement({
|
||||
id: createId(),
|
||||
title: input.title,
|
||||
content: input.content,
|
||||
type: input.type,
|
||||
@@ -105,7 +109,6 @@ export async function updateAnnouncementAction(
|
||||
}
|
||||
|
||||
const input = parsed.data
|
||||
const wasPublished = existing.status === "published"
|
||||
const isPublished = input.status === "published"
|
||||
const publishedAt = isPublished
|
||||
? existing.publishedAt
|
||||
@@ -115,24 +118,20 @@ export async function updateAnnouncementAction(
|
||||
? new Date(input.publishedAt)
|
||||
: null
|
||||
|
||||
await db
|
||||
.update(announcements)
|
||||
.set({
|
||||
title: input.title,
|
||||
content: input.content,
|
||||
type: input.type,
|
||||
status: input.status,
|
||||
targetGradeId: input.targetGradeId,
|
||||
targetClassId: input.targetClassId,
|
||||
publishedAt,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(announcements.id, id))
|
||||
await updateAnnouncementById(id, {
|
||||
title: input.title,
|
||||
content: input.content,
|
||||
type: input.type,
|
||||
status: input.status,
|
||||
targetGradeId: input.targetGradeId,
|
||||
targetClassId: input.targetClassId,
|
||||
publishedAt,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
|
||||
revalidatePath("/admin/announcements")
|
||||
revalidatePath(`/admin/announcements/${id}`)
|
||||
revalidatePath("/announcements")
|
||||
void wasPublished
|
||||
|
||||
return { success: true, message: "Announcement updated", data: id }
|
||||
} catch (e) {
|
||||
@@ -151,7 +150,7 @@ export async function deleteAnnouncementAction(id: string): Promise<ActionState<
|
||||
const existing = await getAnnouncementById(id)
|
||||
if (!existing) return { success: false, message: "Announcement not found" }
|
||||
|
||||
await db.delete(announcements).where(eq(announcements.id, id))
|
||||
await deleteAnnouncementById(id)
|
||||
|
||||
revalidatePath("/admin/announcements")
|
||||
revalidatePath("/announcements")
|
||||
@@ -173,14 +172,10 @@ export async function publishAnnouncementAction(id: string): Promise<ActionState
|
||||
const existing = await getAnnouncementById(id)
|
||||
if (!existing) return { success: false, message: "Announcement not found" }
|
||||
|
||||
await db
|
||||
.update(announcements)
|
||||
.set({
|
||||
status: "published",
|
||||
publishedAt: existing.publishedAt ? new Date(existing.publishedAt) : new Date(),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(announcements.id, id))
|
||||
const publishedAt = existing.publishedAt
|
||||
? new Date(existing.publishedAt)
|
||||
: new Date()
|
||||
await publishAnnouncementById(id, publishedAt)
|
||||
|
||||
revalidatePath("/admin/announcements")
|
||||
revalidatePath(`/admin/announcements/${id}`)
|
||||
@@ -203,13 +198,7 @@ export async function archiveAnnouncementAction(id: string): Promise<ActionState
|
||||
const existing = await getAnnouncementById(id)
|
||||
if (!existing) return { success: false, message: "Announcement not found" }
|
||||
|
||||
await db
|
||||
.update(announcements)
|
||||
.set({
|
||||
status: "archived",
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(announcements.id, id))
|
||||
await archiveAnnouncementById(id)
|
||||
|
||||
revalidatePath("/admin/announcements")
|
||||
revalidatePath(`/admin/announcements/${id}`)
|
||||
|
||||
@@ -7,8 +7,10 @@ import { db } from "@/shared/db"
|
||||
import { announcements, users } from "@/shared/db/schema"
|
||||
import type {
|
||||
Announcement,
|
||||
AnnouncementInsertData,
|
||||
AnnouncementStatus,
|
||||
AnnouncementType,
|
||||
AnnouncementUpdateData,
|
||||
GetAnnouncementsParams,
|
||||
} from "./types"
|
||||
|
||||
@@ -118,3 +120,67 @@ export const getAnnouncementById = cache(
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export async function insertAnnouncement(
|
||||
data: AnnouncementInsertData
|
||||
): Promise<string> {
|
||||
await db.insert(announcements).values({
|
||||
id: data.id,
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
type: data.type,
|
||||
status: data.status,
|
||||
targetGradeId: data.targetGradeId,
|
||||
targetClassId: data.targetClassId,
|
||||
authorId: data.authorId,
|
||||
publishedAt: data.publishedAt,
|
||||
})
|
||||
return data.id
|
||||
}
|
||||
|
||||
export async function updateAnnouncementById(
|
||||
id: string,
|
||||
data: AnnouncementUpdateData
|
||||
): Promise<void> {
|
||||
await db
|
||||
.update(announcements)
|
||||
.set({
|
||||
title: data.title,
|
||||
content: data.content,
|
||||
type: data.type,
|
||||
status: data.status,
|
||||
targetGradeId: data.targetGradeId,
|
||||
targetClassId: data.targetClassId,
|
||||
publishedAt: data.publishedAt,
|
||||
updatedAt: data.updatedAt,
|
||||
})
|
||||
.where(eq(announcements.id, id))
|
||||
}
|
||||
|
||||
export async function deleteAnnouncementById(id: string): Promise<void> {
|
||||
await db.delete(announcements).where(eq(announcements.id, id))
|
||||
}
|
||||
|
||||
export async function publishAnnouncementById(
|
||||
id: string,
|
||||
publishedAt: Date
|
||||
): Promise<void> {
|
||||
await db
|
||||
.update(announcements)
|
||||
.set({
|
||||
status: "published",
|
||||
publishedAt,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(announcements.id, id))
|
||||
}
|
||||
|
||||
export async function archiveAnnouncementById(id: string): Promise<void> {
|
||||
await db
|
||||
.update(announcements)
|
||||
.set({
|
||||
status: "archived",
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(announcements.id, id))
|
||||
}
|
||||
|
||||
@@ -25,3 +25,26 @@ export type GetAnnouncementsParams = {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export interface AnnouncementInsertData {
|
||||
id: string
|
||||
title: string
|
||||
content: string
|
||||
type: AnnouncementType
|
||||
status: AnnouncementStatus
|
||||
targetGradeId: string | null
|
||||
targetClassId: string | null
|
||||
authorId: string
|
||||
publishedAt: Date | null
|
||||
}
|
||||
|
||||
export interface AnnouncementUpdateData {
|
||||
title: string
|
||||
content: string
|
||||
type: AnnouncementType
|
||||
status: AnnouncementStatus
|
||||
targetGradeId: string | null
|
||||
targetClassId: string | null
|
||||
publishedAt: Date | null
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user