diff --git a/packages/devui-vue/devui/code-review/src/code-review.tsx b/packages/devui-vue/devui/code-review/src/code-review.tsx index ef34cca27c..c1ea435294 100644 --- a/packages/devui-vue/devui/code-review/src/code-review.tsx +++ b/packages/devui-vue/devui/code-review/src/code-review.tsx @@ -14,7 +14,7 @@ import './code-review.scss'; export default defineComponent({ name: 'DCodeReview', props: codeReviewProps, - emits: ['foldChange', 'addComment', 'afterViewInit', 'contentRefresh'], + emits: ['foldChange', 'addComment', 'afterViewInit', 'contentRefresh', 'afterCheckLines'], setup(props: CodeReviewProps, ctx: SetupContext) { const ns = useNamespace('code-review'); const { diffType } = toRefs(props); diff --git a/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts b/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts index 2bbcd41ab6..7df895e24f 100644 --- a/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts +++ b/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts @@ -14,7 +14,7 @@ import { export function useCodeReviewComment(reviewContentRef: Ref, props: CodeReviewProps, ctx: SetupContext) { const { outputFormat, allowComment, allowChecked } = toRefs(props); const ns = useNamespace('code-review'); - const { onMousedown } = useCodeReviewLineSelection(reviewContentRef, props, updateLineNumbers, updateLineNumbers); + const { onMousedown } = useCodeReviewLineSelection(reviewContentRef, props, updateLineNumbers, updateLineNumbers, afterCheckLines); const commentLeft = ref(-100); const commentTop = ref(-100); let currentLeftLineNumber = -1; @@ -24,6 +24,8 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: let currentLeftLineNumbers: Array = []; let currentRightLineNumbers: Array = []; let checkedLineCodeString: Array | Record> = {}; + let allTrNodes: NodeListOf = []; + let afterCheckLinesEmitData: Record; watch( () => outputFormat.value, () => { @@ -137,11 +139,9 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: }; // 获取一些公共类和判断 const getCommonClassAndJudge = () => { - const lineClassName = props.outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber'; - const linenumberDom = reviewContentRef.value.querySelectorAll(lineClassName); const checkedLine = [currentLeftLineNumbers, currentRightLineNumbers]; return { - linenumberDom, + linenumberDom: allTrNodes, checkedLine, }; }; @@ -217,6 +217,15 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: currentRightLineNumbers = currentRightLineNumber === -1 ? currentRightLineNumbers : getLineNumbers(currentRightLineNumber, currentRightLineNumbers); getCheckedLineCode(false); + afterCheckLinesEmitData = { + left: currentLeftLineNumber, + right: currentRightLineNumber, + details: { + lefts: currentLeftLineNumbers, + rights: currentRightLineNumbers, + codes: checkedLineCodeString, + }, + }; } const updateCheckedLineClass = () => { getCheckedLineCode(true); @@ -266,6 +275,9 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: // 点击添加评论图标触发的事件 ctx.emit('addComment', obj); }; + function afterCheckLines() { + ctx.emit('afterCheckLines', afterCheckLinesEmitData); + } // 图标或者单行的点击 const onCommentIconClick = (e: Event) => { if (e) { @@ -327,13 +339,19 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: resetCommentClass(); }; + const handleMouseDown = (e: MouseEvent) => { + const lineClassName = props.outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber'; + allTrNodes = reviewContentRef.value.querySelectorAll(lineClassName); + onMousedown(e); + }; + const mouseEvent: Record void> = {}; if (allowComment.value) { mouseEvent.onMousemove = onMouseMove; mouseEvent.onMouseleave = onMouseleave; } if (props.allowChecked) { - mouseEvent.onMousedown = onMousedown; + mouseEvent.onMousedown = handleMouseDown; } window.addEventListener('scroll', resetLeftTop); diff --git a/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts b/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts index 4aa9ba0829..2525ffed52 100644 --- a/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts +++ b/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts @@ -7,6 +7,7 @@ export function useCodeReviewLineSelection( reviewContentRef: Ref, props: CodeReviewProps, mouseDownCb: () => void, + mouseMoveCb: () => void, mouseupCb: () => void ) { const ns = useNamespace('code-review'); @@ -14,6 +15,7 @@ export function useCodeReviewLineSelection( let startTrNode: HTMLElement; let trNodes: HTMLElement[]; let isClickedLeft: boolean | undefined; + let shouldClear: boolean; let isMouseMoved: boolean; const onMousedown = (e: MouseEvent) => { @@ -41,6 +43,7 @@ export function useCodeReviewLineSelection( } dragging = true; + shouldClear = true; isMouseMoved = false; mouseDownCb(); e.preventDefault(); @@ -55,6 +58,10 @@ export function useCodeReviewLineSelection( return; } isMouseMoved = true; + if (shouldClear) { + clearCommentChecked(); + shouldClear = false; + } const composedPath = e.composedPath() as HTMLElement[]; const inReviewContent = composedPath.some((item) => item.classList?.contains(ns.e('content'))); if (!inReviewContent) { @@ -69,6 +76,7 @@ export function useCodeReviewLineSelection( if (endIndex === -1) { return; } + mouseMoveCb(); if (startIndex > endIndex) { [startIndex, endIndex] = [endIndex, startIndex]; } @@ -99,6 +107,13 @@ export function useCodeReviewLineSelection( document.removeEventListener('mousemove', onMousemove); } + // 清除上次的选中 + function clearCommentChecked() { + for (let i = 0; i < trNodes.length; i++) { + toggleCommentCheckedClass(trNodes[i], false, 'all'); + } + } + function toggleCommentCheckedClass(trNode: HTMLElement, isAddClass: boolean, position: 'left' | 'right' | 'all') { const tdNodes = Array.from(trNode.children); let toDoNodes; @@ -109,7 +124,7 @@ export function useCodeReviewLineSelection( } else { toDoNodes = tdNodes.slice(2); } - if ((position === 'left' || position === 'right') && isNaN(parseInt(toDoNodes[0].innerHTML))) { + if ((position === 'left' || position === 'right') && isNaN(parseInt(toDoNodes[0]?.innerHTML))) { return; } toDoNodes.forEach((item) => { diff --git a/packages/devui-vue/docs/components/code-review/index.md b/packages/devui-vue/docs/components/code-review/index.md index c4663fe8c0..831b38849b 100644 --- a/packages/devui-vue/docs/components/code-review/index.md +++ b/packages/devui-vue/docs/components/code-review/index.md @@ -597,6 +597,7 @@ export default defineComponent({ | add-comment | `Function(position: CommentPosition)` | 点击添加评论图标时触发的事件,参数内容详见[CommentPosition](#commentposition) | | after-view-init | `Function(methods: CodeReviewMethods)` | 初始化完成后触发的事件,返回相关操作方法,参数内容详见[CodeReviewMethods](#codereviewmethods) | | content-refresh | `Function(diffFile: DiffFile)` | 内容刷新后触发的事件,返回解析后的相关文件信息,参数内容详见[DiffFile](https://github.com/rtfpessoa/diff2html/blob/master/src/types.ts#L49) | +|after-check-lines|`Function(position: CommentPosition)`|多行选中后触发的事件,参数内容详见[CommentPosition](#commentposition)| ### CodeReview 插槽