diff --git a/components/work-review/WorkReviewAnnotationMarker.tsx b/components/work-review/WorkReviewAnnotationMarker.tsx index e5dbc95..50d7228 100644 --- a/components/work-review/WorkReviewAnnotationMarker.tsx +++ b/components/work-review/WorkReviewAnnotationMarker.tsx @@ -8,6 +8,7 @@ export type WorkReviewDisplayAnnotation = { reviewerName?: string reviewerRole?: WorkReviewRole draft?: boolean + positionEditable?: boolean } function markerTone(item: WorkReviewDisplayAnnotation) { @@ -33,7 +34,8 @@ export function WorkReviewAnnotationMarker({ ? '元泽' : '评审人' const summary = annotation.comment.trim() || '待填写修改意见' - const label = `${roleLabel}标注 ${item.markerNumber}${item.reviewerName ? `,${item.reviewerName}` : ''}:${summary}` + const positionState = item.positionEditable ? ',位置可调整' : '' + const label = `${roleLabel}标注 ${item.markerNumber}${positionState}${item.reviewerName ? `,${item.reviewerName}` : ''}:${summary}` const visualTitle = showComment ? label : `${roleLabel}标注 ${item.markerNumber}` return ( @@ -44,12 +46,13 @@ export function WorkReviewAnnotationMarker({ onClick?.() }} onPointerDown={(event) => event.stopPropagation()} + onPointerUp={(event) => event.stopPropagation()} aria-label={label} title={visualTitle} - className="group absolute z-20 h-11 w-11 -translate-x-1/2 -translate-y-1/2 outline-none" + className={`group absolute z-20 h-11 w-11 -translate-x-1/2 -translate-y-1/2 outline-none ${item.positionEditable ? 'cursor-move' : 'cursor-pointer'}`} style={{ left: `${annotation.x * 100}%`, top: `${annotation.y * 100}%` }} > - + {item.markerNumber} annotationCount?: number showAnnotationComments?: boolean onToggleAnnotationMode?: () => void onToggleAnnotationComments?: () => void onAddAnnotation?: (x: number, y: number) => void + onMoveAnnotation?: (x: number, y: number) => void onSelectDraftAnnotation?: (annotationId: string) => void }) { const displayGroups = useMemo( @@ -121,6 +127,7 @@ function LongImagePane({ Math.max(0, displayGroups.length - 1), ) const activeGroup = displayGroups[activeIndex] + const placementMode = annotationMode || annotationRepositionMode useEffect(() => { if (controlledActiveIndex == null) setInternalActiveIndex(0) @@ -136,7 +143,11 @@ function LongImagePane({ if (bounds.width <= 0 || bounds.height <= 0) return const x = Math.min(1, Math.max(0, (clientX - bounds.left) / bounds.width)) const y = Math.min(1, Math.max(0, (clientY - bounds.top) / bounds.height)) - onAddAnnotation?.(x, y) + if (annotationRepositionMode) { + onMoveAnnotation?.(x, y) + } else { + onAddAnnotation?.(x, y) + } } return ( @@ -148,8 +159,9 @@ function LongImagePane({