laravel + redis 实现排行榜

1.控制器

          这里为什么要用redis 有序集合 (sorted set)  因为

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。

  //  模拟数据
        Redis::zadd('_ranking',0,1);
        Redis::zadd('_ranking',1,2);
        Redis::zadd('_ranking',2,3);
        Redis::zadd('_ranking',3,4);
        Redis::zadd('_ranking',4,5);
        Redis::zadd('_ranking',5,6);
        Redis::zadd('_ranking',6,7);
        Redis::zadd('_ranking',7,8);
        Redis::zadd('_ranking',8,9);
        Redis::zadd('_ranking',9,10);

// 按照权重的从大到小  列出成员
$data = Redis::zRevRange('_ranking',0,9);

这个是打印出来的结果

 

因为在此之前我存储的成员 就是我数据表里面的id  所以在下面我又进行了对模型的查询

        
//把上面数组 转化成 字符串 后面要用
$ids = implode(',',$data);
             // 显示权重排行
        $score = Redis::zRevRange('_ranking',0,9,true);
            //改变他原有的数组模式
        $score = explode(',',implode(',',$score));

//按照顺序 弄好排行榜
        $rankingData = Doctor::whereIn('id',$data)
       ->orderByRaw(DB::raw("FIELD(id, $ids)"))->paginate();

        //查看权重
        foreach ($rankingData as $key => $val)
        {
            $val['score'] = $score[$key];
        }


        return $rankingData;

2.HTML样式

<div>
    <article class="leaderboard">
        <header>

            <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 511.999 511.999" style="enable-background:new 0 0 511.999 511.999;" xml:space="preserve" class="leaderboard__icon">
      <g>
          <g>
              <path d="M466.45,49.374c-7.065-8.308-17.368-13.071-28.267-13.071H402.41v-11.19C402.41,11.266,391.143,0,377.297,0H134.705
			c-13.848,0-25.112,11.266-25.112,25.112v11.19H73.816c-10.899,0-21.203,4.764-28.267,13.071
			c-6.992,8.221-10.014,19.019-8.289,29.624c9.4,57.8,45.775,108.863,97.4,136.872c4.717,11.341,10.059,22.083,16.008,32.091
			c19.002,31.975,42.625,54.073,68.627,64.76c2.635,26.644-15.094,51.885-41.794,57.9c-0.057,0.013-0.097,0.033-0.153,0.046
			c-5.211,1.245-9.09,5.921-9.09,11.513v54.363h-21.986c-19.602,0-35.549,15.947-35.549,35.549v28.058
			c0,6.545,5.305,11.85,11.85,11.85H390.56c6.545,0,11.85-5.305,11.85-11.85v-28.058c0-19.602-15.947-35.549-35.549-35.549h-21.988
			V382.18c0-5.603-3.893-10.286-9.118-11.52c-0.049-0.012-0.096-0.028-0.145-0.04c-26.902-6.055-44.664-31.55-41.752-58.394
			c25.548-10.86,48.757-32.761,67.479-64.264c5.949-10.009,11.29-20.752,16.008-32.095c51.622-28.01,87.995-79.072,97.395-136.87
			C476.465,68.392,473.443,57.595,466.45,49.374z M60.652,75.192c-0.616-3.787,0.431-7.504,2.949-10.466
			c2.555-3.004,6.277-4.726,10.214-4.726h35.777v21.802c0,34.186,4.363,67.3,12.632,97.583
			C89.728,153.706,67.354,116.403,60.652,75.192z M366.861,460.243c6.534,0,11.85,5.316,11.85,11.85v16.208H134.422v-16.208
			c0-6.534,5.316-11.85,11.85-11.85H366.861z M321.173,394.03v42.513H191.96V394.03H321.173z M223.037,370.331
			c2.929-3.224,5.607-6.719,8.002-10.46c7.897-12.339,12.042-26.357,12.228-40.674c4.209,0.573,8.457,0.88,12.741,0.88
			c4.661,0,9.279-0.358,13.852-1.036c0.27,19.239,7.758,37.45,20.349,51.289H223.037z M378.709,81.803
			c0,58.379-13.406,113.089-37.747,154.049c-23.192,39.03-53.364,60.525-84.956,60.525c-31.597,0-61.771-21.494-84.966-60.523
			c-24.342-40.961-37.748-95.671-37.748-154.049V25.112c0-0.78,0.634-1.413,1.412-1.413h242.591c0.78,0,1.414,0.634,1.414,1.413
			V81.803z M451.348,75.192c-6.702,41.208-29.074,78.51-61.569,104.191c8.268-30.283,12.631-63.395,12.631-97.58V60.001h35.773
			c3.938,0,7.66,1.723,10.214,4.726C450.915,67.688,451.963,71.405,451.348,75.192z" />
          </g>
      </g>
                <g>
                    <g>
                        <path d="M327.941,121.658c-1.395-4.288-5.103-7.414-9.566-8.064l-35.758-5.196l-15.991-32.402
			c-1.997-4.044-6.116-6.605-10.626-6.605c-4.511,0-8.63,2.561-10.626,6.605l-15.991,32.402l-35.758,5.196
			c-4.464,0.648-8.172,3.775-9.566,8.065c-1.393,4.291-0.231,8.999,2.999,12.148l25.875,25.221l-6.109,35.613
			c-0.763,4.446,1.064,8.938,4.714,11.59c3.648,2.651,8.487,3,12.479,0.902L256,190.32l31.982,16.813
			c1.734,0.911,3.627,1.36,5.512,1.36c2.456,0,4.902-0.763,6.966-2.263c3.65-2.652,5.477-7.144,4.714-11.59l-6.109-35.613
			l25.875-25.221C328.172,130.658,329.334,125.949,327.941,121.658z M278.064,146.405c-2.793,2.722-4.068,6.644-3.408,10.489
			l3.102,18.09l-16.245-8.541c-1.725-0.908-3.62-1.36-5.514-1.36c-1.894,0-3.788,0.454-5.514,1.36l-16.245,8.541l3.102-18.09
			c0.66-3.844-0.615-7.766-3.408-10.489l-13.141-12.81l18.162-2.64c3.859-0.56,7.196-2.985,8.922-6.482l8.123-16.458l8.122,16.458
			c1.727,3.497,5.062,5.921,8.922,6.482l18.162,2.64L278.064,146.405z" />
                    </g>
                </g>
    </svg>

            <h1 class="leaderboard__title"><span class="leaderboard__title--top">慢热医疗</span><span class="leaderboard__title--bottom">热门医生排行榜</span></h1>
        </header>

        <main class="leaderboard__profiles">
            @foreach($rankingData as $val)
            <article class="leaderboard__profile">
                <img src="{{$val['doctor_pic']}}" alt="Mark Zuckerberg" class="leaderboard__picture">
                <span class="leaderboard__name">{{$val['doctor_name']}}</span>
                <span class="leaderboard__value"><span>挂号量:</span>{{$val['score']}}</span>
            </article>
            @endforeach
        </main>
    </article>
</div>

3. css


    <style>
        .leaderboard {
            max-width: 490px;
            width: 100%;
            border-radius: 12px;
        }
        .leaderboard header {
            --start: 15%;
            height: 130px;
            background-image: repeating-radial-gradient(circle at var(--start), transparent 0%, transparent 10%, rgba(54, 89, 219, 0.33) 10%, rgba(54, 89, 219, 0.33) 17%), linear-gradient(to right, #5b7cfa, #3659db);
            color: #fff;
            position: relative;
            border-radius: 12px 12px 0 0;
            overflow: hidden;
        }
        .leaderboard header .leaderboard__title {
            position: absolute;
            z-index: 2;
            top: 50%;
            right: calc(var(--start) * .75);
            transform: translateY(-50%);
            text-transform: uppercase;
            margin: 0;
        }
        .leaderboard header .leaderboard__title span {
            display: block;
        }
        .leaderboard header .leaderboard__title--top {
            font-size: 24px;
            font-weight: 700;
            letter-spacing: 6.5px;
        }
        .leaderboard header .leaderboard__title--bottom {
            font-size: 13px;
            font-weight: 500;
            letter-spacing: 3.55px;
            opacity: .65;
            transform: translateY(-2px);
        }
        .leaderboard header .leaderboard__icon {
            fill: #fff;
            opacity: .35;
            width: 50px;
            position: absolute;
            top: 50%;
            left: var(--start);
            transform: translate(-50%, -50%);
        }
        .leaderboard__profiles {
            background-color: #fff;
            border-radius: 0 0 12px 12px;
            padding: 15px 15px 20px;
            display: grid;
            row-gap: 8px;
        }
        .leaderboard__profile {
            display: grid;
            grid-template-columns: 1fr 3fr 1fr;
            align-items: center;
            padding: 10px 30px 10px 10px;
            overflow: hidden;
            border-radius: 10px;
            box-shadow: 0 5px 7px -1px rgba(51, 51, 51, 0.23);
            cursor: pointer;
            transition: transform 0.25s cubic-bezier(0.7, 0.98, 0.86, 0.98), box-shadow 0.25s cubic-bezier(0.7, 0.98, 0.86, 0.98);
            background-color: #fff;
        }
        .leaderboard__profile:hover {
            transform: scale(1.2);
            box-shadow: 0 9px 47px 11px rgba(51, 51, 51, 0.18);
        }
        .leaderboard__picture {
            max-width: 100%;
            width: 60px;
            border-radius: 50%;
            box-shadow: 0 0 0 10px #ebeef3, 0 0 0 22px #f3f4f6;
        }
        .leaderboard__name {
            color: #979cb0;
            font-weight: 600;
            font-size: 20px;
            letter-spacing: 0.64px;
            margin-left: 12px;
        }
        .leaderboard__value {
            color: #0e90d2;
            font-weight: 700;
            font-size: 30px;
            text-align: right;
            margin-top: 4px;
        }
        .leaderboard__value > span {
            opacity: .8;
            font-weight: 600;
            font-size: 16px;
            margin-left: 6px;
            margin-top: -11px;
        }

        body {
            margin: 0;
            background-color: #eaeaea;
            display: grid;
            height: 100vh;
            place-items: center;
            font-family: 'Source Sans Pro', sans-serif;
        }

        .leaderboard {
            box-shadow: 0 0 40px -10px rgba(0, 0, 0, 0.4);
        }

    </style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥都不多头发多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值