From efd5183906c57e458a992057de20277f5adf868c Mon Sep 17 00:00:00 2001 From: admin Date: Sat, 28 Feb 2026 14:27:33 +0700 Subject: [PATCH] 260228:1427 20260228:14:00 workflow update --- .../workflow-engine.controller.ts | 20 +++++++++++--- .../workflow-engine.service.ts | 27 +++++++++++++++++++ .../doc-control/workflows/[id]/edit/page.tsx | 4 +-- .../admin/doc-control/workflows/page.tsx | 26 +++--------------- .../lib/services/workflow-engine.service.ts | 27 ++++++++++++++++--- frontend/types/workflow.ts | 2 +- 6 files changed, 73 insertions(+), 33 deletions(-) diff --git a/backend/src/modules/workflow-engine/workflow-engine.controller.ts b/backend/src/modules/workflow-engine/workflow-engine.controller.ts index e77917e..f627b01 100644 --- a/backend/src/modules/workflow-engine/workflow-engine.controller.ts +++ b/backend/src/modules/workflow-engine/workflow-engine.controller.ts @@ -52,12 +52,26 @@ export class WorkflowEngineController { return this.workflowService.createDefinition(dto); } + @Get('definitions') + @ApiOperation({ summary: 'ดึง Workflow Definition ทั้งหมด' }) + @RequirePermission('system.manage_all') + async getDefinitions() { + return this.workflowService.getDefinitions(); + } + + @Get('definitions/:id') + @ApiOperation({ summary: 'ดึง Workflow Definition ด้วย ID' }) + @RequirePermission('system.manage_all') + async getDefinitionById(@Param('id') id: string) { + return this.workflowService.getDefinitionById(id); + } + @Patch('definitions/:id') @ApiOperation({ summary: 'แก้ไข Workflow Definition (Re-compile DSL)' }) @RequirePermission('system.manage_all') async updateDefinition( @Param('id') id: string, - @Body() dto: UpdateWorkflowDefinitionDto, + @Body() dto: UpdateWorkflowDefinitionDto ) { return this.workflowService.update(id, dto); } @@ -81,7 +95,7 @@ export class WorkflowEngineController { async processTransition( @Param('id') instanceId: string, @Body() dto: WorkflowTransitionDto, - @Request() req: any, + @Request() req: any ) { // ดึง User ID จาก Token (req.user มาจาก JwtStrategy) const userId = req.user?.userId; @@ -91,7 +105,7 @@ export class WorkflowEngineController { dto.action, userId, dto.comment, - dto.payload, + dto.payload ); } diff --git a/backend/src/modules/workflow-engine/workflow-engine.service.ts b/backend/src/modules/workflow-engine/workflow-engine.service.ts index 3df5b86..8dcbeae 100644 --- a/backend/src/modules/workflow-engine/workflow-engine.service.ts +++ b/backend/src/modules/workflow-engine/workflow-engine.service.ts @@ -121,6 +121,33 @@ export class WorkflowEngineService { return this.workflowDefRepo.save(definition); } + /** + * ดึง Workflow Definition ทั้งหมด (เฉพาะ Version ล่าสุดของแต่ละ Workflow Code) + */ + async getDefinitions(): Promise { + // หา version ล่าสุดของแต่ละ workflow_code + // ใช้ query builder เพื่อ group by และหา max version + const latestDefinitions = await this.workflowDefRepo + .createQueryBuilder('def') + .where( + 'def.version = (SELECT MAX(sub.version) FROM workflow_definitions sub WHERE sub.workflow_code = def.workflow_code)', + ) + .getMany(); + + return latestDefinitions; + } + + /** + * ดึง Workflow Definition ตาม ID หรือ Code + */ + async getDefinitionById(id: string): Promise { + const definition = await this.workflowDefRepo.findOne({ where: { id } }); + if (!definition) { + throw new NotFoundException(`Workflow Definition with ID "${id}" not found`); + } + return definition; + } + /** * ดึง Action ที่ทำได้ ณ State ปัจจุบัน */ diff --git a/frontend/app/(admin)/admin/doc-control/workflows/[id]/edit/page.tsx b/frontend/app/(admin)/admin/doc-control/workflows/[id]/edit/page.tsx index 9a7d500..c01dab5 100644 --- a/frontend/app/(admin)/admin/doc-control/workflows/[id]/edit/page.tsx +++ b/frontend/app/(admin)/admin/doc-control/workflows/[id]/edit/page.tsx @@ -21,7 +21,7 @@ import Link from 'next/link'; export default function WorkflowEditPage() { const params = useParams(); const router = useRouter(); - const id = params?.id === 'new' ? null : Number(params?.id); + const id = params?.id === 'new' ? null : params?.id as string; const [workflowData, setWorkflowData] = useState>({ workflowName: '', @@ -31,7 +31,7 @@ export default function WorkflowEditPage() { isActive: true, }); - const { data: fetchedWorkflow, isLoading: loadingWorkflow } = useWorkflowDefinition(id as number); + const { data: fetchedWorkflow, isLoading: loadingWorkflow } = useWorkflowDefinition(id as string); const createMutation = useCreateWorkflowDefinition(); const updateMutation = useUpdateWorkflowDefinition(); diff --git a/frontend/app/(admin)/admin/doc-control/workflows/page.tsx b/frontend/app/(admin)/admin/doc-control/workflows/page.tsx index dd4110c..62e74a9 100644 --- a/frontend/app/(admin)/admin/doc-control/workflows/page.tsx +++ b/frontend/app/(admin)/admin/doc-control/workflows/page.tsx @@ -1,35 +1,15 @@ 'use client'; -import { useState, useEffect } from 'react'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Plus, Edit, Copy, Trash, Loader2 } from 'lucide-react'; import Link from 'next/link'; +import { useWorkflowDefinitions } from '@/hooks/use-workflows'; import { Workflow } from '@/types/workflow'; -import { workflowApi } from '@/lib/api/workflows'; -import { toast } from 'sonner'; export default function WorkflowsPage() { - const [workflows, setWorkflows] = useState([]); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchWorkflows = async () => { - setLoading(true); - try { - const data = await workflowApi.getWorkflows(); - setWorkflows(data); - } catch (error) { - toast.error('Failed to load workflows'); - console.error('[WorkflowsPage]', error); - } finally { - setLoading(false); - } - }; - - fetchWorkflows(); - }, []); + const { data: workflows = [], isLoading: loading } = useWorkflowDefinitions(); return (
@@ -52,7 +32,7 @@ export default function WorkflowsPage() {
) : (
- {workflows.map((workflow) => ( + {workflows.map((workflow: Workflow) => (
diff --git a/frontend/lib/services/workflow-engine.service.ts b/frontend/lib/services/workflow-engine.service.ts index e3e74f7..f504173 100644 --- a/frontend/lib/services/workflow-engine.service.ts +++ b/frontend/lib/services/workflow-engine.service.ts @@ -7,6 +7,23 @@ import { GetAvailableActionsDto, } from '@/types/dto/workflow-engine/workflow-engine.dto'; +import { Workflow } from '@/types/workflow'; + +const mapWorkflow = (backendObj: any): Workflow => { + if (!backendObj) throw new Error('Workflow not found'); + return { + workflowId: backendObj.id, + workflowName: backendObj.dsl?.workflowName || backendObj.workflow_code, + description: backendObj.description || backendObj.dsl?.description || '', + workflowType: backendObj.workflow_code, + version: backendObj.version || 1, + isActive: backendObj.is_active, + dslDefinition: typeof backendObj.dsl === 'string' ? backendObj.dsl : backendObj.dsl?.dslDefinition || JSON.stringify(backendObj.dsl, null, 2), + stepCount: backendObj.compiled?.states ? Object.keys(backendObj.compiled.states).length : 0, + updatedAt: backendObj.updated_at || new Date().toISOString(), + }; +}; + export const workflowEngineService = { // --- Engine Execution (Low-Level) --- @@ -34,18 +51,20 @@ export const workflowEngineService = { * ดึง Workflow Definition ทั้งหมด * GET /workflow-engine/definitions */ - getDefinitions: async () => { + getDefinitions: async (): Promise => { const response = await apiClient.get('/workflow-engine/definitions'); - return response.data?.data || response.data; + const data = response.data?.data || response.data; + return Array.isArray(data) ? data.map(mapWorkflow) : data; }, /** * ดึง Workflow Definition ตาม ID * GET /workflow-engine/definitions/:id */ - getDefinitionById: async (id: string | number) => { + getDefinitionById: async (id: string | number): Promise => { const response = await apiClient.get(`/workflow-engine/definitions/${id}`); - return response.data?.data || response.data; + const data = response.data?.data || response.data; + return mapWorkflow(data); }, /** diff --git a/frontend/types/workflow.ts b/frontend/types/workflow.ts index 19b69da..b36e114 100644 --- a/frontend/types/workflow.ts +++ b/frontend/types/workflow.ts @@ -11,7 +11,7 @@ export interface WorkflowStep { } export interface Workflow { - workflowId: number; + workflowId: string | number; workflowName: string; description: string; workflowType: WorkflowType;