zoukankan      html  css  js  c++  java
  • 无限层级拉新,数据建立和数据分析 php

    2021年4月19日18:40:54

    关于用户拉新活动,如果在活动开始之初,设计的时候没有做好用户关系处理的话,那就涉及统计的时候就是一个很麻烦的事情。

    如果你刚好拉新员工的用户也是在这个表,需要筛选非员工的裂变用户数据就更麻烦了,因为这个是一个树状结构的,需要过滤掉员工数据,那就更蛋疼了,到现在我都没找到什么有效统计数据的办法,只能用简单的迭代查询数据库的办法来处理数据

    然后通过一些非常规方式来查询数据库

     调用服务

           ini_set('memory_limit', '1024M');
    
            $u = UUser::select(['id', 'phone', 'invite_people_id'])->orderBy('id', 'asc')->get()->toArray();
            if (!empty($u)) {
                foreach ($u as $k => $v) {
                   $p = new PullNewRelationshipService();
    $p->runUserInvitRelationship($v); } }
    class PullNewRelationshipService extends Base {
    
        public $data;
    
        public function __construct() {
            $this->data = new SplStack();
        }
    
        /*
         * 跑业务数据用户注册邀请关系
         * 是否是用户ID是员工单独跑
         */
    
        public function runUserInvitRelationship(array $data = [], array $ids = []) {
    
            //插入
            $uir = new UUserInvitRelationship();
            if ($data['invite_people_id'] == 0) {
                //如果invite_people_id 等于0说明是自己注册的直接写入
                $uir->user_id = $data['id'];
                $uir->level = 1;
                $uir->save();
            } else {
                $this->recursionUserData($data['invite_people_id']);
    //            p($this->data);
                //重置指针
                $this->data->rewind();
                $path = '';
                $i = 1;
                $run = [];
                while ($this->data->valid()) {
                    $i++;
    //                        echo $this->data->current(), "
    ";
                    $path = $path . ',' . $this->data->current();
                    $run[] = $this->data->current();
                    $this->data->next();
                }
    //            pp($upper_level_id);
                $uir->user_id = $data['id'];
                $uir->level = $i;
                $uir->level_path = trim($path, ',');
                $uir->upper_user_id = end($run);
                $uir->root_user_id = reset($run);
    
                $uir->save();
            }
        }
    
        //递归u_user表数据,向上递归
        public function recursionUserData(int $user_id = 0) {
            if ($user_id == 0) {
                return;
            }
    
            $u = UUser::where('id', $user_id)->first();
            if ($u == null) {
                
            } else {
                $this->data->push($u->id);
                $this->recursionUserData($u->invite_people_id);
            }
        }

    数据库结构:

    CREATE TABLE `u_user_invit_relationship` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `update_time` datetime DEFAULT NULL COMMENT '更新时间',
      `remark` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
      `is_delete` tinyint(1) NOT NULL DEFAULT '10' COMMENT '10默认99删除',
      `is_show` tinyint(1) NOT NULL DEFAULT '10' COMMENT '10默认显示99不显示',
      `user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '用户ID',
      `level` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '层级级别0是默认从1层',
      `level_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '层级路径例如id,id,id',
      `upper_user_id` bigint(20) DEFAULT '0' COMMENT '上层级别ID',
      `root_user_id` bigint(20) DEFAULT '0' COMMENT '层级根用户ID',
      PRIMARY KEY (`id`),
      UNIQUE KEY `user_id` (`user_id`),
      KEY `level_path` (`level_path`)
    ) ENGINE=InnoDB AUTO_INCREMENT=404862 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户注册邀请关系表'

    是从下到上的建立结构,查询sql

    405,500,758,1753,这个是level_path数据结构

    查询用户裂变数据SQL

    SELECT count(*) FROM u_user_invit_relationship WHERE FIND_IN_SET(405,level_path) 

    性能还行比IN好

    SELECT count(*) FROM u_user_invit_relationship WHERE 405 in(level_path);

    如果你需要从上到下的过滤,有些东西,比如员工数据剔除,就只能从上到下剔除,想在上面 的建立的数据结构上去过滤,目前我没发现什么好办法

     $mc = McStaffPullNewTask::select(['weixin_phone'])->get()->toArray();
            $weixinPhones = array_column($mc, 'weixin_phone');
            $ids = UUser::whereIn('phone', $weixinPhones)->get()->toArray();
            $idArray = array_column($ids, 'id');
    
    //        $md = McStaffPullNewTask::orderBy('id', 'asc')->limit(10)->get();
            $md = McStaffPullNewTask::orderBy('id', 'asc')->get();
    
            foreach ($md as $k => $v) {
    
                $t = new StaffRelationshipService();
                $count = $t->runUserInvitRelationship($v->weixin_phone, $idArray);
    
                $v->staff_pull_new = $count;
                $v->save();
            }
    class StaffRelationshipService extends Base {
    
        public $data;
    
        public function __construct() {
            $this->data = new SplStack();
        }
    
        //跑业务数据用户注册邀请关系
        public function runUserInvitRelationship(int $phone = null, array $staffIdArray = []) {
            $uUser = UUser::where('phone', $phone)->first();
    //        pp($uUser);
    
            if ($uUser == null) {
    //            p('用户未找到');
                return 0;
            } else {
    
                $key = array_search($uUser->id, $staffIdArray);
                if ($key !== null) {
                    unset($staffIdArray[$key]);
                }
                $u = UUser::where('invite_people_id', $uUser->id)->whereNotIn('id', $staffIdArray)->get()->toArray();
    //            p(count($u));
                $this->recursionUserData($u, $staffIdArray);
    //            p($this->data);
    //                //重置指针
                $this->data->rewind();
    
                $count = [];
                while ($this->data->valid()) {
                    $count[] = $this->data->current();
                    $this->data->next();
                }
    //            p(array_sum($count));
                return array_sum($count);
            }
        }
    
        //递归u_user表数据,向上递归
        public function recursionUserData(array $ids = [], array $staffIdArray = []) {
    
            if (!empty($ids)) {
                $this->data->push(count($ids));
    
                foreach ($ids as $k => $v) {
                    $key = array_search($v['id'], $staffIdArray);
                    if ($key !== null) {
                        unset($staffIdArray[$key]);
                    }
    
                    $ss = UUser::where('invite_people_id', $v['id'])->whereNotIn('id', $staffIdArray)->get();
    
                    $this->recursionUserData($ss->toArray(), $staffIdArray);
                }
            }
        }
    QQ群 247823727 博客文件如果不能下载请进群下载
    如果公司项目有技术瓶颈问题,如有需要,请联系我,提供技术服务 QQ: 903464207
  • 相关阅读:
    java Concurrent包学习笔记(二):CountDownLatch和CyclicBarrier
    java Concurrent包学习笔记(四):BlockingQueue
    Linux Linux程序练习十五(进程间的通信共享内存版)
    Linux shell中的符号
    Linux shell程序一
    Linux Linux程序练习十四(多进程压力测试)
    Linux Linux程序练习十三(信号阻塞,捕获)
    Linux 网络编程详解二(socket创建流程、多进程版)
    Linux 网络编程详解一(IP套接字结构体、网络字节序,地址转换函数)
    Linux shell实战(ipcs工具)
  • 原文地址:https://www.cnblogs.com/zx-admin/p/14678294.html
Copyright © 2011-2022 走看看