valine ranking 10/22/2020
最近更新于:

评论排行

同样的,先前在浏览其他主题偶然发现了评论统计这么一个东西,数据统计了所有用户评论数量及用户信息(昵称、邮件头像等)然后将数据写入到页面展示出来,感觉还蛮好玩的,当时对 valine 不太了解所以没有下文,不过现在这个功能已经可以使用 Leancloud 在 Valine 评论中实现了~

二级菜单内的评论排行

前言

在具体实现前简单聊下,当时我打算做这个功能的时候思路不太对,然后绕了很多圈子,其实实现起来很简单的东西,不过我这个倔脾气导致我一直绕圈圈搞半天。然后说下之前的思路,我之前想的是因为 Valine 每当有新用户评论之后如果昵称邮件等信息正确就会将该用户存入 leancloud 后台的 _User 表,我也就想的是通过 _User 这个表来匹配 Comment 表内符合昵称(nick/username)或邮件(mail/email)获取对应用户的评论信息数据,然后踩了很多坑..

踩的坑

说起坑,首先就是 _User 表默认是不可查找(find)的(官方文档中表示这样做是为了用户数据安全),不过还好,正确获取之后报了 403 错误,当时就想到是权限问题,随后在 leancloud 后台将 find 设置为所有用户之后正常获取到了用户数据,其中就包括用户昵称和邮件,通过邮件我们可以拿到 gravatar 头像,然后就是评论数据匹配的问题了,这是个大坑!

为什么说数据匹配是坑,首先我表示 leancloud 是对开发版做了请求限制的(在我的测试中这个限制貌似只有几个)所以通过返回 _User 表的用户数据去对比 Comment 表的数据根本上来说是不能实现的,再一个就是获取到对比数据之后,也无法匹配用户的评论数量,然后去查了官方文档,反正是各种方案都没卵用,非常头疼。当然了,最致命的还是请求限制..

新思路

这里我又要吐槽下我自己,有些蛋疼的事情太较真浪费了非常多的时间和精力在上面,最后要不不了了之要不改变思路方向。在上面各种办法试过之后,我突然灵光一闪想起那 _User 表里有用户数据 Comment 表里不也有吗?那我直接请求 Comment 表然后过滤用户数据不就行了,而且连对比都不用了!因为可以直接通过用户信息检索用户评论过的评论数据,这不是直接就返回了用户评论数量了么,而且还能返回其他各种用户评论信息,这一下子思路清晰感觉就很爽了。

有了新的思路之后要做起来就不难了,主要还是思路,正确的思路能少走不少弯路,后面就直接聊这后面的思路方案了。

具体实现

首先还是初始化 valine 并新建 Comment 表查询,往期笔记里都有就不重复写了(注意,如果你像我一样将评论排行写在单独页面时,不要忘记引用 leancloud SDK)

<script src="https://cdn.jsdelivr.net/npm/leancloud-storage@4.6.1/dist/av-min.js"></script>

然后照着下面代码写就对了(注释下次加上)

var query = new AV.Query("Comment"),  //新建 Comment 表查询
    max = 999,  //最大请求数(可选,默认1000)
    comArr = [],  //创建空数组用于填充 Comment 筛选后的数据
    compare = (reply) => {  //数组对象对比排序函数
        return function(a,b){
            var a = a[reply];
            var b = b[reply];
            return b - a;
        }
    };

query.limit(max).find().then(res => {
    var temp = [],  //临时数组1
        temps = [],  //临时数组2
        obj = {};  //空对象
    for (let i=0;i<res.length;i++) {
        let nick = res[i].attributes.nick,
            mail = res[i].attributes.mail;
        comArr.push({nick,mail});  //写入从 Comment 查询到的昵称和邮件到数组
    }
    //遍历 Comment 数组对象
    for(k in comArr){
        let name = comArr[k].nick,
            mail = comArr[k].mail;
        temp.push({name,mail})  //读取 Comment 数组数据并写入到临时数组1
    }
    //遍历临时数组1
    for(let i=0;i<temp.length;i++){
        let _item = temp[i],
            n = _item.name,
            m = _item.mail;
        obj[n+'['+m+']'] = obj[n+'['+m+']']+1 || 1;  //计算数组中重复出现的元素个数并写入到空对象(这个原理我还不是特别清楚)
    }
    //遍历空对象
    for(k in obj){
        let t = obj[k],
            _m = k.indexOf('[')+1,  //索引 [
            m_ = k.indexOf(']'),  //索引 ]
            m = k.substring(_m,m_),  //截取 [之间的内容]
            _n_ = k.substring(_m-1,m_+1),  //截取包括[]之内的内容
            n = k.replace(_n_,"");  //移除 包括[] 之内的内容
        temps.push({n,m,t});  //将昵称、邮件、次数写入临时数组2
        temps.sort(compare('t'));  //对比评论次数t来排序临时数组2
    }
    console.log(temps)
})

排行链接位置( 评论排行(ranks)页面 )没写详细的下次再写

二级菜单内的评论排行

参考链接

js--计算数组中重复出现元素的个数
如何理解JavaScript中obj[item] = (obj[item] +1 || 0)
Gravatar 头像解析 - 保罗|API


以上,有问题评论区留言。