refactor: input keyword / category

This commit is contained in:
Methapon2001 2023-12-01 10:55:36 +07:00
parent 7b894383da
commit cbc867c8e3
No known key found for this signature in database
GPG key ID: 849924FEF46BD132
6 changed files with 514 additions and 401 deletions

View file

@ -2,6 +2,7 @@ import {
Body,
Controller,
Delete,
Example,
Get,
Patch,
Path,
@ -31,10 +32,33 @@ if (!DEFAULT_INDEX) throw Error("Default ElasticSearch index must be specified."
@Route("/cabinet/{cabinetName}/drawer/{drawerName}/folder/{folderName}/file")
export class FileController extends Controller {
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
*/
@Get("/")
@Tags("ไฟล์")
@Security("bearerAuth")
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
@Example([
{
pathname: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/เอกสาร 1",
path: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/",
title: "เอกสาร",
description: "เอกสารการเงิน",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
upload: false,
fileName: "เอกสาร 1",
fileSize: 10240,
fileType: "application/pdf",
createdAt: "2021-07-20T12:33:13.018Z",
createdBy: "admin",
updatedAt: "2021-07-20T12:33:13.018Z",
updatedBy: "admin",
},
])
public async getFile(
@Path() cabinetName: string,
@Path() drawerName: string,
@ -62,6 +86,11 @@ export class FileController extends Controller {
return records;
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
*/
@Post("/")
@Tags("ไฟล์")
@Security("bearerAuth", ["admin"])
@ -70,15 +99,46 @@ export class FileController extends Controller {
"ตำแหน่งที่ระบุไม่พบ กรุณาเตรียมตำแหน่งที่ต้องการก่อนดำเนินการ",
)
@SuccessResponse(HttpStatusCode.CREATED, "สำเร็จ")
@Example({
pathname: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/เอกสาร 1",
path: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/",
title: "เอกสาร",
description: "เอกสารการเงิน",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
upload: false,
fileName: "เอกสาร 1",
fileSize: 10240,
fileType: "application/pdf",
createdAt: "2021-07-20T12:33:13.018Z",
createdBy: "admin",
updatedAt: "2021-07-20T12:33:13.018Z",
updatedBy: "admin",
})
public async uploadFile(
@Request() request: { user: { preferred_username: string } },
@Body()
body: {
/**
* @example "เอกสาร 1"
*/
file: string;
/**
* @example "เอกสาร"
*/
title?: string;
/**
* @example "เอกสารการเงิน"
*/
description?: string;
category?: string;
keyword?: string;
/**
* @example ["บัญชี"]
*/
category?: string[];
/**
* @example ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"]
*/
keyword?: string[];
},
@Path() cabinetName: string,
@Path() drawerName: string,
@ -125,8 +185,8 @@ export class FileController extends Controller {
fileType: "",
title: body.title ?? "",
description: body.description ?? "",
category: body.category?.split(",") ?? [],
keyword: body.keyword?.split(",") ?? [],
category: body.category ?? [],
keyword: body.keyword ?? [],
upload: false,
createdAt: new Date().toISOString(),
createdBy: rec ? rec.createdBy : "n/a",
@ -150,6 +210,12 @@ export class FileController extends Controller {
};
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example fileName "เอกสาร 1"
*/
@Patch("/{fileName}")
@Tags("ไฟล์")
@Security("bearerAuth", ["admin"])
@ -164,11 +230,26 @@ export class FileController extends Controller {
@Path() fileName: string,
@Body()
body: {
/**
* @example "เอกสารใหม่"
*/
file?: string;
/**
* @example "เอกสารการเงิน"
*/
title?: string;
/**
* @example "เอกสารการเงินฉบับใหม่"
*/
description?: string;
category?: string;
keyword?: string;
/**
* @example ["บัญชี"]
*/
category?: string[];
/**
* @example ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"]
*/
keyword?: string[];
},
): Promise<void | { upload: string }> {
if (body.file && body.file.length > 85) {
@ -238,8 +319,6 @@ export class FileController extends Controller {
id,
doc: {
...body,
keyword: body.keyword?.split(","),
category: body.category?.split(","),
updatedAt: new Date().toISOString(),
updatedBy: request.user.preferred_username ?? "n/a",
},
@ -258,6 +337,12 @@ export class FileController extends Controller {
: this.setStatus(HttpStatusCode.NO_CONTENT);
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example fileName "เอกสารใหม่"
*/
@Delete("/{fileName}")
@Tags("ไฟล์")
@Security("bearerAuth", ["admin"])
@ -275,6 +360,12 @@ export class FileController extends Controller {
return this.setStatus(HttpStatusCode.NO_CONTENT);
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example fileName "เอกสารใหม่"
*/
@Get("/{fileName}")
@Tags("ดาวน์โหลด")
@Security("bearerAuth")

View file

@ -1,104 +0,0 @@
import { Body, Controller, Get, Path, Post, Put, Query, Route, SuccessResponse } from "tsoa";
import { replaceIllegalChars } from "../utils/minio";
import minioClient from "../minio";
import HttpStatusCode from "../interfaces/http-status";
import HttpError from "../interfaces/http-error";
const DEFAULT_BUCKET = process.env.MINIO_BUCKET;
const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX;
if (!DEFAULT_BUCKET) throw Error("Default MinIO bucket must be specified.");
if (!DEFAULT_INDEX) throw Error("Default ElasticSearch index must be specified.");
@Route("/storage/d")
export class StorageController extends Controller {
@Get()
@SuccessResponse(HttpStatusCode.OK, "Success")
public async getFolder(@Query() path: string, @Query() bucket?: string) {
const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => {
const item: { pathname: string; name: string }[] = [];
const stream = minioClient.listObjectsV2(bucket ?? DEFAULT_BUCKET!, path);
stream.on("data", (v) => {
if (v && v.prefix) {
item.push({
pathname: v.prefix,
name: v.prefix.slice(path?.length).split("/")[0],
});
}
});
stream.on("end", () => resolve(item));
stream.on("error", () => reject(new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์")));
});
return list;
}
@Post()
@SuccessResponse(HttpStatusCode.CREATED, "Success")
public async createFolder(@Query() path: string, @Query() bucket?: string) {
const fragments = path.split("/").filter(Boolean);
await Promise.all(
fragments.map(async (_, i, a) => {
const path = [...a.slice(0, i + 1)].map((x) => replaceIllegalChars(x)).join("/");
const created = await minioClient
.putObject(bucket ?? DEFAULT_BUCKET!, `${path}/.keep`, "", 0)
.catch((e) => console.error(e));
if (!created) throw new Error("เกิดข้อผิดพลาดกับระบบจัดการไฟล์");
}),
);
return this.setStatus(HttpStatusCode.CREATED);
}
@Put()
@SuccessResponse(HttpStatusCode.NO_CONTENT, "Success")
public async updateFolder(
@Body()
body: {
from: {
bucket: string;
path: string;
};
to: {
bucket: string;
path: string;
};
},
) {
const src = body.from.path.split("/").filter(Boolean).join("/");
const dst = body.to.path.split("/").filter(Boolean).join("/");
if (
!Boolean(
await minioClient
.statObject(DEFAULT_BUCKET!, `${dst.replace(/^\/|\/$/g, "")}/.keep`)
.catch((e) => {
if (e.code === "NotFound") return false;
throw new Error(`Minio Error: ${e}`);
}),
)
)
throw new HttpError(HttpStatusCode.NOT_FOUND, "Destination Not Found");
const list = await new Promise<{ pathname: string; name: string }[]>((resolve, reject) => {
const item: { pathname: string; name: string }[] = [];
const stream = minioClient.listObjectsV2(body.from.bucket, src);
stream.on("data", (v) => {
if (v && v.prefix) {
item.push({
pathname: v.prefix,
name: v.prefix.slice(src.length).split("/")[0],
});
}
});
stream.on("error", (e) => reject(new Error(`Minio Error: ${e}`)));
stream.on("end", () => resolve(item));
});
return this.setStatus(HttpStatusCode.NO_CONTENT);
}
}

View file

@ -2,6 +2,7 @@ import {
Body,
Controller,
Delete,
Example,
Get,
Patch,
Path,
@ -33,10 +34,34 @@ if (!DEFAULT_INDEX) throw Error("Default ElasticSearch index must be specified."
"/cabinet/{cabinetName}/drawer/{drawerName}/folder/{folderName}/subfolder/{subFolderName}/file",
)
export class SubFolderFileController extends Controller {
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example subFolderName "แฟ้มย่อย 1"
*/
@Get("/")
@Tags("ไฟล์")
@Security("bearerAuth")
@SuccessResponse(HttpStatusCode.OK, "สำเร็จ")
@Example([
{
pathname: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/แฟ้มย่อย 1/เอกสาร 1",
path: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/แฟ้มย่อย 1/",
title: "เอกสาร",
description: "เอกสารการเงิน",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
upload: false,
fileName: "เอกสาร 1",
fileSize: 10240,
fileType: "application/pdf",
createdAt: "2021-07-20T12:33:13.018Z",
createdBy: "admin",
updatedAt: "2021-07-20T12:33:13.018Z",
updatedBy: "admin",
},
])
public async getFile(
@Path() cabinetName: string,
@Path() drawerName: string,
@ -65,6 +90,12 @@ export class SubFolderFileController extends Controller {
return records;
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example subFolderName "แฟ้มย่อย 1"
*/
@Post("/")
@Tags("ไฟล์")
@Security("bearerAuth", ["admin"])
@ -73,15 +104,46 @@ export class SubFolderFileController extends Controller {
"ตำแหน่งที่ระบุไม่พบ กรุณาเตรียมตำแหน่งที่ต้องการก่อนดำเนินการ",
)
@SuccessResponse(HttpStatusCode.CREATED, "สำเร็จ")
@Example({
pathname: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/แฟ้มย่อย 1/เอกสาร 1",
path: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/แฟ้มย่อย 1/",
title: "เอกสาร",
description: "เอกสารการเงิน",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
upload: false,
fileName: "เอกสาร 1",
fileSize: 10240,
fileType: "application/pdf",
createdAt: "2021-07-20T12:33:13.018Z",
createdBy: "admin",
updatedAt: "2021-07-20T12:33:13.018Z",
updatedBy: "admin",
})
public async uploadFile(
@Request() request: { user: { preferred_username: string } },
@Body()
body: {
/**
* @example "เอกสาร 1"
*/
file: string;
/**
* @example "เอกสาร"
*/
title?: string;
/**
* @example "เอกสารการเงิน"
*/
description?: string;
category?: string;
keyword?: string;
/**
* @example ["บัญชี"]
*/
category?: string[];
/**
* @example ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"]
*/
keyword?: string[];
},
@Path() cabinetName: string,
@Path() drawerName: string,
@ -129,8 +191,8 @@ export class SubFolderFileController extends Controller {
fileType: "",
title: body.title ?? "",
description: body.description ?? "",
category: body.category?.split(",") ?? [],
keyword: body.keyword?.split(",") ?? [],
category: body.category ?? [],
keyword: body.keyword ?? [],
upload: false,
createdAt: new Date().toISOString(),
createdBy: rec ? rec.createdBy : "n/a",
@ -154,6 +216,13 @@ export class SubFolderFileController extends Controller {
};
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example subFolderName "แฟ้มย่อย 1"
* @example fileName "เอกสาร 1"
*/
@Patch("/{fileName}")
@Tags("ไฟล์")
@Security("bearerAuth", ["admin"])
@ -168,11 +237,26 @@ export class SubFolderFileController extends Controller {
@Path() fileName: string,
@Body()
body: {
/**
* @example "เอกสารใหม่"
*/
file?: string;
/**
* @example "เอกสารการเงิน"
*/
title?: string;
/**
* @example "เอกสารการเงินฉบับใหม่"
*/
description?: string;
category?: string;
keyword?: string;
/**
* @example ["บัญชี"]
*/
category?: string[];
/**
* @example ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"]
*/
keyword?: string[];
},
) {
if (body.file && body.file.length > 85) {
@ -241,8 +325,6 @@ export class SubFolderFileController extends Controller {
id,
doc: {
...body,
keyword: body.keyword?.split(","),
category: body.category?.split(","),
updatedAt: new Date().toISOString(),
updatedBy: request.user.preferred_username ?? "n/a",
},
@ -261,6 +343,13 @@ export class SubFolderFileController extends Controller {
: this.setStatus(HttpStatusCode.NO_CONTENT);
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example subFolderName "แฟ้มย่อย 1"
* @example fileName "เอกสาร 1"
*/
@Delete("/{fileName}")
@Tags("ไฟล์")
@Security("bearerAuth", ["admin"])
@ -279,6 +368,13 @@ export class SubFolderFileController extends Controller {
return this.setStatus(HttpStatusCode.NO_CONTENT);
}
/**
* @example cabinetName "ตู้เอกสาร 1"
* @example drawerName "ลิ้นชัก 1"
* @example folderName "แฟ้ม 1"
* @example folderName "แฟ้มย่อย 1"
* @example fileName "เอกสาร 1"
*/
@Get("/{fileName}")
@Tags("ดาวน์โหลด")
@Security("bearerAuth")