Tp5 结合redis实现粉丝关注取关

思路:

数据库存储的都是用户id,先将数据存在redis 有序序列 value为id,sorce为时间戳

利用redis判断是 相互关注 还是 单关注

然后再进行mysql数据库操作

 

mysql:

 

 

 

Base基础类

class Base extends Controller //控制器封装类
{
    //是否为数字
    public function is_num($id)
    {
        if (!is_numeric($id))
            throw new ValidateException('param error');
    }

    /**
     * 封装api数组
     *
     * @param $res         //是否成功(真/假)
     * @param $data        //数据
     * @param $successMsg  //成功信息
     * @param $errorMsg    //失败信息
     * @return array
     */
    public function arrays($res, $data=null, $successMsg =null,$errorMsg=null)
    {
        if ($res)
            return ['data' => $data, 'msg' => $successMsg, 'code' => 200];
        else
            return ['data' => '', 'msg' => $errorMsg, 'code' => 400];
    }

    /**
     * 标准api接口
     *
     * @param $data        //数据
     * @param $msg          //信息
     * @param $code     //StatusCode
     */
    public function create($data,$msg = '',$code = 200,$type = 'json'){
        $result = [
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
        ];
        //返回API接口ss
        return Response::create($result,$type);
    }
}

 

FollowModel模型类

class FollowFanModel extends BaseModel
{
    protected $table = 'fit_follow_fan';
    public $autoWriteTimestamp = true;
    private $redis;

    protected function initialize()
    {
        $this->redis = GetRedis::getInstance();//redis实例化
    }

    //增加关注
    public function _addFollow($data)
    {
        $fan_id = $data['fan_id'];       //粉丝id
        $follow_id = $data['follow_id']; //被关注人id
        if($follow_id==$fan_id) return false;
        Db::startTrans(); //开启事务
        try{
            if($this->redis->zScore($follow_id.'_MyFollow',$fan_id)){ //对方是否也关注了我
                //相互关注
                $this->update(['status'=>2],['fan_id'=>$follow_id,'follow_id'=>$fan_id]);//改为互关状态
                //redis插入关注列,粉丝列
                $this->redis->zAdd($fan_id.'_MyFollow',time(),$follow_id);
                $this->redis->zAdd($follow_id.'_MyFan',time(),$fan_id);
            }else{
                //单方面关注,
                $this->create(['follow_id'=>$follow_id,'fan_id'=>$fan_id]);//mysql插入
                //redis插入关注列,粉丝列
                $this->redis->zAdd($fan_id.'_MyFollow',time(),$follow_id);//id,关注时间,被关注人id
                $this->redis->zAdd($follow_id.'_MyFan',time(),$fan_id);//被关注人id,关注时间,id
            }
            Db::commit();
            return $this->arrays(true,'','关注成功');
        }catch (Exception $e){
            Db::rollback();
            return $this->arrays(false,'','',$e->getMessage());
        }
    }

    //取消关注
    public function _deleteFollow($data)
    {
        $fan_id = $data['fan_id'];       //粉丝id
        $follow_id = $data['follow_id']; //被关注人id
        if($follow_id==$fan_id) return false;
        Db::startTrans(); //开启事务
        try{
            if($this->redis->zScore($follow_id.'_MyFollow',$fan_id)){ //对方是否也关注了我
                //已经相互关注
                $where1 = [ ['fan_id','eq',$follow_id], ['follow_id','eq',$fan_id] ]; //or 因为mysql存储两种可能
                $where2 = [  ['fan_id','eq',$fan_id], ['follow_id','eq',$follow_id] ];
                $this->whereOr([$where1,$where2])->update(['status'=>1]); //改为单方面关注
                //redis删除关注列,粉丝列
                $this->redis->zRem($fan_id.'_MyFollow',$follow_id);
                $this->redis->zRem($follow_id.'_MyFan',$fan_id);
            }else{
                //取关
                $this->where(['follow_id'=>$follow_id,'fan_id'=>$fan_id])->delete();//mysql删除
                //redis删除关注列,粉丝列
                $this->redis->zRem($fan_id.'_MyFollow',$follow_id);
                $this->redis->zRem($follow_id.'_MyFan',$fan_id);
            }
            Db::commit();
            return $this->arrays(true,'','取关成功');
        }catch (Exception $e){
            Db::rollback();
            return $this->arrays(false,'','',$e->getMessage());
        }
    }

    //关注查询
    public function _followList($data)
    {
        $res = self::alias('a')
            ->rightJoin($data['join'],$data['condition'])
            ->where($data['where'])
            ->field($data['field'])
            ->order($data['order'])
            ->selectOrFail();
        return $res;
    }

}

 

Follow实现类, (验证器和redis配置自己定义)

class Follow extends Base
{
    protected $ff,$redis,$valid,$request;

    public function initialize()
    {
        $this->redis = GetRedis::getInstance(); //redis操作
        $this->ff = FollowFanModel::getInstance();//mysql操作
        $this->valid = new FollowValidate();    //验证器
        $this->request = Request::instance();   //request请求
    }

    public function addFollow()  //添加关注
    {
        $data = $this->request->param();
        $this->valid->goCheck($data);
        $res = $this->ff->_addFollow($data);
        return $res;
    }

    public function deleteFollow()  //取消关注
    {
        $data = $this->request->param();
        $this->valid->goCheck($data);
        $res = $this->ff->_deleteFollow($data);
        return $res;
    }

    public function myFanNum()//关注粉丝个数
    {
        return $this->myNum('_MyFan',$this->request,'粉丝数');
    }

    public function myFollowNum()//关注偶像个数
    {
        return $this->myNum('_MyFollow',$this->request,'偶像数');
    }

    public function myFanList($need=null)//粉丝列表
    {
        return $this->myList('_MyFan',$this->request,'粉丝列表',$need);
    }

    public function myFollowList($need=null)//偶像列表
    {
        return $this->myList('_MyFollow',$this->request,'偶像列表',$need);
    }

    /**
     * 用户列表
     *
     * @param $type    //偶像/粉丝列表  _MyFollow / _MyFan
     * @param $request //Request请求类
     * @param $msg     //成功返回的信息
     * @param $need    //是否只返回数组
     * @return array
     */
    public function myList($type,$request,$msg,$need=null)//列表
    {
        $id = $request->user_id;
        $this->is_num($id);
        $nums = $this->redis->zrange($id.$type,0, -1);//返回user_id数组
        if($need) return $nums; //只返回user id数组
        $res = UserModel::where('id','in',$nums)->field('img_url,id,username')->selectOrFail();
        return $this->arrays(true,$res,$msg);
    }

    /**
     * 用户数量
     *
     * @param $str    //偶像/粉丝数量  _MyFollow / _MyFan
     * @param $request //Request请求类
     * @param $msg     //成功返回的信息
     * @return array
     */
    public function myNum($str,$request,$msg) //数量
    {
        $id = $request->user_id;
        $this->is_num($id);
        $num = $this->redis->zCard($id.$str); //redis获取
        return $this->arrays($num,$msg,200);
    }

}

 

效果:

 

 

 

 

 

 

 

 

 

 

posted @ 2021-06-14 10:30  jaychou、  阅读(391)  评论(0)    收藏  举报