Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 48

Cấu hình User Task: Assignee, Candidate Users & Groups

Recommended resources

Chào bạn,

Trong module trước, chúng ta đã khám phá cách sử dụng DMN để tách biệt và quản lý các quy tắc nghiệp vụ phức tạp. Bạn đã học cách tạo, tích hợp và kiểm thử các bảng quyết định, giúp tự động hóa phần lớn logic của quy trình.

Tuy nhiên, không phải mọi bước trong một quy trình đều có thể được tự động hóa hoàn toàn. Nhiều quy trình nghiệp vụ yêu cầu sự can thiệp, phán đoán hoặc phê duyệt của con người. Đây là lúc chúng ta chuyển từ thế giới của các Service Task và Business Rule Task sang một thành phần cốt lõi khác: User Task.

Bài học hôm nay là bài đầu tiên của Module 10: "Xây dựng Giao diện Quản lý Tác vụ Người dùng". Chúng ta sẽ tập trung vào mục tiêu: Cấu hình User Task với Assignee, Candidate Users và Candidate Groups.

Bạn sẽ học cách định nghĩa "ai" chịu trách nhiệm cho một công việc, "ai" có thể thực hiện nó, và "nhóm nào" có quyền xử lý. Nắm vững kỹ thuật này là bước đầu tiên và quan trọng nhất để xây dựng các ứng dụng có sự tương tác của người dùng trên nền tảng Camunda.


1. User Task: Khi Con người tham gia vào Quy trình

Trong BPMN, User Task được dùng để mô hình hóa một công việc cần được thực hiện bởi một người dùng. Khi một quy trình chạy đến User Task, engine sẽ tạo ra một task trong "danh sách công việc" (task list) và tạm dừng luồng xử lý tại đó. Quy trình chỉ tiếp tục khi có người hoàn thành task này.

Điều này khác với:

  • Service Task: Được thực thi tự động bởi hệ thống (ví dụ: gọi một API, thực thi một đoạn mã Java).
  • Manual Task: Mô hình hóa một công việc được thực hiện thủ công bên ngoài hệ thống, mà engine không hề hay biết hay hỗ trợ (ví dụ: nhân viên kho tự đi lấy hàng).

Để một User Task có thể được thực hiện, chúng ta phải chỉ định ai là người có trách nhiệm với nó. Camunda cung cấp ba cách chính để làm điều này.


2. Ba Khái niệm Cốt lõi của việc Giao việc (Assignment)

Hãy tưởng tượng bạn đang quản lý công việc trong một đội. Bạn có thể giao việc theo những cách sau:

a. Assignee (Người được giao)

Đây là cách giao việc trực tiếp nhất. Một task có Assignee nghĩa là nó được chỉ định cho một người dùng cụ thể.

  • Đặc điểm: Chỉ người đó mới thấy và có thể làm task này trong danh sách công việc cá nhân của họ.
  • Ví dụ: "Phê duyệt chi phí này" được giao thẳng cho jane.doe (trưởng phòng tài chính).

b. Candidate Users (Những người có thể nhận việc)

Một task có Candidate Users nghĩa là nó có thể được thực hiện bởi bất kỳ ai trong một danh sách những người dùng cụ thể.

  • Đặc điểm: Task sẽ xuất hiện trong "hàng đợi" (queue) của tất cả những người trong danh sách. Ai nhận (claim) task trước thì sẽ xử lý nó, và task sẽ biến mất khỏi hàng đợi của những người còn lại.
  • Ví dụ: "Kiểm tra lại hợp đồng" có thể được thực hiện bởi john hoặc mary (hai luật sư trong đội pháp lý).

c. Candidate Groups (Các nhóm có thể nhận việc)

Tương tự như Candidate Users, nhưng thay vì liệt kê từng người, bạn chỉ định một hoặc nhiều nhóm người dùng.

  • Đặc điểm: Bất kỳ thành viên nào của các nhóm này đều có thể thấy và nhận task. Đây là cách hiệu quả để quản lý các task cho một phòng ban hoặc một vai trò chung.
  • Ví dụ: "Xử lý yêu cầu hỗ trợ của khách hàng" được giao cho nhóm support_level_2. Bất kỳ ai trong nhóm này cũng có thể xử lý.
Camunda User Task Assignment Configuration
Giao diện cấu hình Assignment trong Properties Panel của Camunda Modeler. Bạn có thể thấy các trường "Assignee", "Candidate groups" và "Candidate users".


3. Cấu hình Assignment trong Camunda Modeler

Với nền tảng là một developer, bạn sẽ thấy việc cấu hình này rất linh hoạt, hỗ trợ cả giá trị tĩnh và động.

a. Gán tĩnh (Static Assignment)

Bạn có thể nhập trực tiếp User ID hoặc Group ID vào các trường tương ứng trong Properties Panel. Đây là cách đơn giản nhất, phù hợp cho các quy trình có vai trò cố định.

  • Assignee: demo
  • Candidate Users: john, mary, peter (phân tách bằng dấu phẩy)
  • Candidate Groups: management, accounting (phân tách bằng dấu phẩy)

b. Gán động (Dynamic Assignment)

Đây mới là sức mạnh thực sự của Camunda, đặc biệt phù hợp với các ứng dụng phức tạp. Thay vì một giá trị tĩnh, bạn có thể sử dụng Expression Language (JUEL) để lấy giá trị từ các biến quy trình.

Hãy xem hình ảnh dưới đây. Thay vì nhập một tên cụ thể, các trường được điền bằng các biểu thức như ${assignee}.

Configuring User Task Assignment in Camunda
Cấu hình User Task sử dụng các biến quy trình. Giá trị thực tế của `assignee`, `candidateUsers`, và `candidateGroups` sẽ được xác định tại thời điểm quy trình chạy đến task này.

Ví dụ, biến assignee có thể được đặt ở một bước trước đó, chẳng hạn như "Tìm người quản lý của nhân viên" và lưu kết quả vào biến quy trình.


4. "Dưới Lớp Vỏ": XML và Logic Thực thi

Giao diện Modeler rất trực quan, nhưng với vai trò là developer, việc hiểu rõ cấu trúc XML bên dưới sẽ giúp bạn kiểm soát quy trình tốt hơn. Camunda sử dụng các thuộc tính mở rộng (extension attributes) để lưu các cấu hình này.

Tài liệu sau đây từ Camunda 7 giải thích chi tiết về các thuộc tính này.

User Task | Camunda 7 Docs

Tài liệu này sẽ cho bạn thấy cách các cấu hình Assignee, Candidate Users và Candidate Groups được biểu diễn trong file BPMN XML và cách sử dụng các biểu thức (expressions) để gán việc một cách linh hoạt.

Hãy dành khoảng 15 phút để đọc các phần sau: Bắt đầu từ mục "User Assignment using Camunda Extensions". Tập trung vào các ví dụ XML cho các thuộc tính: camunda:assignee, camunda:candidateUsers, và camunda:candidateGroups. Tiếp tục với mục "Assignment based on Data and Service Logic". Đọc kỹ phần "Using Process Variables". Chú ý đến ví dụ sử dụng camunda:initiator để lấy người khởi tạo quy trình và sau đó gán task cho họ bằng biểu thức ${starter}. Đây là một pattern rất phổ biến.

Sau khi đọc tài liệu, bạn có thể thấy rõ mối liên hệ:

  • Trường Assignee trong Modeler tương ứng với thuộc tính camunda:assignee trong XML.
  • Trường Candidate Users tương ứng với camunda:candidateUsers.
  • Trường Candidate Groups tương ứng với camunda:candidateGroups.


5. Ví dụ thực tế: Quy trình Xin nghỉ phép

Hãy áp dụng các kiến thức trên vào một kịch bản cụ thể: một nhân viên tạo yêu cầu xin nghỉ, và người quản lý cần phê duyệt.

Kịch bản 1: Gán trực tiếp cho một quản lý cố định

Nếu công ty nhỏ và chỉ có một quản lý tên là supervisor_01 chịu trách nhiệm duyệt phép.

  • Cấu hình Modeler:
    • Assignee: supervisor_01
  • XML tương ứng:
    <userTask id="approveRequestTask" 
              name="Approve Leave Request" 
              camunda:assignee="supervisor_01" />
    

Kịch bản 2: Bất kỳ ai trong nhóm "Quản lý" đều có thể duyệt

Nếu công ty có nhiều quản lý và bất kỳ ai cũng có thể duyệt phép để tăng tốc độ.

  • Cấu hình Modeler:
    • Candidate Groups: managers
  • XML tương ứng:
    <userTask id="approveRequestTask" 
              name="Approve Leave Request" 
              camunda:candidateGroups="managers" />
    

Kịch bản 3: Gán cho quản lý trực tiếp của người xin nghỉ (Kịch bản động)

Đây là kịch bản thực tế và linh hoạt nhất.

  1. Khi quy trình bắt đầu, chúng ta dùng thuộc tính camunda:initiator trên Start Event để lưu ID của người xin nghỉ vào biến employeeId.
  2. Tiếp theo, một Service Task có tên "Find Manager" sẽ chạy, nhận employeeId làm đầu vào và trả về ID của người quản lý, lưu vào biến managerId.
  3. Cuối cùng, User Task "Approve Leave Request" sẽ sử dụng biến này.
  • Cấu hình Modeler:
    • Assignee: ${managerId}
  • XML tương ứng:
    <startEvent id="start" camunda:initiator="employeeId" />
    ...
    <serviceTask id="findManagerTask" name="Find Manager" ... />
    ...
    <userTask id="approveRequestTask" 
              name="Approve Leave Request" 
              camunda:assignee="${managerId}" />
    

Cách tiếp cận này cho thấy sức mạnh của việc kết hợp các biến quy trình và biểu thức để tạo ra các quy trình có khả năng thích ứng cao.



Tổng kết

Trong bài học này, bạn đã nắm được những kiến thức nền tảng về việc phân công nhiệm vụ cho con người trong Camunda:

  • User Task là điểm dừng trong quy trình để chờ con người hành động.
  • Assignee gán việc cho một người duy nhất.
  • Candidate Users và Candidate Groups tạo ra một hàng đợi công việc chung cho nhiều người.
  • Việc gán có thể được thực hiện tĩnh (hard-coded) hoặc động (dùng expression và biến quy trình), mang lại sự linh hoạt tối đa.

Hiểu rõ cách cấu hình các thuộc tính này là cực kỳ quan trọng, vì nó quyết định cách người dùng cuối sẽ tương tác với hệ thống của bạn.


Xem trước bài học tiếp theo

Bây giờ bạn đã biết cách giao việc cho người dùng và các nhóm. Bước tiếp theo một cách tự nhiên là: làm thế nào để một ứng dụng bên ngoài (ví dụ: một trang web) có thể lấy danh sách công việc của một người dùng cụ thể?

Trong bài học tới, "Sử dụng Camunda REST API để truy vấn danh sách task theo user và group", chúng ta sẽ đi sâu vào khía cạnh kỹ thuật, khám phá các endpoint API mà Camunda cung cấp để bạn có thể bắt đầu xây dựng giao diện quản lý tác vụ tùy chỉnh của riêng mình.