add
This commit is contained in:
parent
5a5d4ec3ff
commit
7e482f8c53
|
@ -1,25 +1,27 @@
|
||||||
import { db, Prisma, PrismaClient } from "@nice/common";
|
import { db, Prisma, PrismaClient } from '@nice/common';
|
||||||
|
|
||||||
export type Operations =
|
export type Operations =
|
||||||
| 'aggregate'
|
| 'aggregate'
|
||||||
| 'count'
|
| 'count'
|
||||||
| 'create'
|
| 'create'
|
||||||
| 'createMany'
|
| 'createMany'
|
||||||
| 'delete'
|
| 'delete'
|
||||||
| 'deleteMany'
|
| 'deleteMany'
|
||||||
| 'findFirst'
|
| 'findFirst'
|
||||||
| 'findMany'
|
| 'findMany'
|
||||||
| 'findUnique'
|
| 'findUnique'
|
||||||
| 'update'
|
| 'update'
|
||||||
| 'updateMany'
|
| 'updateMany'
|
||||||
| 'upsert';
|
| 'upsert';
|
||||||
export type DelegateFuncs = { [K in Operations]: (args: any) => Promise<unknown> }
|
export type DelegateFuncs = {
|
||||||
|
[K in Operations]: (args: any) => Promise<unknown>;
|
||||||
|
};
|
||||||
export type DelegateArgs<T> = {
|
export type DelegateArgs<T> = {
|
||||||
[K in keyof T]: T[K] extends (args: infer A) => Promise<any> ? A : never;
|
[K in keyof T]: T[K] extends (args: infer A) => Promise<any> ? A : never;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DelegateReturnTypes<T> = {
|
export type DelegateReturnTypes<T> = {
|
||||||
[K in keyof T]: T[K] extends (args: any) => Promise<infer R> ? R : never;
|
[K in keyof T]: T[K] extends (args: any) => Promise<infer R> ? R : never;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WhereArgs<T> = T extends { where?: infer W } ? W : never;
|
export type WhereArgs<T> = T extends { where?: infer W } ? W : never;
|
||||||
|
@ -28,17 +30,17 @@ export type DataArgs<T> = T extends { data: infer D } ? D : never;
|
||||||
export type IncludeArgs<T> = T extends { include: infer I } ? I : never;
|
export type IncludeArgs<T> = T extends { include: infer I } ? I : never;
|
||||||
export type OrderByArgs<T> = T extends { orderBy: infer O } ? O : never;
|
export type OrderByArgs<T> = T extends { orderBy: infer O } ? O : never;
|
||||||
export type UpdateOrderArgs = {
|
export type UpdateOrderArgs = {
|
||||||
id: string
|
id: string;
|
||||||
overId: string
|
overId: string;
|
||||||
}
|
};
|
||||||
export interface FindManyWithCursorType<T extends DelegateFuncs> {
|
export interface FindManyWithCursorType<T extends DelegateFuncs> {
|
||||||
cursor?: string;
|
cursor?: string;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
where?: WhereArgs<DelegateArgs<T>['findUnique']>;
|
where?: WhereArgs<DelegateArgs<T>['findUnique']>;
|
||||||
select?: SelectArgs<DelegateArgs<T>['findUnique']>;
|
select?: SelectArgs<DelegateArgs<T>['findUnique']>;
|
||||||
orderBy?: OrderByArgs<DelegateArgs<T>['findMany']>
|
orderBy?: OrderByArgs<DelegateArgs<T>['findMany']>;
|
||||||
}
|
}
|
||||||
export type TransactionType = Omit<
|
export type TransactionType = Omit<
|
||||||
PrismaClient,
|
PrismaClient,
|
||||||
'$connect' | '$disconnect' | '$on' | '$transaction' | '$use' | '$extends'
|
'$connect' | '$disconnect' | '$on' | '$transaction' | '$use' | '$extends'
|
||||||
>;
|
>;
|
|
@ -3,8 +3,10 @@ import { TrpcService } from '@server/trpc/trpc.service';
|
||||||
import { CourseMethodSchema, Prisma } from '@nice/common';
|
import { CourseMethodSchema, Prisma } from '@nice/common';
|
||||||
import { PostService } from './post.service';
|
import { PostService } from './post.service';
|
||||||
import { z, ZodType } from 'zod';
|
import { z, ZodType } from 'zod';
|
||||||
|
import { UpdateOrderArgs } from '../base/base.type';
|
||||||
const PostCreateArgsSchema: ZodType<Prisma.PostCreateArgs> = z.any();
|
const PostCreateArgsSchema: ZodType<Prisma.PostCreateArgs> = z.any();
|
||||||
const PostUpdateArgsSchema: ZodType<Prisma.PostUpdateArgs> = z.any();
|
const PostUpdateArgsSchema: ZodType<Prisma.PostUpdateArgs> = z.any();
|
||||||
|
const PostUpdateOrderArgsSchema: ZodType<UpdateOrderArgs> = z.any();
|
||||||
const PostFindFirstArgsSchema: ZodType<Prisma.PostFindFirstArgs> = z.any();
|
const PostFindFirstArgsSchema: ZodType<Prisma.PostFindFirstArgs> = z.any();
|
||||||
const PostFindManyArgsSchema: ZodType<Prisma.PostFindManyArgs> = z.any();
|
const PostFindManyArgsSchema: ZodType<Prisma.PostFindManyArgs> = z.any();
|
||||||
const PostDeleteManyArgsSchema: ZodType<Prisma.PostDeleteManyArgs> = z.any();
|
const PostDeleteManyArgsSchema: ZodType<Prisma.PostDeleteManyArgs> = z.any();
|
||||||
|
@ -107,5 +109,21 @@ export class PostRouter {
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
return await this.postService.findManyWithPagination(input);
|
return await this.postService.findManyWithPagination(input);
|
||||||
}),
|
}),
|
||||||
|
updateOrder: this.trpc.protectProcedure
|
||||||
|
.input(PostUpdateOrderArgsSchema)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const { staff } = ctx;
|
||||||
|
return await this.postService.updateOrder(input);
|
||||||
|
}),
|
||||||
|
updateOrderByIds: this.trpc.protectProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
ids: z.array(z.string()),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ ctx, input }) => {
|
||||||
|
const { staff } = ctx;
|
||||||
|
return await this.postService.updateOrderByIds(input.ids);
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import EventBus, { CrudOperation } from '@server/utils/event-bus';
|
||||||
import { BaseTreeService } from '../base/base.tree.service';
|
import { BaseTreeService } from '../base/base.tree.service';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { DefaultArgs } from '@prisma/client/runtime/library';
|
import { DefaultArgs } from '@prisma/client/runtime/library';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
||||||
|
@ -43,6 +44,7 @@ export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
||||||
content: content,
|
content: content,
|
||||||
title: title,
|
title: title,
|
||||||
authorId: params?.staff?.id,
|
authorId: params?.staff?.id,
|
||||||
|
updatedAt: dayjs().toDate(),
|
||||||
resources: {
|
resources: {
|
||||||
connect: resourceIds.map((fileId) => ({ fileId })),
|
connect: resourceIds.map((fileId) => ({ fileId })),
|
||||||
},
|
},
|
||||||
|
@ -71,6 +73,7 @@ export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
||||||
parentId: courseId,
|
parentId: courseId,
|
||||||
title: title,
|
title: title,
|
||||||
authorId: staff?.id,
|
authorId: staff?.id,
|
||||||
|
updatedAt: dayjs().toDate(),
|
||||||
} as any,
|
} as any,
|
||||||
},
|
},
|
||||||
{ tx },
|
{ tx },
|
||||||
|
@ -152,6 +155,7 @@ export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
||||||
params?: { staff?: UserProfile; tx?: Prisma.TransactionClient },
|
params?: { staff?: UserProfile; tx?: Prisma.TransactionClient },
|
||||||
) {
|
) {
|
||||||
args.data.authorId = params?.staff?.id;
|
args.data.authorId = params?.staff?.id;
|
||||||
|
args.data.updatedAt = dayjs().toDate();
|
||||||
const result = await super.create(args);
|
const result = await super.create(args);
|
||||||
EventBus.emit('dataChanged', {
|
EventBus.emit('dataChanged', {
|
||||||
type: ObjectType.POST,
|
type: ObjectType.POST,
|
||||||
|
@ -162,6 +166,7 @@ export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
||||||
}
|
}
|
||||||
async update(args: Prisma.PostUpdateArgs, staff?: UserProfile) {
|
async update(args: Prisma.PostUpdateArgs, staff?: UserProfile) {
|
||||||
args.data.authorId = staff?.id;
|
args.data.authorId = staff?.id;
|
||||||
|
args.data.updatedAt = dayjs().toDate();
|
||||||
const result = await super.update(args);
|
const result = await super.update(args);
|
||||||
EventBus.emit('dataChanged', {
|
EventBus.emit('dataChanged', {
|
||||||
type: ObjectType.POST,
|
type: ObjectType.POST,
|
||||||
|
@ -246,8 +251,38 @@ export class PostService extends BaseTreeService<Prisma.PostDelegate> {
|
||||||
}[];
|
}[];
|
||||||
totalPages: number;
|
totalPages: number;
|
||||||
}> {
|
}> {
|
||||||
|
// super.updateOrder;
|
||||||
return super.findManyWithPagination(args);
|
return super.findManyWithPagination(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateOrderByIds(ids: string[]) {
|
||||||
|
const posts = await db.post.findMany({
|
||||||
|
where: { id: { in: ids } },
|
||||||
|
select: { id: true, order: true },
|
||||||
|
});
|
||||||
|
const postMap = new Map(posts.map((post) => [post.id, post]));
|
||||||
|
const orderedPosts = ids
|
||||||
|
.map((id) => postMap.get(id))
|
||||||
|
.filter((post): post is { id: string; order: number } => !!post);
|
||||||
|
|
||||||
|
// 生成仅需更新的操作
|
||||||
|
const updates = orderedPosts
|
||||||
|
.map((post, index) => ({
|
||||||
|
id: post.id,
|
||||||
|
newOrder: index, // 按数组索引设置新顺序
|
||||||
|
currentOrder: post.order,
|
||||||
|
}))
|
||||||
|
.filter(({ newOrder, currentOrder }) => newOrder !== currentOrder)
|
||||||
|
.map(({ id, newOrder }) =>
|
||||||
|
db.post.update({
|
||||||
|
where: { id },
|
||||||
|
data: { order: newOrder },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 批量执行更新
|
||||||
|
return updates.length > 0 ? await db.$transaction(updates) : [];
|
||||||
|
}
|
||||||
protected async setPerms(data: Post, staff?: UserProfile) {
|
protected async setPerms(data: Post, staff?: UserProfile) {
|
||||||
if (!staff) return;
|
if (!staff) return;
|
||||||
const perms: ResPerm = {
|
const perms: ResPerm = {
|
||||||
|
|
|
@ -37,5 +37,4 @@ export class PostQueueService implements OnModuleInit {
|
||||||
debounce: { id: `${QueueJobType.UPDATE_POST_STATE}_${data.id}` },
|
debounce: { id: `${QueueJobType.UPDATE_POST_STATE}_${data.id}` },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
Department,
|
Department,
|
||||||
getRandomElement,
|
getRandomElement,
|
||||||
getRandomElements,
|
getRandomElements,
|
||||||
|
PostType,
|
||||||
Staff,
|
Staff,
|
||||||
TaxonomySlug,
|
TaxonomySlug,
|
||||||
Term,
|
Term,
|
||||||
|
@ -14,6 +15,7 @@ import {
|
||||||
import EventBus from '@server/utils/event-bus';
|
import EventBus from '@server/utils/event-bus';
|
||||||
import { capitalizeFirstLetter, DevDataCounts, getCounts } from './utils';
|
import { capitalizeFirstLetter, DevDataCounts, getCounts } from './utils';
|
||||||
import { StaffService } from '@server/models/staff/staff.service';
|
import { StaffService } from '@server/models/staff/staff.service';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GenDevService {
|
export class GenDevService {
|
||||||
private readonly logger = new Logger(GenDevService.name);
|
private readonly logger = new Logger(GenDevService.name);
|
||||||
|
@ -22,7 +24,7 @@ export class GenDevService {
|
||||||
terms: Record<TaxonomySlug, Term[]> = {
|
terms: Record<TaxonomySlug, Term[]> = {
|
||||||
[TaxonomySlug.CATEGORY]: [],
|
[TaxonomySlug.CATEGORY]: [],
|
||||||
[TaxonomySlug.TAG]: [],
|
[TaxonomySlug.TAG]: [],
|
||||||
[TaxonomySlug.LEVEL]: []
|
[TaxonomySlug.LEVEL]: [],
|
||||||
};
|
};
|
||||||
depts: Department[] = [];
|
depts: Department[] = [];
|
||||||
domains: Department[] = [];
|
domains: Department[] = [];
|
||||||
|
@ -35,7 +37,7 @@ export class GenDevService {
|
||||||
private readonly departmentService: DepartmentService,
|
private readonly departmentService: DepartmentService,
|
||||||
private readonly staffService: StaffService,
|
private readonly staffService: StaffService,
|
||||||
private readonly termService: TermService,
|
private readonly termService: TermService,
|
||||||
) { }
|
) {}
|
||||||
async genDataEvent() {
|
async genDataEvent() {
|
||||||
EventBus.emit('genDataEvent', { type: 'start' });
|
EventBus.emit('genDataEvent', { type: 'start' });
|
||||||
try {
|
try {
|
||||||
|
@ -58,6 +60,7 @@ export class GenDevService {
|
||||||
if (this.counts.termCount === 0) {
|
if (this.counts.termCount === 0) {
|
||||||
this.logger.log('Generate terms');
|
this.logger.log('Generate terms');
|
||||||
await this.createTerms(null, TaxonomySlug.CATEGORY, depth, count);
|
await this.createTerms(null, TaxonomySlug.CATEGORY, depth, count);
|
||||||
|
await this.createLevelTerm();
|
||||||
const domains = this.depts.filter((item) => item.isDomain);
|
const domains = this.depts.filter((item) => item.isDomain);
|
||||||
for (const domain of domains) {
|
for (const domain of domains) {
|
||||||
await this.createTerms(domain, TaxonomySlug.CATEGORY, depth, count);
|
await this.createTerms(domain, TaxonomySlug.CATEGORY, depth, count);
|
||||||
|
@ -174,7 +177,54 @@ export class GenDevService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private async createLevelTerm() {
|
||||||
|
try {
|
||||||
|
// 1. 获取分类时添加异常处理
|
||||||
|
const taxLevel = await db.taxonomy.findFirst({
|
||||||
|
where: { slug: TaxonomySlug.LEVEL },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!taxLevel) {
|
||||||
|
throw new Error('LEVEL taxonomy not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 使用数组定义初始化数据 + 名称去重
|
||||||
|
const termsToCreate = [
|
||||||
|
{ name: '初级', taxonomyId: taxLevel.id },
|
||||||
|
{ name: '中级', taxonomyId: taxLevel.id },
|
||||||
|
{ name: '高级', taxonomyId: taxLevel.id }, // 改为高级更合理
|
||||||
|
];
|
||||||
|
await this.termService.createMany({
|
||||||
|
data: termsToCreate,
|
||||||
|
});
|
||||||
|
console.log('created level terms');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to create level terms:', error);
|
||||||
|
throw error; // 向上抛出错误供上层处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private async createCourse(
|
||||||
|
title: string,
|
||||||
|
deptId: string,
|
||||||
|
cateId: string,
|
||||||
|
levelId: string,
|
||||||
|
) {
|
||||||
|
const course = await db.post.create({
|
||||||
|
data: {
|
||||||
|
type: PostType.COURSE,
|
||||||
|
title: title,
|
||||||
|
updatedAt: dayjs().toDate(),
|
||||||
|
depts: {
|
||||||
|
connect: {
|
||||||
|
id: deptId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
terms:{
|
||||||
|
connect:[cateId,levelId].map
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
private async createDepartment(
|
private async createDepartment(
|
||||||
name: string,
|
name: string,
|
||||||
parentId?: string | null,
|
parentId?: string | null,
|
||||||
|
|
|
@ -115,7 +115,7 @@ export function CourseFormProvider({
|
||||||
});
|
});
|
||||||
message.success("课程更新成功!");
|
message.success("课程更新成功!");
|
||||||
} else {
|
} else {
|
||||||
const result = await createCourse.mutateAsync({
|
const result = await create.mutateAsync({
|
||||||
courseDetail: {
|
courseDetail: {
|
||||||
data: {
|
data: {
|
||||||
title: formattedValues.title || "12345",
|
title: formattedValues.title || "12345",
|
||||||
|
|
|
@ -48,7 +48,7 @@ export const LectureList: React.FC<LectureListProps> = ({
|
||||||
field,
|
field,
|
||||||
sectionId,
|
sectionId,
|
||||||
}) => {
|
}) => {
|
||||||
const { softDeleteByIds } = usePost();
|
const { softDeleteByIds, updateOrderByIds } = usePost();
|
||||||
const { data: lectures = [], isLoading } = (
|
const { data: lectures = [], isLoading } = (
|
||||||
api.post.findMany as any
|
api.post.findMany as any
|
||||||
).useQuery(
|
).useQuery(
|
||||||
|
@ -87,11 +87,19 @@ export const LectureList: React.FC<LectureListProps> = ({
|
||||||
const handleDragEnd = (event: DragEndEvent) => {
|
const handleDragEnd = (event: DragEndEvent) => {
|
||||||
const { active, over } = event;
|
const { active, over } = event;
|
||||||
if (!over || active.id === over.id) return;
|
if (!over || active.id === over.id) return;
|
||||||
|
// updateOrder.mutateAsync({
|
||||||
|
// id: active.id,
|
||||||
|
// overId: over.id,
|
||||||
|
// });
|
||||||
|
let newItems = [];
|
||||||
setItems((items) => {
|
setItems((items) => {
|
||||||
const oldIndex = items.findIndex((item) => item.id === active.id);
|
const oldIndex = items.findIndex((item) => item.id === active.id);
|
||||||
const newIndex = items.findIndex((item) => item.id === over.id);
|
const newIndex = items.findIndex((item) => item.id === over.id);
|
||||||
return arrayMove(items, oldIndex, newIndex);
|
newItems = arrayMove(items, oldIndex, newIndex);
|
||||||
|
return newItems;
|
||||||
|
});
|
||||||
|
updateOrderByIds.mutateAsync({
|
||||||
|
ids: newItems.map((item) => item.id),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// import { FormArrayField } from "@web/src/components/common/form/FormArrayField";
|
|
||||||
// import { useFormContext } from "react-hook-form";
|
|
||||||
// import { CourseFormData } from "../context/CourseEditorContext";
|
|
||||||
// import InputList from "@web/src/components/common/input/InputList";
|
|
||||||
// import { useState } from "react";
|
|
||||||
// import { Form } from "antd";
|
|
||||||
|
|
||||||
// export function CourseGoalForm() {
|
|
||||||
// return (
|
|
||||||
// <div className="max-w-2xl mx-auto space-y-6 p-6">
|
|
||||||
// <Form.Item name="requirements" label="前置要求">
|
|
||||||
// <InputList placeholder="请输入前置要求"></InputList>
|
|
||||||
// </Form.Item>
|
|
||||||
// <Form.Item name="objectives" label="学习目标">
|
|
||||||
// <InputList placeholder="请输入学习目标"></InputList>
|
|
||||||
// </Form.Item>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
|
@ -1,26 +0,0 @@
|
||||||
// import AvatarUploader from "@web/src/components/common/uploader/AvatarUploader";
|
|
||||||
// import { Form, Input } from "antd";
|
|
||||||
|
|
||||||
// export default function CourseSettingForm() {
|
|
||||||
// return (
|
|
||||||
// <div className="max-w-2xl mx-auto space-y-6 p-6">
|
|
||||||
// <Form.Item
|
|
||||||
// name="title"
|
|
||||||
// label="课程预览图"
|
|
||||||
// >
|
|
||||||
// <AvatarUploader
|
|
||||||
// style={
|
|
||||||
// {
|
|
||||||
// width: "120px",
|
|
||||||
// height: "120px",
|
|
||||||
// margin:" 0 10px"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// onChange={(value) => {
|
|
||||||
// console.log(value);
|
|
||||||
// }}
|
|
||||||
// ></AvatarUploader>
|
|
||||||
// </Form.Item>
|
|
||||||
// </div>
|
|
||||||
// )
|
|
||||||
// }
|
|
|
@ -113,5 +113,8 @@ export function useEntity<T extends keyof RouterInputs>(
|
||||||
T,
|
T,
|
||||||
"updateOrder"
|
"updateOrder"
|
||||||
>, // 更新实体顺序的 mutation 函数
|
>, // 更新实体顺序的 mutation 函数
|
||||||
|
updateOrderByIds: createMutationHandler(
|
||||||
|
"updateOrderByIds"
|
||||||
|
) as MutationResult<T, "updateOrderByIds">, // 更新实体顺序的 mutation 函数
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@ model Department {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
name String
|
name String
|
||||||
order Float?
|
order Float?
|
||||||
|
posts Post[] @relation("post_dept")
|
||||||
ancestors DeptAncestry[] @relation("DescendantToAncestor")
|
ancestors DeptAncestry[] @relation("DescendantToAncestor")
|
||||||
descendants DeptAncestry[] @relation("AncestorToDescendant")
|
descendants DeptAncestry[] @relation("AncestorToDescendant")
|
||||||
parentId String? @map("parent_id")
|
parentId String? @map("parent_id")
|
||||||
|
@ -200,6 +201,8 @@ model Post {
|
||||||
order Float? @default(0) @map("order")
|
order Float? @default(0) @map("order")
|
||||||
duration Int?
|
duration Int?
|
||||||
rating Int? @default(0)
|
rating Int? @default(0)
|
||||||
|
|
||||||
|
depts Department[] @relation("post_dept")
|
||||||
// 索引
|
// 索引
|
||||||
// 日期时间类型字段
|
// 日期时间类型字段
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
|
|
Loading…
Reference in New Issue