Commit 1c23049e authored by wyuer's avatar wyuer

adslder

parent 842fa941
......@@ -2,7 +2,7 @@
import React from "react";
import AddFolder from "@/components/AddFolder";
import AddFileInfo from "@/components/AddFileInfo";
import AddFileInfo from "@/components/AddCollection";
import Cards from "@/components/Cards";
import { useRequest } from "ahooks";
import { getFetch } from "@/lib/doFetch";
......
// RESTFUl api 匹配带路由参数
import response from "@/lib/res";
import prisma from "@/lib/prisma";
// R -> Read One
export async function GET(request, { params }) {
const slug = params.slug;
try {
const collection = await prisma.collection.findUnique({
where: {
id: parseInt(slug),
},
include: {
folder: true,
},
});
return response(collection);
} catch (error) {
return response(error, "err");
}
}
//U -> Update
export async function PUT(request, { params }) {
const body = await request.json();
const slug = params.slug;
try {
const res = await prisma.collection.update({
where: { id: parseInt(slug) },
data: { ...body },
});
return response({ ...res },"更新成功");
} catch (error) {
return response(error, "err");
}
}
//D -> Delete
export async function DELETE(request, { params }) {
const slug = params.slug;
try {
const res = await prisma.collection.delete({
where: { id: parseInt(slug) },
});
return response({ ...res },'删除成功');
} catch (error) {
return response(error, "err");
}
}
// RESTFUl api 匹配无路由参数
import prisma from "@/lib/prisma";
import response from "@/lib/res";
// C -> Create
export async function POST(request) {
const body = await request.json();
//获取body参数
const res = await prisma.collection.create({
data: { ...body },
});
return response({ ...res }, "新建成功");
}
// R -> Read
export async function GET(request, { params }) {
// query is "hello" for /api/search?query=hello
// const slug = params.slug; // 路由参数
try {
const collections = await prisma.collection.findMany({
where: {
parentId: null, // 根目录
},
include: {
folder: true,
},
});
return response(collections);
} catch (error) {
return response(error, "err");
}
}
......@@ -26,9 +26,11 @@ export async function GET(request, { params }) {
},
include: {
collections: true,
folders: true,
},
folders: true
}
});
return response(folders);
} catch (error) {
return response(error, "err");
......
"use client";
import { getFetch } from "@/lib/doFetch";
import { useRequest } from "ahooks";
import { Button } from "@nextui-org/react";
import { ArrowLeftOutlined } from "@ant-design/icons";
import EditFolder from "@/components/EditFolder";
import DeleteFolder from "@/components/DeleteFolder";
import { useRouter } from "next/navigation";
const columns = [
{ name: "code", label: "编码" },
{ name: "faultType", label: "故障类型" },
{ name: "fault", label: "故障" },
{ name: "faultJudge", label: "判断条件" },
{ name: "faultReason", label: "故障原因" },
{ name: "faultFn", label: "解决方案" },
{ name: "faultMessage", label: "故障描述" },
];
export default function Detail({ params }) {
//params.slug 路由传参获取
const router = useRouter();
const { data, refreshAsync } = useRequest(
async () => {
let res = await getFetch({
url: "/api/collection/" + params.slug,
params: {},
});
return res?.data;
},
{
refreshDeps: [params.slug],
}
);
return (
<div className="flex w-full flex-col">
<div className="flex gap-4">
<Button
isIconOnly
color="primary"
variant="faded"
aria-label="Take a add"
onPress={() => {
router.back();
}}
>
<ArrowLeftOutlined></ArrowLeftOutlined>
</Button>
<Button color="primary" variant="flat">
{data?.name}
</Button>
<EditFolder data={data} refresh={refreshAsync}/>
<DeleteFolder data={data} refresh={refreshAsync}/>
</div>
<ul class="divide-y divide-gray-200">
{columns?.map((it) => {
return (
<li class="flex items-center py-4" key={it?.name}>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">{it?.label}</div>
<div class="text-sm text-gray-500">{data?.[it?.name]}</div>
</div>
</li>
);
})}
</ul>
</div>
);
}
......@@ -8,7 +8,11 @@ import { ArrowLeftOutlined } from "@ant-design/icons";
import EditFolder from "@/components/EditFolder";
import DeleteFolder from "@/components/DeleteFolder";
import AddFolder from "@/components/AddFolder";
import AddCollection from '@/components/AddCollection';
import Cards from "@/components/Cards";
import Collections from "@/components/Collections";
import { useRouter } from "next/navigation";
export default function Detail({ folder, params }) {
......@@ -72,10 +76,16 @@ export default function Detail({ folder, params }) {
type={"icon"}
></AddFolder>
<Divider orientation="vertical" />
<AddCollection
refresh={refreshAsync}
parentId={params.slug}
type={"icon"}
/>
</div>
<div className="mt-8">
<div className="mt-8 flex flex-wrap gap-2">
<Cards list={data?.folders ?? []}></Cards>
<Collections list={data?.collections ?? []}></Collections>
</div>
</div>
</div>
......
......@@ -2,8 +2,10 @@
import React from "react";
import AddFolder from "@/components/AddFolder";
import AddFileInfo from "@/components/AddFileInfo";
import AddCollection from "@/components/AddCollection";
import Cards from "@/components/Cards";
import Collections from "@/components/Collections";
import { useRequest } from "ahooks";
import { getFetch } from "@/lib/doFetch";
......@@ -14,13 +16,20 @@ export default function Home(props) {
return res?.data ?? [];
});
const collection = useRequest(async () => {
const res = await getFetch({ url: "/api/collection", params: {} });
return res?.data ?? [];
});
return (
<div>
<div className="flex gap-4">
<AddFolder refresh={refreshAsync} />
<AddFileInfo refresh={refreshAsync} />
<AddCollection refresh={collection?.refreshAsync} />
</div>
<div className="flex gap-4">
<Cards list={data ?? []} />
<Collections list={collection?.data ?? []} />
</div>
</div>
);
}
......@@ -17,7 +17,7 @@ export function Providers({ children }) {
return (
<NextUIProvider navigate={router.push}>
<div className="flex w-full flex-col mb-4">
{/* <div className="flex w-full flex-col mb-4">
<Tabs
aria-label="Options"
radius={"full"}
......@@ -30,11 +30,8 @@ export function Providers({ children }) {
<Tab key="/" title={"首页"}></Tab>
<Tab key="/login" title={"login"}></Tab>
<Tab key="/detail" title={"detail"}></Tab>
</Tabs>
</div>
{/* <Link href="/">首页</Link>
<Link href="/detail">DOC</Link> */}
</div> */}
{children}
</NextUIProvider>
);
......
import React from "react";
import {
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
Button,
useDisclosure,
Input,
Avatar,
Textarea,
} from "@nextui-org/react";
import { AiFillPlusSquare } from "react-icons/ai";
import { useForm } from "react-hook-form";
import { doFetch } from "@/lib/doFetch";
import UploadImage from "./UploadImage";
export default function AddCollection({ refresh, parentId, type }) {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit, control, setValue } = useForm();
const handleButtonClick = async (close) => {
// 手动触发表单提交
handleSubmit(onSubmit)();
await refresh();
close();
};
const onSubmit = async (data) => {
return await doFetch({
url: "/api/collection",
params: { ...data, parentId:parentId ?parseInt(parentId): null },
});
};
return (
<>
{type === "icon" ? (
<Button
isIconOnly
color="primary"
variant="faded"
aria-label="Take a add"
onPress={onOpen}
>
<AiFillPlusSquare style={{ fontSize: "20px" }} />
</Button>
) : (
<Button
radius="full"
className="bg-gradient-to-tr from-green-500 to-blue-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<AiFillPlusSquare />
添加知识库
</Button>
)}
<Modal
isOpen={isOpen}
backdrop={"blur"}
onOpenChange={onOpenChange}
motionProps={{
variants: {
enter: {
y: 0,
opacity: 1,
transition: {
duration: 0.3,
ease: "easeOut",
},
},
exit: {
y: -20,
opacity: 0,
transition: {
duration: 0.2,
ease: "easeIn",
},
},
},
}}
>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
添加知识库
</ModalHeader>
<ModalBody>
<form action="" className="flex flex-col gap-4">
<Input
type="text"
label="知识库名称"
name="name"
isRequired
{...register("name", { required: true, maxLength: 20 })}
/>
<Input
type="text"
label="编码"
name="code"
{...register("code", { required: true, maxLength: 20 })}
/>
<Input
type="text"
label="故障类型"
name="faultType"
{...register("faultType", {
required: true,
maxLength: 20,
})}
/>
<Input
type="text"
label="故障"
name="fault"
{...register("fault", { required: true, maxLength: 20 })}
/>
<Textarea
type="text"
label="判断条件"
name="faultJudge"
{...register("faultJudge", {
required: true,
maxLength: 20,
})}
/>
<Textarea
type="text"
label="故障原因"
name="faultReason"
{...register("faultReason", {
required: true,
maxLength: 20,
})}
/>
<Textarea
type="text"
label="解决方案"
name="faultFn"
{...register("faultFn", { required: true, maxLength: 20 })}
/>
<Textarea
type="text"
label="故障描述"
name="faultMessage"
{...register("faultMessage", {
required: true,
maxLength: 20,
})}
/>
</form>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
取消
</Button>
<Button
color="primary"
onPress={() => {
handleButtonClick(onClose);
}}
>
提交
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</>
);
}
......@@ -16,7 +16,7 @@ export default memo(({ list }) => {
{list?.map?.((item, index) => (
<Card
shadow="sm"
className="w-[170px]"
className="w-[220px]"
key={index}
isPressable
onPress={() => {
......@@ -30,7 +30,7 @@ export default memo(({ list }) => {
radius="lg"
width="100%"
alt={item.name}
className="w-full object-cover h-[140px]"
className="w-full object-cover h-[180px]"
src={item.poster}
fallbackSrc="/folder.png"
/>
......
/* eslint-disable import/no-anonymous-default-export */
/* eslint-disable react/display-name */
import React, { memo } from "react";
import { Card, CardBody, CardFooter, Image, Button } from "@nextui-org/react";
import { difftime } from "@/lib/time";
import { useRouter } from "next/navigation";
export default memo(({ list }) => {
const router = useRouter();
return (
<div className="gap-2 flex flex-wrap">
{list?.map?.((item, index) => (
<Card
shadow="sm"
className="w-[220px]"
key={index}
isPressable
onPress={() => {
router.push("/collectiondetail/" + item.id);
}}
>
<CardBody className="overflow-visible p-0">
<div
className="w-full object-cover h-[180px] flex justify-center items-center bg-gradient-to-r from-cyan-500 to-blue-500"
>
<span className="bg-clip-text text-transparent text-white text-lg">
{item?.name?.substring(0,4).toUpperCase()}
</span>
</div>
</CardBody>
<CardFooter className="text-small justify-between">
<b>{item.name}</b>
<p className="text-default-500">{difftime(item.createdAt)}</p>
</CardFooter>
</Card>
))}
</div>
);
});
import React from "react";
import React, { useEffect } from "react";
import {
Modal,
ModalContent,
......@@ -8,38 +8,27 @@ import {
Button,
useDisclosure,
Input,
Avatar,
} from "@nextui-org/react";
import { AiFillPlusSquare } from "react-icons/ai";
import { useForm } from "react-hook-form";
import { doFetch } from "@/lib/doFetch";
import { useForm, Controller } from "react-hook-form";
import { delFetch, doFetch, putFetch } from "@/lib/doFetch";
import UploadImage from "./UploadImage";
import { BsTrash3Fill } from "react-icons/bs";
import { useRouter } from "next/navigation";
export default function AddFileInfo({refresh}) {
export default function DeleteFolder({ refresh, data }) {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit, control, setValue } = useForm();
const router = useRouter();
const handleButtonClick = async (close) => {
// 手动触发表单提交
handleSubmit(onSubmit)();
await refresh();
close();
await delFetch({url:"/api/folder/"+data.id})
router.back(); // 返回上一页
};
const onSubmit = async (data) => {
return await doFetch({ url: "/api/folder", params: data });
};
return (
<>
<Button
radius="full"
className="bg-gradient-to-tr from-green-500 to-blue-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<AiFillPlusSquare />
添加文件
<Button isIconOnly color="danger" aria-label="Like" onPress={onOpen}>
<BsTrash3Fill style={{ fontSize: "18px" }} />
</Button>
<Modal
isOpen={isOpen}
......@@ -70,37 +59,25 @@ export default function AddFileInfo({refresh}) {
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
添加文件
是否删除该文件夹
</ModalHeader>
<ModalBody>
<form action="">
<input type="hidden" {...register("poster")} />
<div className="flex justify-center items-center flex-col mb-8">
<UploadImage
control={control}
setValue={setValue}
></UploadImage>
</div>
<p>
仅可删除空文件夹
</p>
<Input
type="text"
label="文件夹"
name="name"
{...register("name", { required: true, maxLength: 20 })}
/>
</form>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
取消
</Button>
<Button
color="primary"
color="danger"
onPress={() => {
handleButtonClick(onClose);
}}
>
提交
删除
</Button>
</ModalFooter>
</>
......
import React from "react";
import {
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
Button,
useDisclosure,
Input,
Avatar,
Textarea,
} from "@nextui-org/react";
import { AiFillPlusSquare } from "react-icons/ai";
import { useForm } from "react-hook-form";
import { doFetch } from "@/lib/doFetch";
import UploadImage from "./UploadImage";
export default function AddCollection({ refresh, parentId, type }) {
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit, control, setValue } = useForm();
const handleButtonClick = async (close) => {
// 手动触发表单提交
handleSubmit(onSubmit)();
await refresh();
close();
};
const onSubmit = async (data) => {
return await doFetch({
url: "/api/collection",
params: { ...data, parentId:parentId ?parseInt(parentId): null },
});
};
return (
<>
{type === "icon" ? (
<Button
isIconOnly
color="primary"
variant="faded"
aria-label="Take a add"
onPress={onOpen}
>
<AiFillPlusSquare style={{ fontSize: "20px" }} />
</Button>
) : (
<Button
radius="full"
className="bg-gradient-to-tr from-green-500 to-blue-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<AiFillPlusSquare />
添加知识库
</Button>
)}
<Modal
isOpen={isOpen}
backdrop={"blur"}
onOpenChange={onOpenChange}
motionProps={{
variants: {
enter: {
y: 0,
opacity: 1,
transition: {
duration: 0.3,
ease: "easeOut",
},
},
exit: {
y: -20,
opacity: 0,
transition: {
duration: 0.2,
ease: "easeIn",
},
},
},
}}
>
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">
添加知识库
</ModalHeader>
<ModalBody>
<form action="" className="flex flex-col gap-4">
<Input
type="text"
label="知识库名称"
name="name"
isRequired
{...register("name", { required: true, maxLength: 20 })}
/>
<Input
type="text"
label="编码"
name="code"
{...register("code", { required: true, maxLength: 20 })}
/>
<Input
type="text"
label="故障类型"
name="faultType"
{...register("faultType", {
required: true,
maxLength: 20,
})}
/>
<Input
type="text"
label="故障"
name="fault"
{...register("fault", { required: true, maxLength: 20 })}
/>
<Textarea
type="text"
label="判断条件"
name="faultJudge"
{...register("faultJudge", {
required: true,
maxLength: 20,
})}
/>
<Textarea
type="text"
label="故障原因"
name="faultReason"
{...register("faultReason", {
required: true,
maxLength: 20,
})}
/>
<Textarea
type="text"
label="解决方案"
name="faultFn"
{...register("faultFn", { required: true, maxLength: 20 })}
/>
<Textarea
type="text"
label="故障描述"
name="faultMessage"
{...register("faultMessage", {
required: true,
maxLength: 20,
})}
/>
</form>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
取消
</Button>
<Button
color="primary"
onPress={() => {
handleButtonClick(onClose);
}}
>
提交
</Button>
</ModalFooter>
</>
)}
</ModalContent>
</Modal>
</>
);
}
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