Commit 1b74238d authored by wyuer's avatar wyuer

der

parent cea5fbbd
/*
Warnings:
- Added the required column `parentId` to the `Folder` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE `Folder` ADD COLUMN `parentId` INTEGER NOT NULL;
-- CreateTable
CREATE TABLE `Collection` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL,
`parentId` INTEGER NOT NULL,
`code` VARCHAR(191) NOT NULL,
`fault` VARCHAR(191) NOT NULL,
`faultReason` VARCHAR(191) NOT NULL,
`faultType` VARCHAR(191) NOT NULL,
`faultFn` VARCHAR(191) NOT NULL,
`faultMessage` VARCHAR(191) NOT NULL,
`faultJudge` VARCHAR(191) NOT NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
UNIQUE INDEX `Collection_name_key`(`name`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `Folder` ADD CONSTRAINT `Folder_parentId_fkey` FOREIGN KEY (`parentId`) REFERENCES `Folder`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Collection` ADD CONSTRAINT `Collection_parentId_fkey` FOREIGN KEY (`parentId`) REFERENCES `Folder`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- DropForeignKey
ALTER TABLE `Collection` DROP FOREIGN KEY `Collection_parentId_fkey`;
-- DropForeignKey
ALTER TABLE `Folder` DROP FOREIGN KEY `Folder_parentId_fkey`;
-- AlterTable
ALTER TABLE `Collection` MODIFY `parentId` INTEGER NULL;
-- AlterTable
ALTER TABLE `Folder` MODIFY `parentId` INTEGER NULL;
-- AddForeignKey
ALTER TABLE `Folder` ADD CONSTRAINT `Folder_parentId_fkey` FOREIGN KEY (`parentId`) REFERENCES `Folder`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `Collection` ADD CONSTRAINT `Collection_parentId_fkey` FOREIGN KEY (`parentId`) REFERENCES `Folder`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
......@@ -14,10 +14,29 @@ datasource db {
}
model Folder {
id Int @id @default(autoincrement())
name String @unique
poster String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id Int @id @default(autoincrement())
name String @unique
parentId Int?
poster String
collections Collection[] @relation("FolderToCollection")
folders Folder[] @relation("ChildFolders")
parent Folder? @relation("ChildFolders", fields: [parentId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Collection {
id Int @id @default(autoincrement())
name String @unique
parentId Int?
code String
fault String
faultReason String
faultType String
faultFn String
faultMessage String
faultJudge String
folder Folder? @relation("FolderToCollection", fields: [parentId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
"use client";
import React from "react";
import AddFolder from "@/components/AddFolder";
import AddFileInfo from "@/components/AddFileInfo";
import Cards from "@/components/Cards";
import { useRequest } from "ahooks";
import { getFetch } from "@/lib/doFetch";
export default function Home({ params: { slug } }) {
const { data, refreshAsync, refresh } = useRequest(async () => {
const res = await getFetch({ url: "/api/folder/" + slug, params: {} });
return res?.data ?? [];
});
return (
<div>
<div className="flex gap-4">
<AddFolder refresh={refreshAsync} parentId={slug}/>
<AddFileInfo refresh={refreshAsync} />
</div>
<Cards list={data ?? []} />
</div>
);
}
......@@ -10,6 +10,10 @@ export async function GET(request, { params }) {
where: {
id: parseInt(slug),
},
include: {
collections: true,
folders: true,
},
});
return response(folder);
} catch (error) {
......
......@@ -21,12 +21,13 @@ export async function GET(request, { params }) {
// const slug = params.slug; // 路由参数
try {
const folders = await prisma.folder.findMany({
// where: { published: true },
// include: {
// author: {
// select: { name: true },
// },
// },
where: {
parentId: null, // 根目录
},
include: {
collections: true,
folders: true,
},
});
return response(folders);
} catch (error) {
......
......@@ -4,12 +4,16 @@ import { getFetch } from "@/lib/doFetch";
import { useRequest } from "ahooks";
import { Image, Divider, Button } from "@nextui-org/react";
import dayjs from "dayjs";
import { BsFolderFill } from "react-icons/bs";
import { ArrowLeftOutlined } from "@ant-design/icons";
import EditFolder from "@/components/EditFolder";
import DeleteFolder from "@/components/DeleteFolder";
import AddFolder from "@/components/AddFolder";
import Cards from "@/components/Cards";
import { useRouter } from "next/navigation";
export default function Detail({ folder, params }) {
//params.slug 路由传参获取
const router = useRouter();
const { data, refreshAsync } = useRequest(
async () => {
......@@ -33,7 +37,7 @@ export default function Detail({ folder, params }) {
width={400}
alt="avatar"
/>
<div className="max-w-md ml-20 mt-12 flex-1">
<div className="ml-20 mt-12 flex-1">
<div className="space-y-1">
<h1 className="text-2xl mb-2">{data?.name}</h1>
<p className="text-small text-default-400 ">
......@@ -44,20 +48,34 @@ export default function Detail({ folder, params }) {
</p>
</div>
<Divider className="my-4" />
<div className="flex h-5 items-center space-x-4 text-small mt-8">
<DeleteFolder data={data} refresh={refreshAsync}></DeleteFolder>
<Divider orientation="vertical" />
<EditFolder data={data} refresh={refreshAsync} />
<Divider orientation="vertical" />
<div className="flex items-center space-x-4 text-small mt-8">
<Button
isIconOnly
color="primary"
variant="faded"
aria-label="Take a edit"
aria-label="Take a add"
onPress={() => {
router.back();
}}
>
<BsFolderFill style={{ fontSize: "20px" }} />
<ArrowLeftOutlined></ArrowLeftOutlined>
</Button>
<Divider orientation="vertical" />
<DeleteFolder data={data} refresh={refreshAsync}></DeleteFolder>
<Divider orientation="vertical" />
<EditFolder data={data} refresh={refreshAsync} />
<Divider orientation="vertical" />
<AddFolder
refresh={refreshAsync}
parentId={params.slug}
type={"icon"}
></AddFolder>
<Divider orientation="vertical" />
</div>
<div className="mt-8">
<Cards list={data?.folders ?? []}></Cards>
</div>
</div>
</div>
......
......@@ -20,7 +20,6 @@ export default function Home(props) {
<AddFolder refresh={refreshAsync} />
<AddFileInfo refresh={refreshAsync} />
</div>
<Cards list={data ?? []} />
</div>
);
......
......@@ -11,11 +11,13 @@ import {
Avatar,
} from "@nextui-org/react";
import { AiFillPlusSquare } from "react-icons/ai";
import { FiPlus } from "react-icons/fi";
import { BsFolderFill } from "react-icons/bs";
import { useForm } from "react-hook-form";
import { doFetch } from "@/lib/doFetch";
import UploadImage from "./UploadImage";
export default function AddFolder({ refresh }) {
export default function AddFolder({ refresh, parentId, type }) {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit, control, setValue } = useForm();
......@@ -26,20 +28,36 @@ export default function AddFolder({ refresh }) {
};
const onSubmit = async (data) => {
await doFetch({ url: "/api/folder", params: data });
await doFetch({
url: "/api/folder",
params: { ...data, parentId: parentId ?parseInt(parentId): null },
});
await refresh();
};
return (
<>
<Button
radius="full"
className="bg-gradient-to-tr from-pink-500 to-yellow-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<AiFillPlusSquare />
添加文件夹
</Button>
{type === "icon" ? (
<Button
isIconOnly
color="primary"
variant="faded"
aria-label="Take a add"
onPress={onOpen}
>
<BsFolderFill style={{ fontSize: "20px" }} />
</Button>
) : (
<Button
radius="full"
className="bg-gradient-to-tr from-pink-500 to-yellow-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<FiPlus />
添加文件夹
</Button>
)}
<Modal
isOpen={isOpen}
backdrop={"blur"}
......
......@@ -12,10 +12,11 @@ export default memo(({ list }) => {
const router = useRouter();
return (
<div className="gap-2 grid xl:grid-cols-8 lg:grid-cols-6 md:grid-cols-4 sm:grid-cols-2">
<div className="gap-2 flex flex-wrap">
{list?.map?.((item, index) => (
<Card
shadow="sm"
className="w-[170px]"
key={index}
isPressable
onPress={() => {
......@@ -31,6 +32,7 @@ export default memo(({ list }) => {
alt={item.name}
className="w-full object-cover h-[140px]"
src={item.poster}
fallbackSrc="/folder.png"
/>
</CardBody>
<CardFooter className="text-small justify-between">
......@@ -40,13 +42,13 @@ export default memo(({ list }) => {
</Card>
))}
{list?.length === 0 && (
<Image
alt="empty"
isZoomed
className="object-cover"
src="/empty.png"
width={240}
/>
<Image
alt="empty"
isZoomed
className="object-cover"
src="/empty.png"
width={240}
/>
)}
</div>
);
......
......@@ -82,8 +82,10 @@ const UploadImage = ({ control, setValue }) => {
src={imageUrl}
alt="avatar"
style={{
width: "100%",
width: "100.4px",
height: "100.4px",
}}
className="object-cover"
/>
) : (
uploadButton
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment