feat: file move and delete endpoint
This commit is contained in:
parent
8fbeda892b
commit
07d97a9091
4 changed files with 520 additions and 44 deletions
|
|
@ -42,17 +42,11 @@ const io = new Server(server, {
|
|||
});
|
||||
|
||||
setInstance(io);
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log("User Connected");
|
||||
|
||||
socket.on("disconnected", () => {
|
||||
console.log("User Disconnected");
|
||||
});
|
||||
});
|
||||
io.on("connection", () => console.log("[Socket.IO] User connected."));
|
||||
io.on("disconnected", () => console.log("[Socket.IO] User disconnected."));
|
||||
|
||||
server.listen(PORT, "0.0.0.0", () =>
|
||||
console.log(`[APP] Application is running on http://localhost:${PORT}`),
|
||||
);
|
||||
|
||||
rabbitmq.init(amqHandler).catch((e) => console.error(e));
|
||||
// rabbitmq.init(amqHandler).catch((e) => console.error(e));
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import { Body, Controller, Delete, Example, Post, Put, Route, SuccessResponse } from "tsoa";
|
||||
import { Body, Controller, Delete, Example, Post, Put, Route, SuccessResponse, Tags } from "tsoa";
|
||||
|
||||
import minioClient from "../minio";
|
||||
import esClient from "../elasticsearch";
|
||||
|
||||
import HttpError from "../interfaces/http-error";
|
||||
import HttpStatusCode from "../interfaces/http-status";
|
||||
import { StorageFile, StorageFolder } from "../interfaces/storage-fs";
|
||||
|
||||
import { copyCond } from "../utils/minio";
|
||||
|
||||
if (!process.env.MINIO_BUCKET) throw Error("Default MinIO bucket must be specified.");
|
||||
|
|
@ -20,35 +23,73 @@ interface ListRequestBody {
|
|||
path: string[];
|
||||
}
|
||||
|
||||
interface CreateFolderBody {
|
||||
interface FolderBody {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2"] */
|
||||
path: string[];
|
||||
/** @example "แฟ้ม 3" */
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface PutFolderBody {
|
||||
from: {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2"] */
|
||||
path: string[];
|
||||
/** @example "แฟ้ม 3" */
|
||||
name: string;
|
||||
};
|
||||
to: {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2"] */
|
||||
path: string[];
|
||||
/** @example "แฟ้ม 3 แก้ไข" */
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface DeleteFolderBody {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2", "แฟ้ม 3 แก้ไข"] */
|
||||
path: string[];
|
||||
}
|
||||
|
||||
interface CreateFileBody {
|
||||
interface FileBody {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2", "แฟ้ม 3"] */
|
||||
path: string[];
|
||||
/** @example "ไฟล์ 1.xlsx" */
|
||||
file: string;
|
||||
/** @example "การเงิน" */
|
||||
title?: string;
|
||||
/** @example "การเงิน" */
|
||||
description?: string;
|
||||
/** @example ["การเงิน", "รายงาน"] */
|
||||
category?: string[];
|
||||
/** @example ["การเงิน", "รายรับ", "รายจ่าย"] */
|
||||
keyword?: string[];
|
||||
}
|
||||
|
||||
interface PutFileBody extends Omit<FileBody, "file" | "path"> {
|
||||
/** หากต้องการอัพโหลดไฟล์ด้วยให้ส่งค่าเป็นจริง */
|
||||
from: {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2", "แฟ้ม 3"] */
|
||||
path: string[];
|
||||
/** @example "ไฟล์ 1.xlsx" */
|
||||
file: string;
|
||||
};
|
||||
to?: {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2", "แฟ้ม 3"] */
|
||||
path: string[];
|
||||
/** @example "ไฟล์ 1 แก้ไข.xlsx" */
|
||||
file: string;
|
||||
};
|
||||
/** @example false */
|
||||
upload?: boolean;
|
||||
}
|
||||
|
||||
interface DeleteFileBody {
|
||||
/** @example ["แฟ้ม 1", "แฟ้ม 2", "แฟ้ม 3"] */
|
||||
path: string[];
|
||||
/** @example "ไฟล์ 1 แก้ไข.xlsx" */
|
||||
file: string;
|
||||
}
|
||||
|
||||
async function listFolder(path: string[]) {
|
||||
const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => {
|
||||
const item: { pathname: string; name: string }[] = [];
|
||||
|
|
@ -90,13 +131,9 @@ async function listFolder(path: string[]) {
|
|||
async function listFile(path: string[]) {
|
||||
const result = await esClient
|
||||
.search<StorageFile & { attachment: Record<string, string> }>({
|
||||
index: DEFAULT_INDEX!,
|
||||
index: DEFAULT_INDEX,
|
||||
sort: [{ pathname: "asc" }],
|
||||
query: {
|
||||
match: {
|
||||
path: path.join("/") + "/",
|
||||
},
|
||||
},
|
||||
query: { match: { path: path.join("/") + "/" } },
|
||||
size: 10000,
|
||||
})
|
||||
.then((r) => r.hits.hits);
|
||||
|
|
@ -114,8 +151,12 @@ async function listFile(path: string[]) {
|
|||
}
|
||||
|
||||
async function checkPathExist(bucket: string, path: string) {
|
||||
return await checkFileExist(bucket, `${path}/.keep`);
|
||||
}
|
||||
|
||||
async function checkFileExist(bucket: string, pathname: string) {
|
||||
return Boolean(
|
||||
await minioClient.statObject(bucket, `${path}/.keep`).catch((e) => {
|
||||
await minioClient.statObject(bucket, pathname).catch((e) => {
|
||||
if (e.code === "NotFound") return false;
|
||||
console.error(`Storage Error: ${e}`);
|
||||
throw new Error(MINIO_ERROR_MESSAGE);
|
||||
|
|
@ -158,6 +199,7 @@ export class StorageController extends Controller {
|
|||
updatedBy: "admin",
|
||||
},
|
||||
])
|
||||
@Tags("Storage Folder", "Storage File")
|
||||
public async getList(@Body() body: ListRequestBody) {
|
||||
const path = body.path.filter(Boolean);
|
||||
|
||||
|
|
@ -166,8 +208,9 @@ export class StorageController extends Controller {
|
|||
}
|
||||
|
||||
@Post("folder")
|
||||
@Tags("Storage Folder")
|
||||
@SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ")
|
||||
public async postFolder(@Body() body: CreateFolderBody) {
|
||||
public async postFolder(@Body() body: FolderBody) {
|
||||
const { path, name } = body;
|
||||
|
||||
if (!(await checkPathExist(DEFAULT_BUCKET, path.join("/")))) {
|
||||
|
|
@ -196,6 +239,8 @@ export class StorageController extends Controller {
|
|||
* ยา้ย Folder ภายใต้ Folder (Path) หนึ่ง ไปภายใน Folder (Path) หนึ่งและสามารถเปลี่ยนชื่อได้
|
||||
*/
|
||||
@Put("folder")
|
||||
@Tags("Storage Folder")
|
||||
@SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ")
|
||||
public async moveFolder(@Body() body: PutFolderBody) {
|
||||
const src = `${body.from.path.join("/")}/${body.from.name}`;
|
||||
const dst = `${body.to.path.join("/")}/${body.to.name}`;
|
||||
|
|
@ -284,6 +329,7 @@ export class StorageController extends Controller {
|
|||
* ลบ Folder หรือ File ออกจากระบบ
|
||||
*/
|
||||
@Delete("folder")
|
||||
@Tags("Storage Folder")
|
||||
@SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ")
|
||||
public async deleteStorage(@Body() body: DeleteFolderBody) {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
|
|
@ -304,8 +350,9 @@ export class StorageController extends Controller {
|
|||
* ร้องขอการอัพโหลดไฟล์ โดยเมื่อร้องขอจะได้ URL สำหรับอัพโหลดไฟล์มาพร้อมข้อมูลของไฟล์ที่จะทำการอัพโหลด
|
||||
*/
|
||||
@Post("file")
|
||||
@Tags("Storage File")
|
||||
@SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ")
|
||||
public async postFile(@Body() body: CreateFileBody) {
|
||||
public async postFile(@Body() body: FileBody) {
|
||||
const { path, file } = body;
|
||||
|
||||
if (!(await checkPathExist(DEFAULT_BUCKET, path.join("/")))) {
|
||||
|
|
@ -363,4 +410,131 @@ export class StorageController extends Controller {
|
|||
|
||||
return { ...metadata, uploadUrl: presignedUrl };
|
||||
}
|
||||
|
||||
@Put("file")
|
||||
@Tags("Storage File")
|
||||
@SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ")
|
||||
public async moveFile(@Body() body: PutFileBody) {
|
||||
const search = await esClient
|
||||
.search<StorageFile & { attachment: Record<string, any> }>({
|
||||
index: DEFAULT_INDEX,
|
||||
query: {
|
||||
match: { pathname: body.from.path.join("/") + `/${body.from.file}` },
|
||||
},
|
||||
})
|
||||
.catch((e) => console.error(`ElasticSearch Error: ${e}`));
|
||||
|
||||
if (!search) {
|
||||
throw new Error("เกิดข้อผิดพลาดกับระบบฐานข้อมูล กรุณาลองใหม่ในภายหลัง");
|
||||
}
|
||||
if (search && search.hits.hits.length === 0) {
|
||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบไฟล์ดังกล่าว");
|
||||
}
|
||||
if (!(await checkFileExist(DEFAULT_BUCKET, body.from.path.join("/") + `/${body.from.file}`))) {
|
||||
await esClient.delete({
|
||||
index: DEFAULT_INDEX,
|
||||
id: search.hits.hits[0]._id,
|
||||
});
|
||||
throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่พบไฟล์ดังกล่าว");
|
||||
}
|
||||
if (body.to && !(await checkPathExist(DEFAULT_BUCKET, body.to.path.join("/")))) {
|
||||
throw new HttpError(HttpStatusCode.PRECONDITION_FAILED, "ไม่พบตำแหน่งที่ต้องการย้าย");
|
||||
}
|
||||
if (
|
||||
body.to &&
|
||||
(await checkFileExist(DEFAULT_BUCKET, body.to.path.join("/") + `/${body.to.file}`))
|
||||
) {
|
||||
throw new HttpError(
|
||||
HttpStatusCode.PRECONDITION_FAILED,
|
||||
"พบไฟล์ในต้ำแหน่งปลายทาง ไม่สามารถย้ายได้",
|
||||
);
|
||||
}
|
||||
if (!search.hits.hits[0]._source) {
|
||||
// This should not possible.
|
||||
// Just in case the result found with no associated data.
|
||||
await esClient.delete({
|
||||
index: DEFAULT_INDEX,
|
||||
id: search.hits.hits[0]._id,
|
||||
});
|
||||
throw new Error("ไม่พบข้อมูลในฐานข้อมูล");
|
||||
}
|
||||
|
||||
const id = search.hits.hits[0]._id;
|
||||
|
||||
const { to, from, upload, ...metadata } = body;
|
||||
|
||||
if (from && to) {
|
||||
const src = [DEFAULT_BUCKET, ...from.path, ""].join("/") + from.file;
|
||||
const dst = to.path.join("/") + `/${to.file}`;
|
||||
|
||||
const result = await minioClient.copyObject(DEFAULT_BUCKET, dst, src, copyCond).catch((e) => {
|
||||
console.error(`MinIO Error: ${e}`);
|
||||
throw new Error("เกิดข้อผิดพลาด ไม่สามารถย้ายไฟล์ได้");
|
||||
});
|
||||
|
||||
if (result) {
|
||||
await esClient
|
||||
.update({
|
||||
index: DEFAULT_INDEX,
|
||||
id: id,
|
||||
doc: {
|
||||
...metadata,
|
||||
path: to.path.join("/") + "/",
|
||||
pathname: dst,
|
||||
updatedAt: new Date().toISOString(),
|
||||
updatedBy: "n/a",
|
||||
},
|
||||
refresh: "wait_for",
|
||||
})
|
||||
.then(async () => await minioClient.removeObject(DEFAULT_INDEX, src))
|
||||
.catch((e) => console.error(`ElasticSearch Error: ${e}`));
|
||||
|
||||
if (upload) {
|
||||
const presignedUrl = await minioClient.presignedPutObject(DEFAULT_BUCKET, dst);
|
||||
return { uploadUrl: presignedUrl };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (from) {
|
||||
await esClient
|
||||
.update({
|
||||
index: DEFAULT_INDEX,
|
||||
id: id,
|
||||
doc: {
|
||||
...metadata,
|
||||
updatedAt: new Date().toISOString(),
|
||||
updatedBy: "n/a",
|
||||
},
|
||||
refresh: "wait_for",
|
||||
})
|
||||
.catch((e) => console.error(`ElasticSearch Error: ${e}`));
|
||||
if (upload) {
|
||||
const src = from.path.join("/") + `/${from.file}`;
|
||||
const presignedUrl = await minioClient.presignedPutObject(DEFAULT_BUCKET, src);
|
||||
return { uploadUrl: presignedUrl };
|
||||
}
|
||||
}
|
||||
|
||||
return this.setStatus(HttpStatusCode.NO_CONTENT);
|
||||
}
|
||||
|
||||
@Delete("file")
|
||||
@Tags("Storage File")
|
||||
@SuccessResponse(HttpStatusCode.NO_CONTENT, "สำเร็จ")
|
||||
public async deleteFile(@Body() body: DeleteFileBody) {
|
||||
const pathname = body.path.join("/") + body.file;
|
||||
|
||||
await minioClient
|
||||
.removeObject(DEFAULT_BUCKET, pathname)
|
||||
.catch((e) => console.error(`MinIO Error: ${e}`));
|
||||
await esClient
|
||||
.deleteByQuery({
|
||||
index: DEFAULT_INDEX,
|
||||
query: { match: { pathname } },
|
||||
})
|
||||
.catch((e) => console.error(`ElasticSearch Error: ${e}`));
|
||||
|
||||
return this.setStatus(HttpStatusCode.NO_CONTENT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ const models: TsoaRoute.Models = {
|
|||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
"CreateFolderBody": {
|
||||
"FolderBody": {
|
||||
"dataType": "refObject",
|
||||
"properties": {
|
||||
"path": {"dataType":"array","array":{"dataType":"string"},"required":true},
|
||||
|
|
@ -102,7 +102,7 @@ const models: TsoaRoute.Models = {
|
|||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
"CreateFileBody": {
|
||||
"FileBody": {
|
||||
"dataType": "refObject",
|
||||
"properties": {
|
||||
"path": {"dataType":"array","array":{"dataType":"string"},"required":true},
|
||||
|
|
@ -115,6 +115,29 @@ const models: TsoaRoute.Models = {
|
|||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
"PutFileBody": {
|
||||
"dataType": "refObject",
|
||||
"properties": {
|
||||
"title": {"dataType":"string"},
|
||||
"description": {"dataType":"string"},
|
||||
"category": {"dataType":"array","array":{"dataType":"string"}},
|
||||
"keyword": {"dataType":"array","array":{"dataType":"string"}},
|
||||
"from": {"dataType":"nestedObjectLiteral","nestedProperties":{"file":{"dataType":"string","required":true},"path":{"dataType":"array","array":{"dataType":"string"},"required":true}},"required":true},
|
||||
"to": {"dataType":"nestedObjectLiteral","nestedProperties":{"file":{"dataType":"string","required":true},"path":{"dataType":"array","array":{"dataType":"string"},"required":true}}},
|
||||
"upload": {"dataType":"boolean"},
|
||||
},
|
||||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
"DeleteFileBody": {
|
||||
"dataType": "refObject",
|
||||
"properties": {
|
||||
"path": {"dataType":"array","array":{"dataType":"string"},"required":true},
|
||||
"file": {"dataType":"string","required":true},
|
||||
},
|
||||
"additionalProperties": false,
|
||||
},
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
};
|
||||
const validationService = new ValidationService(models);
|
||||
|
||||
|
|
@ -737,7 +760,7 @@ export function RegisterRoutes(app: Router) {
|
|||
|
||||
function StorageController_postFolder(request: any, response: any, next: any) {
|
||||
const args = {
|
||||
body: {"in":"body","name":"body","required":true,"ref":"CreateFolderBody"},
|
||||
body: {"in":"body","name":"body","required":true,"ref":"FolderBody"},
|
||||
};
|
||||
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
|
|
@ -775,7 +798,7 @@ export function RegisterRoutes(app: Router) {
|
|||
|
||||
|
||||
const promise = controller.moveFolder.apply(controller, validatedArgs as any);
|
||||
promiseHandler(controller, promise, response, undefined, next);
|
||||
promiseHandler(controller, promise, response, 204, next);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
|
@ -812,7 +835,7 @@ export function RegisterRoutes(app: Router) {
|
|||
|
||||
function StorageController_postFile(request: any, response: any, next: any) {
|
||||
const args = {
|
||||
body: {"in":"body","name":"body","required":true,"ref":"CreateFileBody"},
|
||||
body: {"in":"body","name":"body","required":true,"ref":"FileBody"},
|
||||
};
|
||||
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
|
|
@ -831,6 +854,56 @@ export function RegisterRoutes(app: Router) {
|
|||
}
|
||||
});
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
app.put('/storage/file',
|
||||
...(fetchMiddlewares<RequestHandler>(StorageController)),
|
||||
...(fetchMiddlewares<RequestHandler>(StorageController.prototype.moveFile)),
|
||||
|
||||
function StorageController_moveFile(request: any, response: any, next: any) {
|
||||
const args = {
|
||||
body: {"in":"body","name":"body","required":true,"ref":"PutFileBody"},
|
||||
};
|
||||
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
|
||||
let validatedArgs: any[] = [];
|
||||
try {
|
||||
validatedArgs = getValidatedArgs(args, request, response);
|
||||
|
||||
const controller = new StorageController();
|
||||
|
||||
|
||||
const promise = controller.moveFile.apply(controller, validatedArgs as any);
|
||||
promiseHandler(controller, promise, response, 204, next);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
});
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
app.delete('/storage/file',
|
||||
...(fetchMiddlewares<RequestHandler>(StorageController)),
|
||||
...(fetchMiddlewares<RequestHandler>(StorageController.prototype.deleteFile)),
|
||||
|
||||
function StorageController_deleteFile(request: any, response: any, next: any) {
|
||||
const args = {
|
||||
body: {"in":"body","name":"body","required":true,"ref":"DeleteFileBody"},
|
||||
};
|
||||
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
|
||||
let validatedArgs: any[] = [];
|
||||
try {
|
||||
validatedArgs = getValidatedArgs(args, request, response);
|
||||
|
||||
const controller = new StorageController();
|
||||
|
||||
|
||||
const promise = controller.deleteFile.apply(controller, validatedArgs as any);
|
||||
promiseHandler(controller, promise, response, 204, next);
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
});
|
||||
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
||||
app.get('/cabinet/:cabinetName/drawer/:drawerName/folder/:folderName/subfolder',
|
||||
authenticateMiddleware([{"bearerAuth":[]}]),
|
||||
...(fetchMiddlewares<RequestHandler>(SubFolderController)),
|
||||
|
|
|
|||
|
|
@ -198,16 +198,21 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CreateFolderBody": {
|
||||
"FolderBody": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "แฟ้ม 3"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -222,13 +227,18 @@
|
|||
"from": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "แฟ้ม 3"
|
||||
},
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -240,13 +250,18 @@
|
|||
"to": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "แฟ้ม 3 แก้ไข"
|
||||
},
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -269,7 +284,12 @@
|
|||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2",
|
||||
"แฟ้ม 3 แก้ไข"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -278,34 +298,167 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"CreateFileBody": {
|
||||
"FileBody": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2",
|
||||
"แฟ้ม 3"
|
||||
]
|
||||
},
|
||||
"file": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "ไฟล์ 1.xlsx"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "การเงิน"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"example": "การเงิน"
|
||||
},
|
||||
"category": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"การเงิน",
|
||||
"รายงาน"
|
||||
]
|
||||
},
|
||||
"keyword": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
"type": "array",
|
||||
"example": [
|
||||
"การเงิน",
|
||||
"รายรับ",
|
||||
"รายจ่าย"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"file"
|
||||
],
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"PutFileBody": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"example": "การเงิน"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"example": "การเงิน"
|
||||
},
|
||||
"category": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"example": [
|
||||
"การเงิน",
|
||||
"รายงาน"
|
||||
]
|
||||
},
|
||||
"keyword": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"example": [
|
||||
"การเงิน",
|
||||
"รายรับ",
|
||||
"รายจ่าย"
|
||||
]
|
||||
},
|
||||
"from": {
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"example": "ไฟล์ 1.xlsx"
|
||||
},
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2",
|
||||
"แฟ้ม 3"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file",
|
||||
"path"
|
||||
],
|
||||
"type": "object",
|
||||
"description": "หากต้องการอัพโหลดไฟล์ด้วยให้ส่งค่าเป็นจริง"
|
||||
},
|
||||
"to": {
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"example": "ไฟล์ 1 แก้ไข.xlsx"
|
||||
},
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2",
|
||||
"แฟ้ม 3"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"upload": {
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from"
|
||||
],
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
},
|
||||
"DeleteFileBody": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"example": [
|
||||
"แฟ้ม 1",
|
||||
"แฟ้ม 2",
|
||||
"แฟ้ม 3"
|
||||
]
|
||||
},
|
||||
"file": {
|
||||
"type": "string",
|
||||
"example": "ไฟล์ 1 แก้ไข.xlsx"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -1875,6 +2028,10 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Storage Folder",
|
||||
"Storage File"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
|
|
@ -1897,6 +2054,9 @@
|
|||
"description": "สำเร็จ"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Storage Folder"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
|
|
@ -1904,7 +2064,7 @@
|
|||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateFolderBody"
|
||||
"$ref": "#/components/schemas/FolderBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1914,10 +2074,13 @@
|
|||
"operationId": "MoveFolder",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "No content"
|
||||
"description": "สำเร็จ"
|
||||
}
|
||||
},
|
||||
"description": "ยา้ย Folder ภายใต้ Folder (Path) หนึ่ง ไปภายใน Folder (Path) หนึ่งและสามารถเปลี่ยนชื่อได้",
|
||||
"tags": [
|
||||
"Storage Folder"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
|
|
@ -1939,6 +2102,9 @@
|
|||
}
|
||||
},
|
||||
"description": "ลบ Folder หรือ File ออกจากระบบ",
|
||||
"tags": [
|
||||
"Storage Folder"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
|
|
@ -2056,6 +2222,9 @@
|
|||
}
|
||||
},
|
||||
"description": "ร้องขอการอัพโหลดไฟล์ โดยเมื่อร้องขอจะได้ URL สำหรับอัพโหลดไฟล์มาพร้อมข้อมูลของไฟล์ที่จะทำการอัพโหลด",
|
||||
"tags": [
|
||||
"Storage File"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
|
|
@ -2063,7 +2232,73 @@
|
|||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CreateFileBody"
|
||||
"$ref": "#/components/schemas/FileBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"operationId": "MoveFile",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "สำเร็จ",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"anyOf": [
|
||||
{},
|
||||
{
|
||||
"properties": {
|
||||
"uploadUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"uploadUrl"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Storage File"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/PutFileBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"operationId": "DeleteFile",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "สำเร็จ"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"Storage File"
|
||||
],
|
||||
"security": [],
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/DeleteFileBody"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue