[]
        
(Showing Draft Content)

충돌 감지 및 처리

스케줄러는 이벤트 간 시간 중복이나 설정된 비작업 시간과 겹치는 이벤트를 감지할 수 있습니다. 기본적으로 충돌 감지는 정보 제공용으로만 동작합니다. 충돌이 발생한 작업을 허용하지 않으려면 애플리케이션에서 conflictChecked 이벤트를 취소하도록 처리하세요.

충돌하는 변경 거부

conflictChecked는 유효한 생성 또는 업데이트 후보가 계산된 후, 실제로 반영되기 전에 실행됩니다. 마우스를 사용한 이동 및 크기 조정 작업에서도 실행됩니다.

scheduler.conflictChecked.addHandler((_sender, args) => {
  const conflicts = args.result?.conflicts ?? [];
  if (conflicts.length > 0) {
    showConflictWarning(conflicts);
    args.cancel = true;
  }
});

충돌을 표시하거나 로그에 기록하거나 검토 절차로 전달하는 것이 목적이라면 args.cancel 값을 변경하지 마세요. 최종 유효성 검사는 서버에서 수행해야 합니다.

필요한 작업

사용 방법

프로그래밍 방식 요청의 충돌 확인

result.conflicts를 확인합니다.

대기 중인 요청 거부

conflictChecked에서 args.cancel = true로 설정합니다.

충돌 감지 전에 요청 중단

itemChanging에서 args.cancel = true로 설정합니다.

승인된 요청 저장

itemChanged를 처리합니다.

충돌 결과 읽기

args.result.conflicts에는 충돌 레코드가 0개 이상 포함됩니다. 하나의 결과에 두 유형이 모두 포함될 수 있습니다.

유형

의미

세부 정보 속성

SchedulerConflictType.TimeOverlap

후보 이벤트가 로드된 다른 이벤트와 시간상 겹칩니다.

conflictingItems

SchedulerConflictType.NonWorkingTime

후보 이벤트가 설정된 비작업 시간과 겹칩니다.

conflictingTimeRanges

비즈니스 규칙을 다르게 적용할 때는 배열 순서가 아니라 conflict.type을 사용하세요.

scheduler.conflictChecked.addHandler((_sender, args) => {
  for (const conflict of args.result?.conflicts ?? []) {
    if (conflict.type === wjScheduler.SchedulerConflictType.TimeOverlap) {
      notifyOverlap(conflict.conflictingItems);
    }
    if (conflict.type === wjScheduler.SchedulerConflictType.NonWorkingTime) {
      notifyUnavailable(conflict.conflictingTimeRanges);
    }
  }
});

작업이 충돌 검사 단계까지 진행된 경우에만 결과를 사용할 수 있습니다. 유효성 검사에 실패하거나 그 전에 취소 가능한 이벤트에서 요청이 중단되면 결과가 제공되지 않을 수 있습니다.

충돌 판정 규칙

  • 이벤트 시간 범위는 [start, end)로 처리하므로, 종료 시간과 다음 이벤트의 시작 시간이 같으면 충돌로 판정하지 않습니다.

  • 리소스가 설정된 경우, 두 이벤트가 공통으로 사용하는 모든 리소스 필드의 값이 일치해야 충돌로 판정됩니다.

  • 비어 있거나 알 수 없는 리소스 값은 무시됩니다. 리소스 데이터 소스가 비어 있으면 해당 리소스는 매칭에 사용되지 않습니다.

  • 리소스가 구성되어 있지만 두 이벤트 모두 유효한 리소스 값이 없으면 TimeOverlap 충돌은 발생하지 않습니다.

  • 비작업 시간과의 충돌은 리소스와 관계없이 전역적으로 판정됩니다.

  • 이벤트 중복 검사는 현재 스케줄러에 로드된 이벤트만 대상으로 합니다.

예를 들어 roomId를 리소스 매칭 기준으로 사용하는 경우 다음과 같습니다.

이벤트 A

이벤트 B

시간 중복 충돌

09:00–10:00, 회의실 A

10:00–11:00, 회의실 A

아니요. 시간 범위가 맞닿아 있습니다.

09:00–10:00, 회의실 A

09:30–10:30, 회의실 A

예

09:00–10:00, 회의실 A

09:30–10:30, 회의실 B

아니요. 리소스 값이 다릅니다.

리소스 필드가 여러 개라면 두 이벤트가 모두 설정한 각 필드의 값이 일치해야 합니다. 예를 들어 teamId와 regionId가 모두 일치해야 중복으로 판정됩니다. 둘 중 하나라도 값이 다르면 TimeOverlap 충돌이 발생하지 않습니다.

리소스 설정

이벤트 A

이벤트 B

시간 중복 판정

리소스가 설정되지 않음

할당 없음

할당 없음

시간 중복이 보고됩니다.

리소스가 설정됨

유효한 할당 없음

유효한 할당 없음

TimeOverlap이 보고되지 않습니다.

리소스가 설정됨

team=A, region=East

team=A, region=East

시간 중복이 보고됩니다.

리소스가 설정됨

team=A, region=East

team=A, region=West

리소스 값이 다르므로 TimeOverlap이 보고되지 않습니다.

업데이트 결과에서 충돌 확인

애플리케이션 코드에서 업데이트 메서드를 호출한 경우, 작업이 유효성 검사와 충돌 감지 단계를 거친 후 반환 결과를 확인하세요.

const event = scheduler.getEvents(undefined, undefined, [
  { fieldExpr: 'id', value: 1 },
])[0];

if (event) {
  const result = scheduler.update(event, {
    start: new Date(2026, 7, 24, 9, 30),
    end: new Date(2026, 7, 24, 10, 30),
  });
  const conflicts = result.conflicts ?? [];
}

update에는 현재 스케줄러 컬렉션에 있는 원본 객체를 전달해야 합니다. 복사본이나 렌더링된 이벤트 인스턴스, 다른 컬렉션에 있는 항목은 전달하지 마세요.

애플리케이션에서 작업을 취소하려면 이벤트 핸들러를 사용하고, 프로그래밍 방식으로 요청 결과를 확인하거나 기록하려면 반환값을 사용하세요.

반환값은 프로그래밍 방식으로 요청한 작업의 결과를 알려주지만, conflictChecked 이벤트에서 작업을 취소하는 기능을 대신하지는 않습니다. itemChanging에서 요청이 취소되면 충돌 검사 단계까지 진행되지 않을 수 있으므로 충돌 결과가 반환되지 않을 수 있습니다.

충돌 이벤트 스타일 지정

하나 이상의 충돌이 있는 이벤트에는 스케줄러가 wj-scheduler-item-conflict 클래스를 적용합니다.

.wj-scheduler-item-conflict {
  outline: 2px solid #dc2626;
  outline-offset: -2px;
}

사용자 지정 항목 템플릿에서는 SchedulerItemTemplateContext.conflicts를 읽고 각 충돌 유형에 따라 세부 정보를 렌더링할 수 있습니다. 충돌 표시는 원본 이벤트 데이터와 분리해서 처리하세요.