-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
yanghua
committed
Jan 30, 2025
1 parent
5107b63
commit a636b82
Showing
6 changed files
with
231 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package resource | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
"io" | ||
|
||
"github.com/gofiber/fiber/v2" | ||
"github.com/google/uuid" | ||
"github.com/kehuay/aimemos/store" | ||
) | ||
|
||
// 定义类型 | ||
|
||
type ResourceCreate struct { | ||
Data []byte `json:"data"` | ||
Type string `json:"type"` | ||
Id uuid.UUID `json:"id,omitempty"` | ||
} | ||
|
||
// 定义函数 | ||
|
||
func NewResourceApi(group fiber.Router) fiber.Router { | ||
resourceApi := group.Group("/resource") | ||
|
||
// 新建 | ||
resourceApi.Post("", createResource) | ||
resourceApi.Get("/:id", getResource) | ||
|
||
return resourceApi | ||
} | ||
|
||
func createResource(c *fiber.Ctx) error { | ||
|
||
resourceCreate := ResourceCreate{} | ||
|
||
resourceCreate.Type = c.FormValue("type") | ||
|
||
file, err := c.FormFile("files") | ||
|
||
if err != nil { | ||
return errors.New("文件内容不存在") | ||
} | ||
|
||
reader, err := file.Open() | ||
if err != nil { | ||
return errors.New("文件打开失败") | ||
} | ||
defer reader.Close() | ||
|
||
buff := new(bytes.Buffer) | ||
|
||
_, err = io.Copy(buff, reader) | ||
|
||
if err != nil { | ||
return errors.New("文件读取失败") | ||
} | ||
|
||
resourceCreate.Data = buff.Bytes() | ||
|
||
// log.Println(file.Size) | ||
// log.Println(n) | ||
|
||
resourceCreate.Id = uuid.New() | ||
|
||
_store := c.Locals("store").(*store.Store) | ||
|
||
_, err = store.CreateResource(store.Resource{ | ||
Id: resourceCreate.Id, | ||
Type: resourceCreate.Type, | ||
Data: resourceCreate.Data, | ||
}, *_store) | ||
|
||
// log.Println(resourceCreate) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.JSON(fiber.Map{ | ||
"code": 1000, | ||
"data": fiber.Map{ | ||
"id": resourceCreate.Id, | ||
"url": fmt.Sprintf("/api/resource/%s", resourceCreate.Id), | ||
}, | ||
}) | ||
} | ||
|
||
func getResource(c *fiber.Ctx) error { | ||
id := c.Params("id") | ||
|
||
_store := c.Locals("store").(*store.Store) | ||
|
||
resource, err := store.QueryResource(id, *_store) | ||
|
||
// log.Println(resource) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
c.Set("content-type", "image/png") | ||
|
||
return c.Send(resource.Data) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package store | ||
|
||
import ( | ||
"github.com/google/uuid" | ||
) | ||
|
||
type Resource struct { | ||
Id uuid.UUID `json:"id"` | ||
Type string `json:"type"` | ||
Data []byte `json:"data"` | ||
} | ||
|
||
func CreateResource(resource Resource, store Store) (Resource, error) { | ||
|
||
err := store.db.QueryRow( | ||
"insert into resources (id, type, data) values ($1, $2, $3) returning id, type, data", | ||
resource.Id, | ||
resource.Type, | ||
resource.Data, | ||
).Scan(&resource.Id, &resource.Type, &resource.Data) | ||
|
||
return resource, err | ||
} | ||
|
||
func QueryResource(id string, store Store) (Resource, error) { | ||
resource := Resource{} | ||
|
||
err := store.db.QueryRow( | ||
"select id,type,data from resources where id = $1;", | ||
id, | ||
).Scan(&resource.Id, &resource.Type, &resource.Data) | ||
|
||
if err != nil { | ||
return resource, err | ||
} | ||
|
||
return resource, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { RequestCode } from "." | ||
|
||
export async function createResource(file: File) { | ||
const formData = new FormData() | ||
|
||
formData.append("type", "image") | ||
formData.append("files", file) | ||
|
||
const response = await fetch("/api/resource", { | ||
method: 'POST', | ||
body: formData | ||
}) | ||
|
||
if (!response.ok) { | ||
return { | ||
code: RequestCode.REQUEST_ERROR | ||
} | ||
} | ||
|
||
const data = await response.json() | ||
|
||
return data | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,74 @@ | ||
<script setup lang="ts"> | ||
import {GridIcon,ListIcon} from "lucide-vue-next" | ||
import { GridIcon, ImageUpIcon, ListIcon } from "lucide-vue-next" | ||
import { ref } from "vue"; | ||
import { createResource } from "../../api/resource"; | ||
import { RequestCode } from "../../api"; | ||
// const isOpened = ref(false) | ||
const inputRef = ref<HTMLInputElement>() | ||
const resourceList = ref<{ | ||
url: string, | ||
id: string | ||
}[]>([]) | ||
function onUploadClicked() { | ||
// if (isOpened.value) { | ||
// return | ||
// } | ||
// isOpened.value = true | ||
inputRef.value?.click() | ||
} | ||
async function onUploadInput() { | ||
// isOpened.value = false | ||
const file = inputRef.value?.files?.[0] | ||
if (!file) { | ||
return | ||
} | ||
// 上传 | ||
const data = await createResource(file) | ||
console.log(data) | ||
if (data.code != RequestCode.REQUEST_SUCCESS) { | ||
return | ||
} | ||
resourceList.value = [{ | ||
url: data.data.url, | ||
id: data.data.id | ||
}, ...resourceList.value] | ||
} | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<div class="max-w-768px mx-auto"> | ||
<div>资源库</div> | ||
<div class="flex items-center justify-center"> | ||
<div class="flex gap-8px border-1px p-4px rounded-4px"> | ||
<!-- 上传区域 --> | ||
<div class="w-full h-200px p-16px relative mt-16px"> | ||
<input ref="inputRef" @input="onUploadInput" class="w-full h-full border-1px rounded-8px" type="file" | ||
accept="image/*" /> | ||
<div @click="onUploadClicked" | ||
class="w-full h-full cursor-pointer border-1px rounded-8px flex flex-col items-center justify-center absolute top-0 left-0 p-16px bg-white"> | ||
<ImageUpIcon :size="64" class="text-#cacaca" /> | ||
<div class="text-#cacaca">点击或拖拽上传资源</div> | ||
</div> | ||
</div> | ||
<div class="flex mt-16px items-center justify-start"> | ||
<div class="ml-auto flex gap-8px border-1px p-4px rounded-4px"> | ||
<GridIcon class="cursor-pointer" :size="16" /> | ||
<ListIcon class="cursor-pointer" :size="16" /> | ||
</div> | ||
<div class="ml-auto bg-green px-1em py-0.25em rounded-0.25em">上传</div> | ||
<!-- <div class="ml-auto bg-green px-1em py-0.25em rounded-0.25em">上传</div> --> | ||
</div> | ||
<div class="mt-20px flex flex-wrap gap-x-8px gap-y-16px"> | ||
<div class="grow-1" v-for="index in 30" :key="index"> | ||
<img class="w-full rounded-8px" :src="`https://picsum.photos/200/120?r=${index}`" /> | ||
<div class="text-center">图片{{ index }}</div> | ||
<div class="mt-16px flex flex-wrap gap-x-8px gap-y-16px"> | ||
<div class="w-200px h-120px" v-for="resource in resourceList" :key="resource.id"> | ||
<img class="w-full h-full border-(1px solid #aaaaaa) rounded-8px object-cover" :src="resource.url" /> | ||
<!-- <div class="text-center">图片{{ resource.id }}</div> --> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|