ci框架php+redis实现基础的盲盒交友

盲盒交友的逻辑:

​ ci框架实现,集成在博客系统之中。

​ 用户每天有一次免费抽取纸条和一次免费放入纸条的机会。机会消耗完之后需要消耗10金币来进行放入纸条和抽取纸条操作,盲盒分为两种,一种存男生放入的纸条,另一种存女生放入的纸条,纸条中有一些可以填写的基本信息。

sql
CREATE TABLE `blind_friend` (
  `id` int NOT NULL AUTO_INCREMENT,
  `uid` int NOT NULL COMMENT '用户id',
  `type` tinyint NOT NULL DEFAULT '1' COMMENT '盲盒类型: 1:男 2:女',
  `images` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '图片简介',
  `code` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '微信号',
  `content` varchar(255) COLLATE utf8_bin NOT NULL COMMENT '纸条内容',
  `init_time` int DEFAULT NULL,
  `last_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin COMMENT='放入纸条信息';

CREATE TABLE `blind_friend_log` (
  `id` int NOT NULL AUTO_INCREMENT,
  `uid` int NOT NULL COMMENT '用户id',
  `note_id` int DEFAULT NULL COMMENT '纸条id',
  `init_time` int DEFAULT NULL,
  `last_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin COMMENT='用户抽取纸条记录';

CREATE TABLE `coin_log` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `uid` int unsigned NOT NULL DEFAULT '0' COMMENT '用户id',
  `amount` varchar(34) NOT NULL DEFAULT '' COMMENT '交易金币金额',
  `desc` mediumtext NOT NULL COMMENT '本次消耗金币详情',
  `init_time` int unsigned NOT NULL COMMENT '创建记录时间',
  `last_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录上次修改时间',
  PRIMARY KEY (`id`),
  KEY `uid_index` (`uid`) USING BTREE,
  KEY `time_index` (`init_time`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3 COMMENT='金币流水表';

前两个表blind_friend、blind_friend_log是为了记录盲盒交友纸条信息,金币流水表是完善金币消费的记录,每次修改金币时添加金币的流水记录。

redis key:
//是否每日免费放入纸条
"sendBlindBoxFriendFree_" . date('Ymd') . '_' . $data['uid'];
//放入纸条防止多次点击锁
"sendBlindBoxFriendLock_" . $data['uid'];
 //抽取纸条是否每日免费
"getBlindBoxFriendFree_" . date('Ymd') . '_' . $data['uid'];
//抽取纸条防止多次点击锁
"getBlindBoxFriendLock_" . $data['uid'];
具体实现:

这个功能的实现我编写了两个公共函数,一个是作为批量图片上传,一个是调用三方接口检测用户放入纸条时,纸条中的内容是否有违禁词汇。代码如下

//敏感词检测三方
if (!function_exists("checkTxt")) {
    function checkTxt($txt)
    {
        //在config中添加三方的appkey,在此处读取出来
        $appKey = config_item('msg_app_key');
        //这里是三方检测敏感词的url地址,在config.php中
        $url = config_item('char_url');
        //拼接url
        $url = $url . "?content={$txt}&appkey={$appKey}";
        //发送curl请求,这里是get请求
        $res = curl_request($url, false);
        //返回结果为json编译成数组
        $res = json_decode($res, true);
        //定义返回的数组
        $response = [
            'code' => 200,
            'status' => true,
            'msg' => '检测成功'
        ];
        //下面都是根据错误码进行判断本次检测是否成功
        $result = $res['result']['showapi_res_body'];
        //请求发送是否成功
        if ($res['code'] != 10000) {
            $response = [
                'code' => $res['code'],
                'status' => false,
                'msg' => $res['msg']
            ];
        } else if ($result['ret_code'] != 0) {
            //查看本次接口检测是否成功
            $response = [
                'code' => 400,
                'status' => false,
                'msg' => '接口调用失败!'
            ];
        } else if ($result['labels'][0]['sug'] != 'pass') {
            //检测词汇是否通过
            $response = [
                'code' => 200,
                'status' => false,
                'msg' => $result['labels'][0]['msg'],
            ];
        }
        return $response;
    }
}

//批量上传图片
if (!function_exists("uploadImages")) {
    function uploadImages($name = 'img', $dir = '')
    {
        $files = $_FILES[$name];
        if (!$files) {
            return false;
        }
        //传递过来的不是数组格式,即不是多张图片
        if (!is_array($files['name'])) {
            //单个上传
            imgUpload($name);
        }
        //若没有传递上传目录则为默认目录
        if ($dir == '') {
            $dir = 'static/img/' . date('Y-m-d', time());
        }
        //文件夹不存在则创建文件夹
        if (!file_exists($dir)) {
            mkdir($dir, 0755,true);
        }
        //图片上传总数
        $count = count($files['name']);
        //允许上传的图片类型
        $allowType = ['image/gif', 'image/png', 'image/jpg', 'image/jpeg'];
        for ($i = 0; $i < $count; $i++) {
            $nameItem = $files['name'][$i];
            $tmpItem = $files['tmp_name'][$i];
            //图片类型
            $typeItem = $files['type'][$i];
            //图片是否符合类型
            if (!in_array($typeItem, $allowType)) {
                return false;
            }
            //获取图片后缀
            $fileTypeArray = explode('.', $nameItem);
            $fileType = $fileTypeArray[count($fileTypeArray) - 1];
            //拼接文件上传的路径
            $uploadName = $dir . '/' . time() . rand(1000, 9999) . '.' . $fileType;
            $res = move_uploaded_file($tmpItem, $uploadName);
            if (!$res) {
                return false;
            }
            $file[] = $uploadName;
        }
        return $file;
    }
}
controller:
    //盲盒交友
    //放入纸条到盲盒
    public function sendBlindBoxNote()
    {
        $data = $this->input->post();
        $rules = [
            [
                'field' => 'uid',
                'label' => '用户id',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户id不能为空'
                ],
            ],
            [
                'field' => 'code',
                'label' => '微信号',
                'rules' => 'required|max_length[100]',
                'errors' => [
                    'required' => '微信号不能为空',
                    'max_length' => '微信号长度错误',
                ],
            ],
            [
                'field' => 'type',
                'label' => '用户性别',
                'rules' => 'required|in_list[1,2]',
                'errors' => [
                    'required' => '性别不能为空',
                    'in_list' => '性别只能为男、女',
                ],
            ],
            [
                'field' => 'content',
                'label' => '放入盲盒内容',
                'rules' => 'required',
                'errors' => [
                    'required' => '内容不能为空',
                ],
            ],
        ];
        $checkParams = $this->validate($data, $rules);
        //参数验证
        if ($checkParams !== true) {
            fail(400, $checkParams);
        }
        if ($data['code'] && !preg_match('#^\w+$#', $data['code'])) {
            fail(400, '微信号仅限数字和字符');
        }
        $this->Activity_service->sendBlindBoxNote($data);
    }

    //抽取纸条
    public function getBlindBoxNote()
    {
        $data = $this->input->post();
        $rules = [
            [
                'field' => 'uid',
                'label' => '用户id',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户id不能为空'
                ],
            ],
            [
                'field' => 'type',
                'label' => '盲盒类型',
                'rules' => 'required|in_list[1,2]',
                'errors' => [
                    'required' => '盲盒类型不能为空',
                    'in_list' => '盲盒类型错误'
                ],
            ],
        ];
        $checkParams = $this->validate($data,$rules);
        if ($checkParams !== true){
            fail(400,$checkParams);
        }
        $this->Activity_service->getBlindBoxNote($data);
    }

    //我的纸条
    public function myBlindBoxNote()
    {
        $data = $this->input->post();
        $rules = [
            [
                'field' => 'uid',
                'label' => '用户id',
                'rules' => 'required',
                'errors' => [
                    'required' => '用户id不能为空'
                ],
            ],
            [
                'field' => 'type',
                'label' => '类型',
                'rules' => 'required|in_list[1,2]',
                'errors' => [
                    'required' => '类型不能为空',
                    'in_list' => '类型只能为抽取、或放入',
                ],
            ],
        ];
        $checkParams = $this->validate($data, $rules);
        $this->Activity_service->myBlindBoxNote($data['uid'], $data['type']);
    }
service:
 //盲盒交友
    //放入纸条
    public function sendBlindBoxNote($data)
    {
        //查看是否每日免费
        $key = "sendBlindBoxFriendFree_" . date('Ymd') . '_' . $data['uid'];
        $lockKey = "sendBlindBoxFriendLock_" . $data['uid'];
        //防止同用户多次点击,上锁
        if (!$this->conn->setNxExpire($lockKey,1,3)) {
            fail(400, '点击太快了,稍后重试');
        }
        //敏感词过滤
        $response = checkTxt($data['content']);
        //含有敏感词
        if (!$response['status']) {
            $this->conn->del($lockKey);//移除锁
            fail(400, $response['msg']);
        }
        //已经存在该键则不是免费
        $status = $this->conn->exists($key);
        if ($status) {
            //扣10金币
            $text = "向交友盲盒放入纸条";
            $res = $this->Activity_model->changeCoins($data['uid'], -10,$text);
            if (!$res) {
                $this->conn->del($lockKey);//移除锁
                fail(400, '金币不足');
            }
        } else {
            //每日免费
            $this->conn->set($key, 1, 2 * 86400);
        }
        //图片上传,本地windos环境上传到D:/image/blindBox/日期/目录下,linux环境上传到/var/www/data/image/blindBox/日期/目录下
        $dir = PHP_OS == "WINNT" ? "D:/image/blindBox/".date('Ymd') : "/var/www/data/image/blindBox/".date('Ymd');
        $res = uploadImages('image',$dir);
        if (is_array($res)) {
            $data['images'] = implode($res, ',');
        }
        $data['init_time'] = time();
        $res = $this->Activity_model->addBlindBoxFriend($data);
        if (!$res) {
            if ($status) {
                //失败则将金币加回去
                $this->Activity_model->changeCoins($data['uid'], 10,'交友盲盒放入纸条失败,返回金币');
            } else {
                //将首次免费机会返回
                $this->conn->del($key);
            }
            fail(400, '放入纸条失败!');
        }
        success([], '放入纸条成功!');
    }

    //抽取纸条
    public function getBlindBoxNote($data)
    {
        //抽取纸条是否每日免费
        $key = "getBlindBoxFriendFree_" . date('Ymd') . '_' . $data['uid'];
        //防止多次点击锁
        $lockKey = "getBlindBoxFriendLock_" . $data['uid'];
        if(!$this->conn->setNxExpire($lockKey,1,3)){
            fail(400,'点击太快了,稍后重试');
        }
        if ($this->conn->exists($key)) {
            //扣金币
            $res = $this->Activity_model->changeCoins($data['uid'], -10,'从交友盲盒中抽取纸条');
            if (!$res) {
                //移除锁
                $this->conn->del($lockKey);
                fail(400, '金币不足');
            }
        } else {
            //每日免费次数
            $this->conn->set($key, 1, 2 * 86400);
        }
        //获取纸条
        $Note = $this->Activity_model->getBlindBoxNote($data['uid'], $data['type']);
        //
        if (!$Note) {
            //移除锁
            $this->conn->del($lockKey);
            fail(400, '没有纸条可以获取');
        }
        $res = [
            'code' => $Note[0]['code'] ? $Note[0]['code'] : '',
            'content' => $Note[0]['content'] ? $Note[0]['content'] : '',
            'images' => $Note[0]['images'] ? explode(',', $Note[0]['images']) : '',
        ];
        //记录抽取记录
        $this->Activity_model->addGetBlindBoxFriend($data['uid'], $Note[0]['id']);
        //移除锁
        $this->conn->del($lockKey);
        success($res);
    }

    //我的纸条
    public function myBlindBoxNote($uid, $type)
    {
        //获取我放入的纸条
        $res = $this->Activity_model->myBlindBoxNote($uid, $type);
        foreach ($res as $k => $v) {
            $response[$k]['code'] = $v['code'];
            $response[$k]['type'] = $v['type'];
            $response[$k]['content'] = $v['content'];
            $response[$k]['images'] = $v['images'];
            if ($v['images']) {
                $response[$k]['images'] = explode(',', $v['images']);
            }
        }
        success($response);
    }
model:
 public function addBlindBoxFriend($data)
    {
        return $this->commonInsert('blind_friend', $data);
    }

    public function getBlindBoxNote($uid, $type)
    {
        $query = $this->db->select("id,images,code,content")
            ->where(['uid !=' => $uid, 'type' => $type])
            ->order_by('id', 'RANDOM')
            ->limit(1)
            ->get('blind_friend');
        return $query->num_rows() ? $query->result_array() : false;
    }

    public function addGetBlindBoxFriend($uid, $noteId)
    {
        return $this->commonInsert('blind_friend_log', ['uid' => $uid, 'note_id' => $noteId, 'init_time' => time()]);
    }

    public function myBlindBoxNote($uid, $type)
    {
        //我放入的纸条
        if ($type == 1) {
            return $this->commonQuery('id,code,type,content,images', ['uid' => $uid], 'blind_friend');
        } else {
            //抽取的纸条
            $this->db->select('b.id,code,b.type,b.content,images')
                ->from('blind_friend_log a')
                ->join('blind_friend b', 'a.note_id=b.id', 'left')
                ->where(['a.uid' => $uid]);
            $query = $this->db->get();
            return $query->num_rows() ? $query->result_array() : '';
        }
    }
接口描述
放入纸条

请求地址: /activity/sendBlindBoxNote

请求参数: uid(用户id) 、code(微信号)、type(男、女)、content(内容)、image[0 - 8] (上传的图片,可以上传多张)

请求方式: post

请求示例

在这里插入图片描述

返回示例:

//成功
{
    "code": 200,
    "msg": "放入纸条成功!",
    "data": []
}
//检测到敏感词
{
    "code": 400,
    "msg": "存在低俗辱骂不合规!",
    "data": []
}

​ 图片上传地址:

在这里插入图片描述

金币消耗流水:

在这里插入图片描述

抽取纸条

请求地址: /Activity/getBlindBoxNote

请求参数: uid(用户id) 、type(抽取的盲盒类型,1:男,2:女)

请求方式: post

返回示例

{
    "code": 200,
    "msg": "success",
    "data": {
        "code": "fj123",
        "content": "你最喜欢吃的是什么",
        "images": [
            "/var/www/data/image/blindBox/20211115/16369668015499.png",
            "/var/www/data/image/blindBox/20211115/16369668017975.png"
        ]
    }
}
我的纸条

请求地址: /Activity/myBlindBoxNote

请求参数: uid(用户id) 、type(抽取的盲盒类型,1:放入,2:抽取)

请求方式: post

返回示例

{
    "code": 200,
    "msg": "success",
    "data": [
        {
            "id": "9",
            "code": "wyqgg123",
            "type": "1",
            "content": "傻逼",
            "images": null
        },
        {
            "id": "10",
            "code": "wyqgg123",
            "type": "1",
            "content": "这是一个有吸引力的活动",
            "images": null
        },
        {
            "id": "11",
            "code": "wyqgg123",
            "type": "1",
            "content": "这是一个有吸引力的活动",
            "images": null
        },
        {
            "id": "12",
            "code": "wyqgg123",
            "type": "1",
            "content": "这是一个有吸引力的活动",
            "images": null
        },
        {
            "id": "13",
            "code": "wyqgg123",
            "type": "1",
            "content": "这是一个有吸引力的活动",
            "images": "static/img/2021-11-15/16369839927531.png,static/img/2021-11-15/16369839929212.png"
        },
        {
            "id": "14",
            "code": "wyqgg123",
            "type": "1",
            "content": "这是一个有吸引力的活动",
            "images": "/var/www/data/image/blindBox/20211114/16369261453027.png,/var/www/data/image/blindBox/20211114/16369261451264.png"
        },
        {
            "id": "15",
            "code": "wyqgg123",
            "type": "1",
            "content": "这是一个有吸引力的活动",
            "images": "D:/image/blindBox/20211116/16370335258904.png,D:/image/blindBox/20211116/16370335256663.png"
        },
        {
            "id": "19",
            "code": "fj123",
            "type": "1",
            "content": "你最喜欢吃的是什么",
            "images": "D:/image/blindBox/20211117/16371338687609.png,D:/image/blindBox/20211117/16371338681157.png"
        },
        {
            "id": "20",
            "code": "fj123",
            "type": "1",
            "content": "你最喜欢吃的是什么",
            "images": "/var/www/data/image/blindBox/20211115/16369664498073.png,/var/www/data/image/blindBox/20211115/16369664499483.png"
        },
        {
            "id": "21",
            "code": "fj123",
            "type": "1",
            "content": "你最喜欢吃的是什么",
            "images": "/var/www/data/image/blindBox/20211115/16369668015499.png,/var/www/data/image/blindBox/20211115/16369668017975.png"
        }
    ]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值