Skip to content

批注(或评论)

批注功能和 Word 的批注评论功能类似,可以选择一段文字对齐进行批注,如下图所示:

PS:此功能在 Pro 版本才有,开源版没有这个功能。 Pro 版预览地址:http://pro.aieditor.com.cn

使用方法

typescript
new AiEditor({
    element: "#aiEditor",
    comment: {
        enable: true,
        floatable: false,
        containerClassName: "comment-container",

        // currentAccountAvatar: "https://aieditor.com.cn/logo.png",
        currentAccount:"Miachel Yang",
        currentAccountId: "1",
        enableWithEditDisable: true,
        
        onCommentActivated: (commentIds) => {
            // 当评论区域获得焦点
        },

        queryAllComments: () => {
            // 查询当前文档的所有评论,返回 CommentInfo[] 或者 Promise<CommentInfo[]>
        },

        queryMyComments: () => {
            // 查询 “我的评论”,返回 CommentInfo[] 或者 Promise<CommentInfo[]>
        },

        queryCommentsByIds: (commentIds) => {
            // 根据多个文档id,查询多条评论,返回 CommentInfo[] 或者 Promise<CommentInfo[]>
        },

        onCommentCreate: (comment) => {
            // 当评论被创建时,,返回 CommentInfo 或者 Promise<CommentInfo>
        },

        onCommentDeleteConfirm:(comment)=>{
            // 当评论被删除时,弹出确认框,返回 boolean 或者  Promise<boolean>;
        },

        onCommentDelete: (commentId) => {
            // 当评论被删除时, 返回 boolean 或者  Promise<boolean>;
        },

        onCommentUpdate: (commentId, content) => {
            // 当评论被修改时,返回 boolean 或者  Promise<boolean>;
        },
    },
})
  • enable: 是否启用评论功能
  • floatable: 评论的内容,是否是跟评论区域位置浮动的
  • containerClassName: 自定义评论区域的 class 名称,用于自定义样式
  • currentAccountAvatar: 在 floatable = false 时,配置显示头像
  • currentAccount: 配置当前用户的名称,用于显示在评论中
  • currentAccountId: 配置当前用户的id
  • enableWithEditDisable: 是否在只读模式下,也开启批注(评论)的功能,默认为 false
  • onCommentActivated: 评论获得焦点时,会触发此回调
  • onCommentCreate: 监听评论被创建,此时我们应该把评论内容保存到数据库,并返回完整的评论信息
  • onCommentDeleteConfirm: 监听评论被删除,弹出确认框,返回 boolean 或者 Promise<boolean>
  • onCommentDelete: 监听评论被删除,此时应该同步删除数据库的评论
  • onCommentUpdate: 监听评论被修改
  • queryAllComments: 查询所有的评论(当配置 floatable: false 是有效)
  • queryMyComments: 查询 我的评论(当配置 floatable: false 是有效)
  • queryCommentsByIds: 根据多条评论 id,查询所有的评论(当配置 floatable: true 是有效)

示例代码

以下的示例代码,是使用了 LocalStorage 来保存评论内容

typescript
const colors = ['#3f3f3f', '#938953', '#548dd4', '#95b3d7',
    '#d99694', '#c3d69b', '#b2a2c7', '#92cddc', '#fac08f'];
new AiEditor({
    element: "#aiEditor",
    comment: {
        enable: true,
        floatable: false,
        enableWithEditDisable: true,
        onCommentActivated: (_commentId) => {
            // console.log("onCommentActivated---->", commentId)
        },

        queryAllComments: () => {
            const allCommentsString = localStorage.getItem("all-comments");
            const allCommentIds = allCommentsString ? JSON.parse(allCommentsString) : [];
            const allComments = [] as any[];
            allCommentIds.forEach((commentId: any) => {
                const contentJSON = localStorage.getItem(commentId);
                if (contentJSON) allComments.push(JSON.parse(contentJSON));
            })
            return allComments;
        },

        queryCommentsByIds: (commentIds) => {
            const allComments = [] as any[];
            if (commentIds) commentIds.forEach((commentId: any) => {
                const contentJSON = localStorage.getItem("comment-" + commentId);
                if (contentJSON) allComments.push(JSON.parse(contentJSON));
            })
            return allComments;
        },


        onCommentCreate: (comment) => {
            console.log("onCommentCreate---->", comment)
            comment = {
                ...comment,
                account: "张三",
                // avatar: Math.floor(Math.random() * 10) > 3 ? "https://aieditor.dev/assets/image/logo.png" : undefined,
                mainColor: colors[Math.floor(Math.random() * colors.length)],
                createdAt: "05-26 10:23",
            } as CommentInfo;

            localStorage.setItem("comment-" + comment.id, JSON.stringify(comment));

            const allCommentsString = localStorage.getItem("all-comments");
            const allComments = allCommentsString ? JSON.parse(allCommentsString) : [];

            if (comment.pid) {
                const parentCommentJSON = localStorage.getItem("comment-" + comment.pid);
                if (parentCommentJSON) {
                    const parentComment = JSON.parse(parentCommentJSON);
                    if (parentComment.children) {
                        parentComment.children.unshift(comment)
                    } else {
                        parentComment.children = [comment]
                    }
                    localStorage.setItem("comment-" + comment.pid, JSON.stringify(parentComment));
                }
            } else {
                allComments.push("comment-" + comment.id)
            }


            localStorage.setItem("all-comments", JSON.stringify(allComments));

            // return callback(comment);
            return new Promise((resolve) => {
                resolve(comment)
            })
            // return comment;
        },


        onCommentDeleteConfirm: (comment) => {
            console.log("onCommentDeleteConfirm---->", comment)
            return confirm("确认要删除吗");
        },
        
        
        onCommentDelete: (commentId) => {
            console.log("onCommentDelete---->", commentId)

            const commentInfo = JSON.parse(localStorage.getItem("comment-" + commentId)!);
            if (commentInfo.pid) {
                const parentCommentJSON = localStorage.getItem("comment-" + commentInfo.pid);
                if (parentCommentJSON) {
                    const parentComment = JSON.parse(parentCommentJSON);
                    if (parentComment.children) {
                        parentComment.children = parentComment.children.filter((item: any) => item.id !== commentId)
                        localStorage.setItem("comment-" + commentInfo.pid, JSON.stringify(parentComment));
                    }
                }
            }
            localStorage.removeItem("comment-" + commentId);
            return true;
        },

        onCommentUpdate: (commentId, content) => {
            console.log("onCommentUpdate---->", commentId, content)
            const commentInfo = JSON.parse(localStorage.getItem("comment-" + commentId)!);
            commentInfo.content = content
            localStorage.setItem("comment-" + commentId, JSON.stringify(commentInfo))
            return true
        }
    },
})

CommentInfo 评论信息描述

  • id: comment id, globally unique
  • pid: comment parent id
  • content: comment content
  • account: comment account or nickname
  • accountId: account id
  • avatar: user avatar URL address
  • createdAt: comment time
  • mainColor: background color of comment text
  • commentFor?: commented content,
  • replyAccount?: reply account (who is replying to?),
  • replyAccountId?: reply account id (who is replying to?),
  • children?: CommentInfo[],