251117:1700 first commit
This commit is contained in:
192
docs/workflow.bak
Normal file
192
docs/workflow.bak
Normal file
@@ -0,0 +1,192 @@
|
||||
## Workflow ระดับ Project (correspondence_routing_steps, technical_doc_workflows): คือ "การเดินทาง" ของเอกสาร ระหว่างองค์กร (เช่น จากผู้รับเหมา -> ไปยังที่ปรึกษา -> ไปยังเจ้าของโครงการ)
|
||||
|
||||
## Workflow ระดับ Organization (Circulation): คือ "การแจกจ่าย" เอกสาร ภายในองค์กรของคุณเอง หลังจากที่คุณได้รับเอกสารนั้นมาแล้ว (เช่น เอกสารมาถึง Document Control แล้วต้องส่งต่อให้ใครบ้างในบริษัท)
|
||||
|
||||
circulation_templates: ตารางหลักสำหรับเก็บชื่อแม่แบบ
|
||||
circulation_template_assignees: ตารางสำหรับเก็บ "รายชื่อผู้รับผิดชอบ" ที่ถูกกำหนดไว้ในแต่ละแม่แบบ
|
||||
|
||||
Workflow การทำงานใน Frontend
|
||||
1. หน้า Admin Panel: จะต้องมีเมนูใหม่สำหรับให้ Admin หรือผู้มีสิทธิ์ เข้าไป สร้าง/แก้ไข/ลบ แม่แบบใบเวียน (circulation_templates) สำหรับองค์กรของตนเองได้
|
||||
|
||||
2. หน้าที่สร้างใบเวียน (Create Circulation Dialog):
|
||||
* ที่ด้านบนสุดของฟอร์ม จะมี Dropdown ใหม่ ปรากฏขึ้นมา เขียนว่า "ใช้แม่แบบ (Use Template)"
|
||||
* ใน Dropdown นี้ จะแสดงรายชื่อแม่แบบทั้งหมดที่องค์กรนั้นๆ สร้างไว้
|
||||
* เมื่อผู้ใช้เลือกแม่แบบ:
|
||||
** ระบบจะยิง API ไปดึงรายชื่อผู้รับผิดชอบจากตาราง circulation_template_assignees
|
||||
** จากนั้น JavaScript จะทำการเติมข้อมูล (Auto-populate) ลงในช่อง "Main", "Action", และ "Information" ให้โดยอัตโนมัติ
|
||||
* ผู้ใช้ยังสามารถ แก้ไข/เพิ่มเติม/ลบ รายชื่อผู้รับผิดชอบได้ตามต้องการ ก่อนที่จะกดสร้างใบเวียนจริง
|
||||
|
||||
|
||||
การจัดการข้อมูล JSON จะเกิดขึ้นใน 3 ส่วนหลักๆ คือ Backend, Frontend, และ Database ครับ
|
||||
|
||||
## 1. การจัดการในฝั่ง Backend (NestJS)
|
||||
นี่คือส่วนที่ทำหน้าที่หลักในการสร้างและอ่านข้อมูล JSON อย่างเป็นระบบและปลอดภัย
|
||||
|
||||
1.1 การแก้ไข Entity
|
||||
เราจะแก้ไข Correspondence entity โดยเพิ่มคอลัมน์ details เข้าไป และลบ Entity ย่อยๆ ที่ไม่ใช้ออก
|
||||
|
||||
src/correspondences/entities/correspondence.entity.ts
|
||||
@Entity('correspondences')
|
||||
export class Correspondence {
|
||||
// ... (คอลัมน์เดิมทั้งหมด: id, document_number, title, etc.)
|
||||
|
||||
@Column({
|
||||
type: 'json', // ◀️ กำหนดประเภทข้อมูลเป็น JSON
|
||||
nullable: true,
|
||||
comment: 'เก็บข้อมูลเฉพาะของเอกสารแต่ละประเภทในรูปแบบ JSON'
|
||||
})
|
||||
details: any; // ◀️ ใช้ type 'any' หรือสร้าง Interface/Type ที่ซับซ้อนขึ้น
|
||||
}
|
||||
|
||||
1.2 การสร้าง DTOs สำหรับแต่ละประเภทเอกสาร
|
||||
เพื่อรักษาความถูกต้องของข้อมูล (Validation) เราจะสร้าง DTO แยกสำหรับเอกสารแต่ละประเภท
|
||||
|
||||
ตัวอย่าง src/correspondences/dto/create-letter.dto.ts:
|
||||
|
||||
TypeScript
|
||||
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsNotEmpty, IsString } from 'class-validator';
|
||||
|
||||
// DTO สำหรับข้อมูลใน details ของ Letter
|
||||
class LetterDetailsDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
attention_to: string;
|
||||
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
signatory_name: string;
|
||||
}
|
||||
|
||||
// DTO หลักสำหรับสร้าง Letter
|
||||
export class CreateLetterDto {
|
||||
@ApiProperty({ description: "ข้อมูลพื้นฐานของเอกสาร" })
|
||||
@ValidateNested() // ◀️ บอกให้ class-validator ตรวจสอบ object ข้างในด้วย
|
||||
@Type(() => CreateCorrespondenceDto) // ◀️ ใช้ DTO พื้นฐานร่วมกัน
|
||||
base_data: CreateCorrespondenceDto;
|
||||
|
||||
@ApiProperty({ description: "ข้อมูลเฉพาะของ Letter" })
|
||||
@ValidateNested()
|
||||
@Type(() => LetterDetailsDto)
|
||||
details: LetterDetailsDto;
|
||||
}
|
||||
|
||||
1.3 การสร้าง API Endpoint และ Logic ใน Service
|
||||
เราจะสร้าง Endpoint แยกสำหรับสร้างเอกสารแต่ละประเภทเพื่อความชัดเจน
|
||||
|
||||
ใน CorrespondencesController:
|
||||
|
||||
TypeScript
|
||||
|
||||
@Post('letter')
|
||||
@ApiOperation({ summary: 'Create a new Letter' })
|
||||
createLetter(@Body() createLetterDto: CreateLetterDto, @Req() req: Request) {
|
||||
const user = req.user as any;
|
||||
return this.correspondencesService.createTypedCorrespondence(
|
||||
createLetterDto.base_data,
|
||||
createLetterDto.details,
|
||||
user
|
||||
);
|
||||
}
|
||||
ใน CorrespondencesService:
|
||||
|
||||
TypeScript
|
||||
|
||||
async createTypedCorrespondence(baseData: CreateCorrespondenceDto, details: any, user: User): Promise<Correspondence> {
|
||||
// ... (โค้ดตรวจสอบสิทธิ์เหมือนเดิม)
|
||||
|
||||
const newCorrespondence = this.correspondenceRepository.create({
|
||||
...baseData, // ข้อมูลพื้นฐาน (เลขที่เอกสาร, ชื่อเรื่อง, etc.)
|
||||
details: details, // ◀️ นำ object ของ details มาใส่ในคอลัมน์ JSON โดยตรง
|
||||
created_by_user_id: user.user_id,
|
||||
originator_org_id: user.org_id,
|
||||
status_id: 1, // 'Draft'
|
||||
});
|
||||
|
||||
return this.correspondenceRepository.save(newCorrespondence);
|
||||
}
|
||||
## 2. การจัดการในฝั่ง Frontend (Next.js / React)
|
||||
Frontend จะทำหน้าที่แสดงฟอร์มที่ถูกต้องตามประเภทเอกสาร และส่งข้อมูลในรูปแบบที่ Backend ต้องการ
|
||||
|
||||
2.1 การแสดงฟอร์มแบบไดนามิก (Dynamic Forms)
|
||||
ในหน้า "Create Correspondence" เมื่อผู้ใช้เลือกประเภทเอกสารจาก Dropdown เราจะใช้ State เพื่อแสดงฟอร์มที่ถูกต้อง
|
||||
|
||||
TypeScript
|
||||
|
||||
const [docType, setDocType] = useState('LETTER');
|
||||
|
||||
// ...
|
||||
|
||||
const renderDetailFields = () => {
|
||||
switch (docType) {
|
||||
case 'LETTER':
|
||||
return (
|
||||
<>
|
||||
{/* ฟิลด์สำหรับ Attention To, Signatory */}
|
||||
</>
|
||||
);
|
||||
case 'RFI':
|
||||
return (
|
||||
<>
|
||||
{/* ฟิลด์สำหรับ Question, Required By Date */}
|
||||
</>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<form>
|
||||
{/* ฟิลด์พื้นฐาน (Document Number, Title) */}
|
||||
{/* Dropdown เลือกประเภทเอกสาร */}
|
||||
{renderDetailFields()} {/* ◀️ แสดงฟิลด์เฉพาะทางที่นี่ */}
|
||||
</form>
|
||||
);
|
||||
2.2 การส่งข้อมูล
|
||||
เมื่อผู้ใช้กด Submit เราจะรวบรวมข้อมูลจากฟอร์มให้เป็นโครงสร้าง JSON ที่ Backend ต้องการ
|
||||
|
||||
JavaScript
|
||||
|
||||
const handleSubmit = () => {
|
||||
// รวบรวมข้อมูลพื้นฐาน
|
||||
const base_data = {
|
||||
document_number: '...',
|
||||
title: '...',
|
||||
// ...
|
||||
};
|
||||
|
||||
// รวบรวมข้อมูลเฉพาะทาง
|
||||
const details = {
|
||||
attention_to: '...',
|
||||
signatory_name: '...',
|
||||
};
|
||||
|
||||
// ส่งข้อมูลไปที่ API Endpoint ที่ถูกต้อง
|
||||
fetch('/api/correspondences/letter', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ base_data, details }),
|
||||
});
|
||||
}
|
||||
## 3. การจัดการในระดับฐานข้อมูล (MariaDB)
|
||||
แม้ว่าเราจะไม่ค่อยได้ Query ข้อมูล JSON โดยตรงผ่าน SQL บ่อยนัก แต่ก็สามารถทำได้เมื่อจำเป็น (เช่น สำหรับการทำรายงานที่ซับซ้อน)
|
||||
|
||||
ตัวอย่าง: ค้นหาเอกสาร Letter ทั้งหมดที่ส่งถึง "Mr. John Doe"
|
||||
|
||||
SQL
|
||||
|
||||
SELECT
|
||||
corr_id,
|
||||
document_number,
|
||||
details
|
||||
FROM
|
||||
correspondences
|
||||
WHERE
|
||||
type_id = (SELECT type_id FROM correspondence_types WHERE type_code = 'LETTER') -- กรองเฉพาะ Letter
|
||||
AND JSON_VALUE(details, '$.attention_to') = 'Mr. John Doe'; -- ◀️ ค้นหาค่าใน JSON
|
||||
การจัดการข้อมูลด้วยวิธีนี้จะทำให้ระบบของคุณมีความ
|
||||
|
||||
|
||||
Reference in New Issue
Block a user