Commit 7823a1b1 authored by wuhao's avatar wuhao 🎯

upload

parent d49c4cf1
......@@ -5,3 +5,4 @@
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="mysql://root:admin123@localhost:3306/llm-train"
API_URL="http://localhost:3000"
\ No newline at end of file
......@@ -13,15 +13,20 @@
"prisma-studio": "prisma studio"
},
"dependencies": {
"@ant-design/icons": "^5.3.6",
"@nextui-org/react": "^2.2.10",
"@prisma/client": "^5.11.0",
"ahooks": "^3.7.10",
"antd": "^5.16.0",
"formidable": "^3.5.1",
"framer-motion": "^11.0.23",
"next": "14.1.4",
"prisma": "^5.11.0",
"react": "^18",
"react-dom": "^18",
"react-icons": "^5.0.1"
"react-hook-form": "^7.51.2",
"react-icons": "^5.0.1",
"umi-request": "^1.4.0"
},
"devDependencies": {
"autoprefixer": "^10.0.1",
......
......@@ -16,6 +16,7 @@ datasource db {
model Folder {
id Int @id @default(autoincrement())
name String @unique
created DateTime?
updated DateTime?
poster String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
\ No newline at end of file
......@@ -17,14 +17,16 @@ export function Providers({ children }) {
return (
<NextUIProvider navigate={router.push}>
{/* <div className="flex w-full flex-col">
<Tabs aria-label="Options" selectedKey={pathname}>
<Tab key="/" title={<Link href="/">首页</Link>}></Tab>
<Tab key="/dashboard" title={<Link href="/dashboard">DOC</Link>}></Tab>
<div className="flex w-full flex-col mb-4">
<Tabs aria-label="Options" radius={'full'} color="primary" selectedKey={pathname} onSelectionChange={(key)=>{
router.push(key)
}}>
<Tab key="/" title={'首页'}></Tab>
<Tab key="/addItem" title={'DOC'}></Tab>
</Tabs>
</div> */}
<Link href="/">首页</Link>
<Link href="/addItem">DOC</Link>
</div>
{/* <Link href="/">首页</Link>
<Link href="/addItem">DOC</Link> */}
{children}
</NextUIProvider>
);
......
import React from "react";
import {Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button, useDisclosure} from "@nextui-org/react";
import {
Modal,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
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 UploadImage from "./UploadImage";
export default function AddFolder() {
const {isOpen, onOpen, onOpenChange} = useDisclosure();
const { isOpen, onOpen, onOpenChange } = useDisclosure();
const { register, handleSubmit } = useForm();
const handleButtonClick = (close) => {
// 手动触发表单提交
handleSubmit(onSubmit)();
};
const onSubmit = async (data) => {
// 提交表单数据
console.log(data);
let res = await doFetch({ url: "/api/folder", params: data });
console.log("====================================");
console.log(res);
console.log("====================================");
};
return (
<>
<Button
radius="full"
className="bg-gradient-to-tr from-pink-500 to-yellow-500 text-white shadow-lg"
className="bg-gradient-to-tr from-pink-500 to-yellow-500 text-white shadow-lg mb-4"
onPress={onOpen}
>
<AiFillPlusSquare />
......@@ -19,32 +47,34 @@ export default function AddFolder() {
<ModalContent>
{(onClose) => (
<>
<ModalHeader className="flex flex-col gap-1">Modal Title</ModalHeader>
<ModalHeader className="flex flex-col gap-1">
添加文件夹
</ModalHeader>
<ModalBody>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam pulvinar risus non risus hendrerit venenatis.
Pellentesque sit amet hendrerit risus, sed porttitor quam.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam pulvinar risus non risus hendrerit venenatis.
Pellentesque sit amet hendrerit risus, sed porttitor quam.
</p>
<p>
Magna exercitation reprehenderit magna aute tempor cupidatat consequat elit
dolor adipisicing. Mollit dolor eiusmod sunt ex incididunt cillum quis.
Velit duis sit officia eiusmod Lorem aliqua enim laboris do dolor eiusmod.
Et mollit incididunt nisi consectetur esse laborum eiusmod pariatur
proident Lorem eiusmod et. Culpa deserunt nostrud ad veniam.
</p>
<form action="">
<div className="flex justify-center items-center flex-col mb-8">
<UploadImage></UploadImage>
</div>
<Input
type="text"
label="文件夹"
name="name"
{...register("name", { required: true, maxLength: 20 })}
/>
</form>
</ModalBody>
<ModalFooter>
<Button color="danger" variant="light" onPress={onClose}>
Close
取消
</Button>
<Button color="primary" onPress={onClose}>
Action
<Button
color="primary"
onPress={() => {
handleButtonClick(onClose);
}}
>
提交
</Button>
</ModalFooter>
</>
......
import React, { useState } from 'react';
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
import { message, Upload } from 'antd';
import { Image } from "@nextui-org/react";
const getBase64 = (img, callback) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
};
const beforeUpload = (file) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('You can only upload JPG/PNG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
return isJpgOrPng && isLt2M;
};
const UploadImage = () => {
const [loading, setLoading] = useState(false);
const [imageUrl, setImageUrl] = useState();
const handleChange = (info) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, (url) => {
setLoading(false);
setImageUrl(url);
});
}
};
const uploadButton = (
<button
style={{
border: 0,
background: 'none',
}}
type="button"
>
{loading ? <LoadingOutlined /> : <PlusOutlined />}
<div
style={{
marginTop: 8,
}}
>
封面
</div>
</button>
);
return (
<>
<Upload
name="file"
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
action="/api/upload"
beforeUpload={beforeUpload}
onChange={handleChange}
>
{imageUrl ? (
<Image
src={imageUrl}
alt="avatar"
style={{
width: '100%',
}}
/>
) : (
uploadButton
)}
</Upload>
</>
);
};
export default UploadImage;
\ No newline at end of file
import request from "umi-request";
export const doFetch = ({ url, params }) => {
return request(url, {
method: "POST",
data: params ?? {},
});
};
export const putFetch = ({ url, params }) => {
return request(url, {
method: "PUT",
data: params ?? {},
});
};
export const delFetch = ({ url, params }) => {
return request(url, {
method: "DELETE",
data: params ?? {},
});
};
export const getFetch = ({ url, params }) => {
return request(url, {
method: "GET",
params: params ?? {},
});
};
export default function handler(req, res) {
const {
query: { id },
body,
method,
} = req;
switch (method) {
case "GET":
res.status(200).json({ id, name: `User ${id}` });
break;
case "PUT":
// Update user with id
res.status(200).json({ id, message: `User ${id} updated` });
break;
case "DELETE":
// Delete user with id
res.status(200).json({ id, message: `User ${id} deleted` });
break;
default:
res.setHeader("Allow", ["GET", "PUT", "DELETE"]);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
import prisma from "@/lib/prisma";
export default async function handler(req, res) {
const {
query, //query ?a=1 转为{a:1} 结构为{a}
body,
method,
} = req;
switch (method) {
case "GET":
const folders = await prisma.folder.findMany({
// where: { published: true },
// include: {
// author: {
// select: { name: true },
// },
// },
});
res.status(200).json({
code: 0,
data: folders,
success: true,
});
break;
case "POST":
console.log("====================================");
console.log(body);
console.log("====================================");
const created = await prisma.folder.create({
data:body
});
res.status(200).json({ name: `User ` });
break;
default:
res.setHeader("Allow", ["GET", "PUT", "DELETE"]);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
// pages/api/upload.js
import fs from "fs";
import path from "path";
import formidable from "formidable";
export default async function handler(req, res) {
if (req.method === "POST") {
const form = formidable({});
console.log('====================================');
console.log(form);
console.log('====================================');
res.status(200).json({data:"sad"});
} else {
res.status(405).end(`Method ${method} Not Allowed`);
}
}
This diff is collapsed.
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