diff --git a/Services/client/src/modules/01_user/components/SearchBar.vue b/Services/client/src/modules/01_user/components/SearchBar.vue
index 183edf6..e1c9df2 100644
--- a/Services/client/src/modules/01_user/components/SearchBar.vue
+++ b/Services/client/src/modules/01_user/components/SearchBar.vue
@@ -31,9 +31,18 @@ const optionsField = [
{ label: 'หมวดหมู่ (category)', value: 'category' },
{ label: 'เนื้อหาในไฟล์ (content)', value: 'attachment.content' },
]
-const submitSearchData = ref<
- InstanceType
['submitSearchData']
->({
+const submitSearchData = ref<{
+ AND: {
+ field: string
+ value: string
+ exact?: boolean
+ }[]
+ OR: {
+ field: string
+ value: string
+ exact?: boolean
+ }[]
+}>({
AND: [],
OR: [],
})
@@ -211,7 +220,6 @@ watch(
diff --git a/Services/client/src/stores/storage.ts b/Services/client/src/stores/storage.ts
index 0c464d6..f5a0b8f 100644
--- a/Services/client/src/stores/storage.ts
+++ b/Services/client/src/stores/storage.ts
@@ -26,6 +26,8 @@ export interface StorageFile {
fileType: string
title: string
description: string
+ author: string,
+ metadata: Record
category: string[]
keyword: string[]
updatedAt: string
@@ -439,9 +441,9 @@ const useStorage = defineStore('storageStore', () => {
},
to: file?.name
? {
- file: file.name,
- path: arr,
- }
+ file: file.name,
+ path: arr,
+ }
: undefined,
upload: !!file,
},
diff --git a/Services/server/src/controllers/storageController.ts b/Services/server/src/controllers/storageController.ts
index 1be0f2d..de13e54 100644
--- a/Services/server/src/controllers/storageController.ts
+++ b/Services/server/src/controllers/storageController.ts
@@ -75,10 +75,14 @@ interface FileBody {
title?: string;
/** @example "การเงิน" */
description?: string;
+ /** @example "นายก" */
+ author?: string;
/** @example ["การเงิน", "รายงาน"] */
category?: string[];
/** @example ["การเงิน", "รายรับ", "รายจ่าย"] */
keyword?: string[];
+ /** @example {} */
+ metadata?: { [key: string]: unknown };
/** @example false */
hidden?: boolean;
}
@@ -250,6 +254,7 @@ export class StorageController extends Controller {
path: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/",
title: "เอกสาร",
description: "เอกสารการเงิน",
+ author: "นายก",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
upload: false,
@@ -498,6 +503,7 @@ export class StorageController extends Controller {
path: "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/",
title: "เอกสาร",
description: "เอกสารการเงิน",
+ author: "นายก",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
upload: false,
@@ -540,9 +546,11 @@ export class StorageController extends Controller {
fileSize: 0, // Will be get by minio object storage after file is uploaded
fileType: "", // Will be determined by minio object storage after file is uploaded
title: body.title ?? validFileName, // default to same as filename
+ author: body.author ?? "",
description: body.description ?? "",
category: body.category ?? [],
keyword: body.keyword ?? [],
+ metadata: body.metadata ?? {},
upload: false, // flag
hidden: body.hidden ?? false,
createdAt: new Date().toISOString(),
@@ -675,6 +683,12 @@ export class StorageController extends Controller {
id: id,
doc: {
...metadata,
+ metadata: metadata["metadata"]
+ ? {
+ ...source["metadata"], // keep old field
+ ...metadata["metadata"], // replace some field that user update
+ }
+ : undefined,
path: stripLeadingSlash(`${to.path.join("/")}/`),
pathname: dst,
fileName: to.file,
@@ -786,6 +800,7 @@ export class StorageController extends Controller {
description: "เอกสารการเงิน",
category: ["บัญชี"],
keyword: ["เงิน", "บัญชี", "รายจ่าย", "รายรับ"],
+ author: "นายก",
upload: false,
hidden: false,
fileName: "เอกสาร 1.pdf",
diff --git a/Services/server/src/interfaces/storage-fs.ts b/Services/server/src/interfaces/storage-fs.ts
index c370bd9..539b653 100644
--- a/Services/server/src/interfaces/storage-fs.ts
+++ b/Services/server/src/interfaces/storage-fs.ts
@@ -26,6 +26,8 @@ export interface StorageFile {
description: string;
category: string[];
keyword: string[];
+ author: string;
+ metadata: Record;
path: string;
upload: boolean;
diff --git a/Services/server/src/rabbitmq/handler.ts b/Services/server/src/rabbitmq/handler.ts
index 9a2e2b9..c179c4f 100644
--- a/Services/server/src/rabbitmq/handler.ts
+++ b/Services/server/src/rabbitmq/handler.ts
@@ -3,6 +3,23 @@ import esClient from "../elasticsearch";
import minioClient from "../minio";
import * as io from "../lib/websocket";
+// const MINIO_ERROR_MESSAGE = "เกิดข้อผิดพลาดกับระบบจัดการไฟล์";
+
+// async function checkPathExist(bucket: string, path: string[]) {
+// if (path.filter(Boolean).length === 0) return true; // root does not contain any mark
+// return await checkFileExist(bucket, `${path.filter(Boolean).join("/")}/.keep`);
+// }
+//
+// async function checkFileExist(bucket: string, pathname: string) {
+// return Boolean(
+// await minioClient.statObject(bucket, stripLeadingSlash(pathname)).catch((e) => {
+// if (e.code === "NotFound") return false;
+// console.error(`Storage Error: ${e}`);
+// throw new Error(MINIO_ERROR_MESSAGE);
+// }),
+// );
+// }
+
const DEFAULT_INDEX = process.env.ELASTICSEARCH_INDEX;
if (!DEFAULT_INDEX) throw Error("Default ElasticSearch index must be specified.");
@@ -122,15 +139,17 @@ async function handleNotFoundRecord(
fileType: stat.type,
title: "",
description: "",
+ author: "",
category: [],
keyword: [],
+ metadata: {},
upload: true,
hidden: false,
createdAt: new Date().toISOString(),
createdBy: "n/a",
updatedAt: new Date().toISOString(),
updatedBy: "n/a",
- } satisfies Partial;
+ } satisfies StorageFile;
const result = await esClient
.index({
diff --git a/Services/server/src/routes.ts b/Services/server/src/routes.ts
index 459fc1d..e9c4832 100644
--- a/Services/server/src/routes.ts
+++ b/Services/server/src/routes.ts
@@ -16,6 +16,11 @@ import type { RequestHandler, Router } from 'express';
// 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 models: TsoaRoute.Models = {
+ "Record_string.unknown_": {
+ "dataType": "refAlias",
+ "type": {"dataType":"nestedObjectLiteral","nestedProperties":{},"validators":{}},
+ },
+ // 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
"StorageFile": {
"dataType": "refObject",
"properties": {
@@ -27,6 +32,8 @@ const models: TsoaRoute.Models = {
"description": {"dataType":"string","required":true},
"category": {"dataType":"array","array":{"dataType":"string"},"required":true},
"keyword": {"dataType":"array","array":{"dataType":"string"},"required":true},
+ "author": {"dataType":"string","required":true},
+ "metadata": {"ref":"Record_string.unknown_","required":true},
"path": {"dataType":"string","required":true},
"upload": {"dataType":"boolean","required":true},
"hidden": {"dataType":"boolean","required":true},
@@ -95,6 +102,11 @@ 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
+ "Record_string.any_": {
+ "dataType": "refAlias",
+ "type": {"dataType":"nestedObjectLiteral","nestedProperties":{},"validators":{}},
+ },
+ // 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
"FileBody": {
"dataType": "refObject",
"properties": {
@@ -102,8 +114,10 @@ const models: TsoaRoute.Models = {
"file": {"dataType":"string","required":true},
"title": {"dataType":"string"},
"description": {"dataType":"string"},
+ "author": {"dataType":"string"},
"category": {"dataType":"array","array":{"dataType":"string"}},
"keyword": {"dataType":"array","array":{"dataType":"string"}},
+ "metadata": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"}},
"hidden": {"dataType":"boolean"},
},
"additionalProperties": false,
@@ -117,6 +131,8 @@ const models: TsoaRoute.Models = {
"title": {"dataType":"string"},
"description": {"dataType":"string"},
"category": {"dataType":"array","array":{"dataType":"string"}},
+ "author": {"dataType":"string"},
+ "metadata": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"}},
"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"},
diff --git a/Services/server/src/swagger.json b/Services/server/src/swagger.json
index 4424572..ac2cb3d 100644
--- a/Services/server/src/swagger.json
+++ b/Services/server/src/swagger.json
@@ -6,6 +6,11 @@
"requestBodies": {},
"responses": {},
"schemas": {
+ "Record_string.unknown_": {
+ "properties": {},
+ "type": "object",
+ "description": "Construct a type with a set of properties K of type T"
+ },
"StorageFile": {
"properties": {
"pathname": {
@@ -39,6 +44,12 @@
},
"type": "array"
},
+ "author": {
+ "type": "string"
+ },
+ "metadata": {
+ "$ref": "#/components/schemas/Record_string.unknown_"
+ },
"path": {
"type": "string"
},
@@ -86,6 +97,8 @@
"description",
"category",
"keyword",
+ "author",
+ "metadata",
"path",
"upload",
"hidden",
@@ -314,6 +327,11 @@
"type": "object",
"additionalProperties": false
},
+ "Record_string.any_": {
+ "properties": {},
+ "type": "object",
+ "description": "Construct a type with a set of properties K of type T"
+ },
"FileBody": {
"properties": {
"path": {
@@ -339,6 +357,10 @@
"type": "string",
"example": "การเงิน"
},
+ "author": {
+ "type": "string",
+ "example": "นายก"
+ },
"category": {
"items": {
"type": "string"
@@ -360,6 +382,12 @@
"รายจ่าย"
]
},
+ "metadata": {
+ "properties": {},
+ "additionalProperties": {},
+ "type": "object",
+ "example": {}
+ },
"hidden": {
"type": "boolean",
"example": false
@@ -407,6 +435,16 @@
"รายงาน"
]
},
+ "author": {
+ "type": "string",
+ "example": "นายก"
+ },
+ "metadata": {
+ "properties": {},
+ "additionalProperties": {},
+ "type": "object",
+ "example": {}
+ },
"from": {
"properties": {
"file": {
@@ -625,6 +663,7 @@
"path": "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/",
"title": "เอกสาร",
"description": "เอกสารการเงิน",
+ "author": "นายก",
"category": [
"บัญชี"
],
@@ -874,6 +913,12 @@
"path": {
"type": "string"
},
+ "metadata": {
+ "$ref": "#/components/schemas/Record_string.any_"
+ },
+ "author": {
+ "type": "string"
+ },
"keyword": {
"items": {
"type": "string"
@@ -917,6 +962,8 @@
"hidden",
"upload",
"path",
+ "metadata",
+ "author",
"keyword",
"category",
"description",
@@ -936,6 +983,7 @@
"path": "ตู้เอกสาร 1/ลิ้นชัก 1/แฟ้ม 1/",
"title": "เอกสาร",
"description": "เอกสารการเงิน",
+ "author": "นายก",
"category": [
"บัญชี"
],
@@ -1127,6 +1175,12 @@
"path": {
"type": "string"
},
+ "metadata": {
+ "$ref": "#/components/schemas/Record_string.any_"
+ },
+ "author": {
+ "type": "string"
+ },
"keyword": {
"items": {
"type": "string"
@@ -1170,6 +1224,8 @@
"hidden",
"upload",
"path",
+ "metadata",
+ "author",
"keyword",
"category",
"description",
@@ -1198,6 +1254,7 @@
"รายจ่าย",
"รายรับ"
],
+ "author": "นายก",
"upload": false,
"hidden": false,
"fileName": "เอกสาร 1.pdf",