1000], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'part' => '分片,片数', 'user_id' => '用户ID', 'tree' => '推荐关系树,【注意字符集!!!】', 'deep' => '层级', 'created_at' => 'Created At', 'updated_at' => 'Updated At', ]; } /** * @desc:保存数据 * @Author: hua * @Date: 2021/11/29 * @Time: 17:54 * @Copyright: copyright (c) 2021 广东七件事集团 * @param array $params * @return UserPartitionRelationship|false|null */ public static function setData(array $params) { try { if (empty($params['user_id'])) throw new Exception('user_id不能为空'); $model = self::findOne(['user_id' => $params['user_id']]); if (empty($model)) { $model = new self(); $model->loadDefaultValues(); } if (empty($params['parent_id'])) { $params['tree'] = Base64Helper::dec2Base64($params['user_id']); $params['deep'] = 0; $params['part'] = 1; if (!$model->load($params, '') || !$model->save()) throw new Exception($model->getErrorMessage()); } else { self::bindParent($params['user_id'],$params['parent_id']); } return true; } catch (Exception $e) { self::$static_error = $e->getMessage(); return false; } } public static function bindParent($user_id,$parent_id){ Yii::$app->custom->logs("关系链绑定日志:". $user_id, $parent_id); //绑定上级,上级关系链,正在改动,阻塞等待锁释放 $parent_tree_model = self::find()->where(['user_id' => $parent_id])->orderBy('part asc')->one(); $tree_id_arr = explode(',', $parent_tree_model['tree']); $top_id = array_shift($tree_id_arr); $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_USER_RELATIONSHIP , $top_id); $res = LockHelper::readLock($lock_key);//锁存在,阻塞 if (!$res) throw new Exception('当前访问人数过多'); $parent_list = self::find()->where(['user_id' => $parent_id])->orderBy('part desc')->all(); $insert = []; $time = time(); foreach ($parent_list as $k => $value) { if ($k == 0) { $code = Base64Helper::dec2Base64($user_id); $tree = explode(',', $value['tree']); if (count($tree) >= 150) { //超过tree的最大存储长度,新增加一条 $insert[] = self::packData($code, $value['part'] + 1, $user_id, $value['deep'], $time); $insert[] = self::packData($value['tree'], $value['part'], $user_id, $value['deep'], $time); } else { $insert[] = self::packData($value['tree'] . ',' . $code, $value['part'], $user_id, $value['deep'], $time); } } else { $insert[] = self::packData($value['tree'], $value['part'], $user_id, $value['deep'], $time); } } UserPartitionRelationship::deleteAll(['user_id' => $user_id]); $field = ['tree', 'part', 'user_id', 'deep', 'created_at', 'updated_at']; if ($insert) { $insert = array_reverse($insert); $res = Yii::$app->db->createCommand()->batchInsert(self::tableName(), $field, $insert)->execute(); if ($res == false) throw new Exception('保存关系链失败'); Yii::$app->custom->logs("关系链绑定成功:". $user_id, $parent_id); } } protected static function packData($tree, $part, $user_id, $deep, $time) { return [$tree, $part, $user_id, $deep + 1, $time, $time]; } /** * * @param array $where * @param string $select * @param array $with * @param int $is_array * @return array|User[]|\yii\db\ActiveRecord[] */ public static function getUserRelationList(array $where, $select = '*', array $with = [], int $is_array = 0) { $query = self::find(); self::paramPack(['where' => $where, 'with' => $with], $query); return $query->select($select)->asArray($is_array)->all(); } /** * 获取自身和上级关系链 * @param $user_id * @return array */ public static function getTree($user_id) { $user_relation_list = self::lists(['where' => [['user_id' => $user_id]], 'order' => 'part asc']); $parent_id_tree = '';//最新一个分片的tree $all_parent_id_tree = '';//所有上级tree $all_parent_id_tree_arr = [];//所有上级id $deep = 0; foreach ($user_relation_list as $key => $value) { $all_parent_id_tree .= $value['tree'] . ','; $all_parent_id_tree_arr = array_merge($all_parent_id_tree_arr, explode(',', $value['tree'])); if (!isset($user_relation_list[$key + 1])) { $parent_id_tree = $value['tree']; } $deep = $value['deep']; } $all_parent_id_tree = trim($all_parent_id_tree, ','); return [$parent_id_tree, $deep, $all_parent_id_tree, $all_parent_id_tree_arr]; } /** * 查询下级数组 * @param $user_id * @param int $deep * @return array */ public static function getChildIdArr($user_id, $deep = 0, $start_time = 0, $end_time = 0) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); $where[] = ['<>', 'user_id', $user_id]; $where[] = ['like', 'tree', "{$tree},%", false]; if (!empty($deep)) $where[] = ['deep' => $deep + $parent_deep]; if (!empty($start_time)) { $where[] = ['>=', 'updated_at', $start_time]; } if (!empty($end_time)) { $where[] = ['<=', 'updated_at', $end_time]; } $list = self::getUserRelationList($where); return array_column($list, 'user_id'); } /** * 查询下级数组 * @param $user_id * @param int $deep * @return array */ public static function getChildIdArrV2($user_id, $deep = 0) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); $where[] = ['<>', 'user_id', $user_id]; $where[] = ['like', 'tree', "{$tree},%", false]; if (!empty($deep)) $where[] = ['deep' => $deep + $parent_deep]; $list = self::getUserRelationList($where, 'user_id', [], 1); return array_column($list, 'user_id'); } /** * 查询下级数组(包含自己) * @param $user_id * @param int $deep * @return array */ public static function getChildList($user_id, $deep = 0) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); $where[] = ['like', 'tree', "{$tree}%", false]; if (!empty($deep)) $where[] = ['deep' => $deep + $parent_deep]; return self::getUserRelationList($where, 'tree, user_id', [], 1); } public static function getChildIdArrByChunk($user_id, $offset = 0, $limit=1000) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); $where[] = ['<>', 'user_id', $user_id]; $where[] = ['like', 'tree', "{$tree},%", false]; $query = self::find(); self::paramPack(['where' => $where], $query); $list = $query->orderBy('id asc')->offset($offset)->limit($limit)->all(); return array_column($list, 'user_id'); } /** * 查询下级数组 * @param $user_id * @param int $deep * @return array */ public static function getChildIdArrOrderBy($user_id, $deep = 0) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); $where[] = ['<>', 'user_id', $user_id]; $where[] = ['like', 'tree', "{$tree},%", false]; if (!empty($deep)) $where[] = ['deep' => $deep + $parent_deep]; $query = self::find(); self::paramPack(['where' => $where, 'with' => [],'order' => 'updated_at asc'], $query); $list = $query->select('*')->asArray(0)->all(); return array_column($list, 'user_id'); } /** * @desc:查询下级数组 * @Author: hua * @Date: 2021/11/30 * @Time: 15:10 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $user_id * @param int $deep * @return bool|int|string|null */ public static function getChildCounts($user_id, $deep = 0) { $model = self::find()->where(['user_id' => $user_id])->orderBy('part desc')->asArray()->one(); $tree = $model['tree']; $parent_deep = $model['deep']; $query = self::find()->where(['<>', 'user_id', $user_id])->andWhere(['like', 'tree', "{$tree}%", false]); if (!empty($deep)) $query->andWhere(['deep' => $deep + $parent_deep]); return $query->count(); } /** * 查找上级数组 * @param $user_id * @return array|false|string[] */ public static function getParentIdArr($user_id) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); array_pop($all_tree_arr); $arr = []; foreach ($all_tree_arr as $code) { $arr[] = Base64Helper::Base642dec($code); } return $arr; } /** * 查询多个会员id直推上级ID数组 * @param $user_id * @return array|false|string[] */ public static function getDirectIdArr($user_id) { $list = User::lists(['where' => [['id' => $user_id]], 'id,parent_id']); return array_column($list, 'parent_id', 'id'); } public static function getParentIds($user_id,$deep=0) { $user = User::getOne([['id' => $user_id]], true); switch ($deep){ case 1: return $user['parent_id']; case 2: return [$user['parent_id'], $user['second_parent_id']]; default: return [$user['parent_id'], $user['second_parent_id'], $user['third_parent_id']]; } } //查询上级昵称数组 public static function getParentsNickname($parent_id_arr) { $parent_list = User::lists(['where' => [['id' => $parent_id_arr]]]); return array_column($parent_list, 'nickname', 'id'); } /** * @desc:绑定关系链,首次下单,首次付款 * @Author: hua * @Date: 2021/11/12 * @Time: 11:33 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $user_id * @param $mall_id * @param $data */ public static function bindRelationship($user_id, $mall_id) { $relation_setting = \Yii::$app->services->setting->mall->get($mall_id, 'user_relation_setting.relation_setting'); $data = []; if (!empty($relation_setting)) $data = json_decode($relation_setting, true); $where = ['user_id' => $user_id, 'mall_id' => $mall_id,'store_id'=>0,'mch_id'=>0]; $result = false; if (!empty($data['status'])&&!empty($data['become_child_way'])) { $where['pay_status'] = 1; if ($data['become_child_way'] == 2) $where['order_status'] = OrderStatusEnum::ACCOMPLISH;//首次完成订单 $counts = Order::find()->where($where)->count(); if ($counts == 1&&(in_array($data['become_child_way'],[2,3]))) { $user = User::findOne(['id' => $user_id, 'mall_id' => $mall_id]); if (!empty($user->temp_parent_id) && empty($user->parent_id) && $user->temp_parent_id != $user_id) { $params['mall_id'] = $mall_id; $params['user_id'] = $user_id; $params['parent_id'] = $user->temp_parent_id; $res = self::setData($params); if ($res == false) throw new Exception(self::getStaticError()); list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); array_pop($all_tree_arr);//自身 array_pop($all_tree_arr);//直推上级 $second_parent_id = array_pop($all_tree_arr);//间推上级 $third_parent_id = array_pop($all_tree_arr);// $user->parent_id = $params['parent_id']; if($second_parent_id){ $user->second_parent_id = Base64Helper::Base642dec($second_parent_id); } if($third_parent_id){ $user->third_parent_id = Base64Helper::Base642dec($third_parent_id); } $res = $user->save(); if ($res == false) throw new Exception($user->getErrorMessage()); $result = true; } } } return $result; } /** * 我的客户 * @param $params * @return mixed */ public static function myCustomer($params, $config) { $children_id_arr = self::getChildIdArr($params['user_id'], $params['level']); $user_team_statistics = UserTeamStatistics::getOne([['user_id' => $params['user_id']]]); $data['user_direct_total'] = !empty($user_team_statistics['user_direct_total']) ? $user_team_statistics['user_direct_total'] : 0; $data['user_indirect_total'] = !empty($user_team_statistics['user_indirect_total']) ? $user_team_statistics['user_indirect_total'] : 0; $data['user_team_total'] = !empty($user_team_statistics['user_team_total']) ? $user_team_statistics['user_team_total'] : 0; $data['loss_user_direct_total'] = !empty($user_team_statistics['loss_user_direct_total']) ? $user_team_statistics['loss_user_direct_total'] : 0; $data['loss_user_indirect_total'] = !empty($user_team_statistics['loss_user_indirect_total']) ? $user_team_statistics['loss_user_indirect_total'] : 0; $data['loss_user_team_total'] = !empty($user_team_statistics['loss_user_team_total']) ? $user_team_statistics['loss_user_team_total'] : 0; $data['level1_zn'] = '好友人数'; $data['level2_zn'] = '粉丝人数'; $data['level_team_zn'] = '潜在粉丝'; $data['level_team_agent_zn'] = '群组业绩'; $data['parent_name'] = '平台'; $data['parent_level_name'] = '平台方'; $data['parent_avatar_url'] = ''; if (!empty($params['user_custom_text'])) { $user_custom_text = $params['user_custom_text']; if (!empty($user_custom_text['direct_text'])) $data['level1_zn'] = $user_custom_text['direct_text']; if (!empty($user_custom_text['indirect_text'])) $data['level2_zn'] = $user_custom_text['indirect_text']; if (!empty($user_custom_text['team_text'])) $data['level_team_zn'] = $user_custom_text['team_text']; if (!empty($user_custom_text['team_agent_text'])) $data['level_team_agent_zn'] = $user_custom_text['team_agent_text']; } $data['is_show_indirect'] = !isset($user_custom_text['is_show_indirect']) || !empty($user_custom_text['is_show_indirect']); $data['is_show_team'] = !isset($user_custom_text['is_show_team']) || !empty($user_custom_text['is_show_team']); $data['is_show_team_agent'] = $user_custom_text['is_show_team_agent'] ?? 1; $user = User::getOne([['id' => $params['user_id']]], false, ['parent']); $parent = $user['parent']; if (!empty($parent)) { $data['parent_name'] = empty($parent->nickname) ? $parent->id : $parent->nickname; $data['parent_avatar_url'] = $parent->avatar_url; $data['parent_level_name'] = $parent->userLevel->name ?? '默认等级'; } $time = time(); $date = date('Y-m-d', $time); $start_time = strtotime($date . ' 00:00:00'); $where = ['and', ['in', 'id', $children_id_arr], ['>=', 'created_at', $start_time], ['<=', 'created_at', $time]]; $add_counts = User::find()->where($where)->count(); $where = ['and', ['in', 'id', $children_id_arr], ['>=', 'last_login_at', $start_time], ['<=', 'last_login_at', $time]]; $active_counts = User::find()->where($where)->count(); //今日流失 修改成 沉睡客户: 90天未登陆 $where = ['and', ['in', 'id', $children_id_arr], ['<=', 'last_login_at', strtotime($date . ' 23:59:59') - 90 * 24 * 3600]]; $loss_counts = User::find()->where($where)->count(); $where = ['and', ['in', 'user_id', $children_id_arr], ['>=', 'created_at', $start_time], ['<=', 'created_at', $time]]; if (!empty($config) && $config['settle_type'] == 2) { $where[] = ['order_status' => [OrderStatusEnum::ACCOMPLISH]]; } else { if ($config['is_sub_refund'] == 1) { $where[] = ['order_status' => [OrderStatusEnum::PAY, OrderStatusEnum::SING, OrderStatusEnum::SHIPMENTS, OrderStatusEnum::ACCOMPLISH]]; } } $order_list = Order::find()->where($where)->select('id,user_id,pay_time,pay_money,goods_price,order_status')->asArray()->all(); $total_price = 0; $order_uids = []; $userNums = []; // 用于记录用户购买次数 foreach ($order_list as $v) { if ($v['pay_time']) {// 只有订单付款才计算订单人员 if (!in_array($v['user_id'], $order_uids)) $order_uids[] = $v['user_id']; $total_price += $v['goods_price']; $userNums[$v['user_id']]++; } } $level_list = [ 'add_counts' => !empty($add_counts) ? $add_counts : 0,//今日新增 'active_counts' => !empty($active_counts) ? $active_counts : 0,//今日活跃 'loss_counts' => !empty($loss_counts) ? $loss_counts : 0,//今日流失 'add_order_counts' => count($order_uids),//今日下单 'pay_order_counts' => count(array_filter($userNums, function ($v) {return $v == 1;})),//今日首购(修改为今日只下一单的用户,超过一单就不算) 'total_price' => !empty($total_price) ? bcadd($total_price,0,2) : 0,//新增业绩 ]; $level_list['total_price'] == \sprintf("%01.2f", $level_list['total_price']); $data['level_list'] = $level_list; return $data; } /** * 我的客户列表 * @param $params * @return array|bool|mixed|void */ public static function myChildrenList($params) { $is_hide_mobile = Yii::$app->services->setting->mall->get($params['mall_id'], 'user_operate.is_hide_mobile'); list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($params['user_id']); $where = []; // if (!empty($params['level'])) $where[] = ['deep' => $params['level'] + $parent_deep]; // $orderBy = 'user_id desc'; // if (!empty($params['sort'])) { // switch ($params['sort']) { // case 'new': // $orderBy = 'created_at desc'; // break; // case 'old': // $orderBy = 'created_at asc'; // break; // } // } // // 查询等级或者关键词 // if (!empty($params['user_level']) or !empty($params['keyword'])) { // $query = User::find()->where(['mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]); // // 等级 // if (!empty($params['user_level'])) { // $query->andWhere(['level' => $params['user_level']]); // } // // 关键词 // if (!empty($params['keyword'])) { // $query->andWhere(['or', // ['like', 'id', $params['keyword']], // ['like', 'nickname', $params['keyword']], // ['like', 'mobile', $params['keyword']] // ]); // } // $user_ids = $query->select('id')->column(); // } // isset($user_ids) && $where[] = ['user_id' => $user_ids]; // // 根据查看的类型(今日新增、今日活跃、近期未访、今日下单、今日首购)获取用户id // if (!empty($params['type'])) { // $childrenIdsFind = self::find(); // self::paramPack([ // 'where' => $where, // 'select' => 'user_id' // ], $childrenIdsFind); // $userIdsByType = self::getMyChildrenUserIdsByType($childrenIdsFind->column(), $params['type']); // if (is_array($userIdsByType)) { // $where[] = ['user_id' => $userIdsByType]; // } // } if (!empty($params['type'])) { $where[] = ['<>', 'user_id', $params['user_id']]; $where[] = ['like', 'tree', "{$tree},%", false]; if (!empty($params['level'])) $where[] = ['deep' => $params['level'] + $parent_deep]; $childrenIdsFind = self::find(); self::paramPack([ 'where' => $where, 'select' => 'user_id' ], $childrenIdsFind); $userIdsByType = self::getMyChildrenUserIdsByType($childrenIdsFind->column(), $params['type']); $where = []; if (is_array($userIdsByType)) { $where[] = ['u.id' => $userIdsByType]; } } $where[] = ['u.mall_id' => $params['mall_id']]; $where[] = ['u.status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]; switch ($params['level']) { case 1: $where[] = ['u.parent_id' => $params['user_id']]; break; case 2: $where[] = ['u.second_parent_id' => $params['user_id']]; break; } if (!empty($params['user_level'])) $where[] = ['u.level' => $params['user_level']]; if (!empty($params['keyword'])) $where[] = ['or', ['like', 'u.nickname', $params['keyword']], ['like', 'u.mobile', $params['keyword']], ['like', 'u.id', $params['keyword']]]; $orderBy = 'u.id desc'; if (!empty($params['sort_type'])) { if ($params['sort_type'] == 'created_at') { $order_desc = 'u.'.$params['sort_type']; } else { $order_desc = 'ua.'.$params['sort_type']; } } if (!empty($params['sort'])) { switch ($params['sort']) { case 'new': $orderBy = $order_desc . ' desc'.' , u.id desc'; break; case 'old': $orderBy = $order_desc . ' asc'.' , u.id asc'; break; } } $joins = [['LEFT JOIN', UserActionRecord::tableName() .' as ua', 'ua.user_id = u.id']]; // print_r(['alias' => 'u', 'where' => $where, 'order' => $orderBy, 'select' => 'u.id,u.mobile,u.nickname,u.avatar_url,u.level,u.created_at,ua.last_pay_time']);exit; $list = User::listPage(['alias' => 'u', 'where' => $where, 'join' => $joins, 'order' => $orderBy, 'select' => 'u.id,u.mobile,u.nickname,u.avatar_url,u.level,u.created_at,ua.last_pay_at']); if (!empty($list['list'])) { $child_id_arr = array_column($list['list'], 'id'); // $user_arr = User::lists(['where' => [['mall_id' => $params['mall_id']],['id' => $child_id_arr]], 'index' => 'id']); $user_wallet_arr = UserWallet::lists(['where' => [['user_id' => $child_id_arr]], 'index' => 'user_id', 'select' => 'user_id,total_commission']); $user_team_statistics_arr = UserTeamStatistics::lists(['where' => [['user_id' => $child_id_arr]], 'index' => 'user_id', 'select' => 'user_id,active_user_team_total,loss_user_team_total,user_team_order_total']); $user_statistics_total_arr = UserStatisticsTotal::lists(['where' => [['user_id' => $child_id_arr]], 'index' =>'user_id','select' => 'id,user_id,order_num,order_money,pay_money,pay_num,finish_order_num,finish_order_money,refund_finish_order_num,refund_finish_order_money']); // print_r($user_statistics_total_arr);exit; $user_level_arr = UserLevel::lists(['where' => [['mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED]], 'index' => 'level', 'select' => 'level, name']); $team_data_config = \Yii::$app->services->setting->addons->get($params['mall_id'], AddonsEnum::ADDONS_NAME_TEAM_DATA, 'basic'); foreach ($list['list'] as &$item) { if (!empty($team_data_config) && $team_data_config['settle_type'] == 2) { $order_num = $user_statistics_total_arr[$item['id']]['finish_order_num'] ?? 0; $order_money = $user_statistics_total_arr[$item['id']]['finish_order_money'] ?? 0;// 消费金额 } else { $order_num = $user_statistics_total_arr[$item['id']]['pay_num']; $order_money = $user_statistics_total_arr[$item['id']]['pay_money']; if ($team_data_config['is_sub_refund']) {//渠道数据插件配置,开启扣除已售后订单数据 $order_num = bcsub($user_statistics_total_arr[$item['id']]['pay_num'], $user_statistics_total_arr[$item['id']]['refund_finish_order_num']); $order_money = bcsub($user_statistics_total_arr[$item['id']]['pay_money'], $user_statistics_total_arr[$item['id']]['refund_finish_order_money'], 2);// 消费金额 } } // 手机号 $mobile = !empty($item['mobile']) ? $item['mobile'] : ''; // 是否隐藏 $mobile = (($is_hide_mobile == 1) && $mobile) ? substr_replace($mobile, '****', 3, 4) : $mobile; // $item['nickname'] = $user_arr[$item['id']]['nickname'] ?? ''; // $item['avatar_url'] = $user_arr[$item['id']]['avatar_url'] ?? ''; $item['mobile'] = $mobile; // $item['level'] = $user_arr[$item['id']]['level'] ?? 0; $item['level_name'] = $user_level_arr[$item['level']]['name'] ?? MallSetting::getDefaultLevelName($params['mall_id']); $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']); $item['total_commission'] = $user_wallet_arr[$item['id']]['total_commission'] ?? 0; $item['active_user_team_total'] = $user_team_statistics_arr[$item['id']]['active_user_team_total'] ?? 0; $item['loss_user_team_total'] = $user_team_statistics_arr[$item['id']]['loss_user_team_total'] ?? 0; $item['user_team_order_total'] = $user_team_statistics_arr[$item['id']]['user_team_order_total'] ?? 0; $item['order_num'] = $order_num ?? 0; $item['order_money'] = $order_money ?? 0;// 消费金额 $item['user_id'] = $item['id']; } } $data['is_hide_mobile'] = $is_hide_mobile; return $list; } /** * 我的客户的业绩订单列表 * @param $params * @return array|bool|mixed|void */ public static function myChildrenOrders($params) { $is_hide_mobile = Yii::$app->services->setting->mall->get($params['mall_id'], 'user_operate.is_hide_mobile'); list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($params['user_id']); $where[] = ['<>', 'user_id', $params['user_id']]; $where[] = ['like', 'tree', "{$tree},%", false]; if (!empty($params['level'])) $where[] = ['deep' => $params['level'] + $parent_deep]; $userIdsFind = self::find(); self::paramPack([ 'where' => $where, 'select' => 'user_id' ], $userIdsFind); $userIds = $userIdsFind->column(); $time = time(); $date = date('Y-m-d', $time); $start_time = strtotime($date . ' 00:00:00'); $list = Order::listPage([ 'select' => 'id, order_no, user_id, pay_time, pay_money, goods_price, shipping_money', 'where' => [ ['in', 'user_id', $userIds], ['>=', 'created_at', $start_time], ['<=', 'created_at', $time], ['=', 'pay_status', OrderStatusEnum::PAY] ], 'with' => [ 'user' => function ($query) { $query->select('id, nickname, avatar_url, mobile, level'); } ] ]); if (!empty($list['list'])) { $user_level_arr = UserLevel::lists(['where' => [['mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED]], 'index' => 'level', 'select' => 'level, name']); foreach ($list['list'] as &$item) { if (!empty($item['user'])) { // 手机号 $mobile = $item['user']['mobile']; // 是否隐藏 $mobile = (($is_hide_mobile == 1) && $mobile) ? substr_replace($mobile, '****', 3, 4) : $mobile; $item['user']['mobile'] = $mobile; $item['user']['level_name'] = $user_level_arr[$item['user']['level']] ?? MallSetting::getDefaultLevelName($params['mall_id']); } $item['pay_time_text'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : ''; } } return $list; } /** * 根据类型返回用户id * * @param array $children_id_arr * @param string $type * * @return array|null */ public static function getMyChildrenUserIdsByType(array $children_id_arr, string $type) { if (empty($children_id_arr)) { return []; } $time = time(); $date = date('Y-m-d', $time); $start_time = strtotime($date . ' 00:00:00'); switch ($type) { case 'today_new': // 今日新增 $where = ['and', ['in', 'id', $children_id_arr], ['>=', 'created_at', $start_time], ['<=', 'created_at', $time]]; return User::find()->where($where)->select('id')->column(); case 'today_active': // 今日活跃 $where = ['and', ['in', 'id', $children_id_arr], ['>=', 'last_login_at', $start_time], ['<=', 'last_login_at', $time]]; return User::find()->where($where)->select('id')->column(); case 'recent_inactive': // 近期未访 //今日流失 修改成 沉睡客户: 90天未登陆 $where = ['and', ['in', 'id', $children_id_arr], ['<=', 'last_login_at', strtotime($date . ' 23:59:59') - 90 * 24 * 3600]]; return User::find()->where($where)->select('id')->column(); case 'today_orders': // 今日下单 $where = ['and', ['in', 'user_id', $children_id_arr], ['>=', 'created_at', $start_time], ['<=', 'created_at', $time], ['=', 'pay_status', OrderStatusEnum::PAY]]; return Order::find()->where($where)->select('DISTINCT(user_id)')->column(); case 'today_acquisitions': // 今日首购 $where = ['and', ['in', 'user_id', $children_id_arr], ['>=', 'created_at', $start_time], ['<=', 'created_at', $time], ['=', 'pay_status', OrderStatusEnum::PAY]]; $orders = Order::find()->groupBy('user_id')->where($where)->select('user_id, count(*) count')->having('count = 1')->asArray()->all(); return array_column($orders, 'user_id'); default: return null; } } public static function changeRelationship($params) { \Yii::$app->db->close(); $t = \Yii::$app->db->beginTransaction(); $stock_locks = []; try { $user_parent_model = User::findOne($params['parent_id']); if (empty($user_parent_model->is_inviter)) throw new Exception('该推荐人没有推广资格'); $user_model = User::findOne($params['user_id']); if (empty($params['parent_id'])) throw new Exception('请选择推荐人'); $arr['before_id'] = $params['before_parent_id'] = $user_model->parent_id;//修改前 $arr['parent_id'] = $params['after_parent_id'] = $params['parent_id'];//修改后 $user_model->parent_id = $params['parent_id']; //加锁 foreach ($arr as $id) { $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_USER_RELATIONSHIP , $id); $identification = uniqid(); $stock_locks[$lock_key] = $identification; if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new \Exception('修改关系,当前访问人数过多'); } list($code, $old_user_relation_ship, $old_all_tree, $old_deep, $old_tree) = self::getUserRelationshipData($params['user_id']);//查询当前用户的的tree信息 list($tree, $parent_deep, $parent_all_tree, $parent_all_tree_arr) = self::getTree($params['parent_id']);//查询上级的tree信息 $parent_all_tree_arr[] = $code; $new_all_tree = $parent_all_tree . ',' . $code; $insert_tree_arr = self::sliceArr($parent_all_tree_arr);//切分后新的关系链数组 self::saveTree($insert_tree_arr, $old_user_relation_ship, $params['user_id'], $parent_deep, 1); $user_model->parent_id = $params['parent_id']; $user_model->second_parent_id = $user_parent_model->parent_id ?? 0; $user_model->third_parent_id = $user_parent_model->second_parent_id ?? 0; $res = $user_model->save(); if ($res == false) throw new \Exception('维护当前用户的user表关系链错误'); $model_log = UserRelationshipLog::setData(['user_id' => $params['user_id'], 'before_id' => $arr['before_id'], 'after_id' => $params['parent_id']]); if ($model_log === false) throw new Exception(UserRelationshipLog::getStaticError()); //所有团队部分修改 $i = 1; $page_size = 1000; $new_deep = $parent_deep + 1; while ($child_list = self::find()->where(['like', 'tree', $old_tree . ',%', false]) ->andWhere(['<>','user_id',$params['user_id']]) ->select('user_id') ->offset(($i - 1) * $page_size)->groupBy('user_id')->limit($page_size)->all()) { foreach ($child_list as $item) { $user_id = $item['user_id']; list($code_, $old_child_relation_ship, $child_all_tree, $child_deep, $child_tree_) = self::getUserRelationshipData($user_id);//查询当前用户的的tree信息 $child_all_tree = str_replace($old_all_tree, $new_all_tree, $child_all_tree);//关系链替换 $tree_arr = explode(',', $child_all_tree);//转成数组 $insert_tree_arr = self::sliceArr($tree_arr);//按150切分 $cha_deep = $child_deep - $old_deep; self::saveTree($insert_tree_arr, $old_child_relation_ship, $user_id, $new_deep, $cha_deep); //大于3层的,不需要维护user表 if ($cha_deep <= 3) { self::stickUser($tree_arr,$user_id); } } $i++; } $t->commit(); LockHelper::batchUlock($stock_locks); // 关系链修改完成触发修改关系链事件 $event = new UserChangeRelationshipEvent($user_model->mall_id); Yii::$app->services->events->dispatch($event, $params, $event->listeners); UserPartitionRelationship::statisticsUserTeamData($new_all_tree, $old_all_tree,$user_model->mall_id); // Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, // ['new_all_tree' => $new_all_tree,'new_all_tree' => $old_all_tree, 'user_id' => $user_model->id], UserTeamProfitStatistics::class, 'userChangeRelationship'); } catch (\Exception $e) { $t->rollBack(); LockHelper::batchUlock($stock_locks); var_dump('修改关系的错误信息:' . $e->getMessage() . $e->getFile() . $e->getLine()); return false; } } //修改成平台 public static function changeRelationshipToPlatform($params) { \Yii::$app->db->close(); $t = \Yii::$app->db->beginTransaction(); $stock_locks = []; try { $user_model = User::findOne($params['user_id']); $arr['before_id'] = $params['before_parent_id'] = $user_model->parent_id;//修改前 $arr['parent_id'] = $params['after_parent_id'] = 0;//修改后 $user_model->parent_id = 0; //加锁 foreach ($arr as $id) { $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_USER_RELATIONSHIP , $id); $identification = uniqid(); $stock_locks[$lock_key] = $identification; if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new \Exception('修改关系,当前访问人数过多'); } list($code, $old_user_relation_ship, $old_all_tree, $old_deep, $old_tree) = self::getUserRelationshipData($params['user_id']);//查询当前用户的的tree信息 $parent_deep = 0; $parent_all_tree_arr = []; $parent_all_tree_arr[] = $code; $new_all_tree = $code; $insert_tree_arr = self::sliceArr($parent_all_tree_arr);//切分后新的关系链数组 self::saveTree($insert_tree_arr, $old_user_relation_ship, $params['user_id'], $parent_deep, 0); $user_model->parent_id = 0; $user_model->second_parent_id = 0; $user_model->third_parent_id = 0; $res = $user_model->save(); if ($res == false) throw new \Exception('维护当前用户的user表关系链错误'); $model_log = UserRelationshipLog::setData(['user_id' => $params['user_id'], 'before_id' => $arr['before_id'], 'after_id' => 0]); if ($model_log === false) throw new Exception(UserRelationshipLog::getStaticError()); //所有团队部分修改 $i = 1; $page_size = 1000; while ($child_list = self::find()->where(['like', 'tree', $old_tree . ',%', false]) ->andWhere(['<>','user_id',$params['user_id']]) ->select('user_id') ->offset(($i - 1) * $page_size)->groupBy('user_id')->orderBy('user_id')->limit($page_size)->all()) { foreach ($child_list as $item) { $user_id = $item['user_id']; list($code_, $old_child_relation_ship, $child_all_tree, $child_deep, $child_tree_) = self::getUserRelationshipData($user_id);//查询当前用户的的tree信息 $child_all_tree = str_replace($old_all_tree, $new_all_tree, $child_all_tree);//关系链替换 $tree_arr = explode(',', $child_all_tree);//转成数组 $insert_tree_arr = self::sliceArr($tree_arr);//按150切分 $cha_deep = $child_deep - $old_deep; self::saveTree($insert_tree_arr, $old_child_relation_ship, $user_id, 0, $cha_deep); //大于3层的,不需要维护user表 if ($cha_deep <= 3) { self::stickUser($tree_arr,$user_id); } } $i++; } $t->commit(); LockHelper::batchUlock($stock_locks); // 关系链修改完成触发修改关系链事件 $event = new UserChangeRelationshipEvent($user_model->mall_id); Yii::$app->services->events->dispatch($event, $params, $event->listeners); UserPartitionRelationship::statisticsUserTeamData($new_all_tree, $old_all_tree,$user_model->mall_id); // Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_ORDER, RabbitMqEnum::ORDER_QUEUE, // ['new_all_tree' => '','old_all_tree' => $old_all_tree, 'user_id' => $user_model->id], UserTeamProfitStatistics::class, 'userChangeRelationship'); } catch (\Exception $e) { $t->rollBack(); LockHelper::batchUlock($stock_locks); var_dump('修改关系的错误信息:' . $e->getMessage() . $e->getFile() . $e->getLine()); return false; } } public static function stickUser(&$tree_arr,$user_id){ array_pop($tree_arr); $parent_id_code = array_pop($tree_arr); $second_parent_id_code = array_pop($tree_arr); $third_parent_id_code = array_pop($tree_arr); $fields =[]; $fields['parent_id'] = !empty($parent_id_code) ? Base64Helper::Base642dec($parent_id_code) : 0; $fields['second_parent_id'] = !empty($second_parent_id_code) ? Base64Helper::Base642dec($second_parent_id_code) : 0; $fields['third_parent_id'] = !empty($third_parent_id_code) ? Base64Helper::Base642dec($third_parent_id_code) : 0; $res = User::updateAll($fields,['id' => $user_id]); if ($res === false) throw new \Exception(User::getStaticError()); } /** * @desc:关系链切分,150个为一组 * @Author: hua * @Date: 2021/12/1 * @Time: 9:28 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $arr * @param int $part * @return array */ public static function sliceArr($arr, $part = 1) { $insert_tree_arr = []; while ($part_tree = array_slice($arr, ($part - 1) * 150, 150)) { $insert_tree_arr[$part] = implode(',', $part_tree); $part++; } return $insert_tree_arr; } /** * @desc:把切分后的关系链数组保存 * @Author: hua * @Date: 2021/12/1 * @Time: 9:28 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $insert_tree_arr * @param $old_relation_ship * @param $user_id * @param $new_deep * @param $cha_deep */ protected static function saveTree($insert_tree_arr, $old_relation_ship, $user_id, $new_deep, $cha_deep) { foreach ($insert_tree_arr as $part => $tree) { if (isset($old_relation_ship[$part])) { $obj = $old_relation_ship[$part]; $obj->tree = $tree; $obj->deep = $new_deep + $cha_deep; $obj->save(); unset($old_relation_ship[$part]); } else { $obj = new self(); $obj->part = $part; $obj->user_id = $user_id; $obj->tree = $tree; $obj->deep = $new_deep + $cha_deep; $obj->save(); } } foreach ($old_relation_ship as $val) { UserPartitionRelationship::deleteAll(['id' => $val['id']]); } } protected static function getUserRelationshipData($user_id) { $condition = [ 'where' => [ ['user_id' => $user_id] ], 'order' => 'part asc' ]; $old_user_relation_ship_list = self::lists($condition, false);//查询当前用户的关系链列表 $code = Base64Helper::dec2Base64($user_id); $old_user_relation_ship = [];//旧的关系链数组,以分区为key $old_all_tree = '';//旧的关系链,不分区 $old_deep = 0;//旧的深度 $old_tree = '';//旧的最后一个分区存储的关系链 foreach ($old_user_relation_ship_list as $item) { $old_user_relation_ship[$item['part']] = $item; $old_deep = $item['deep']; $old_all_tree .= $item['tree'] . ','; $old_tree = $item['tree']; } $old_all_tree = trim($old_all_tree, ',');//旧的tree return [$code, $old_user_relation_ship, $old_all_tree, $old_deep, $old_tree]; } /** * @param int $type 1:下级 2:上级 * @param int $deep 层级 * @param int $page * @return array ['user_id'=>bind_time] count:10 */ public static function getRelationship($user_id, $page = 1, $keyword = '', $search_type = '', $type, $deep = 0) { $limit = 10; if ($type == 1) { $user_relationship = self::find()->where(['user_id' => $user_id])->orderBy('part desc')->one(); if (empty($user_relationship)) return []; $tree = $user_relationship->tree; //找出分片最大一个的tree,like查询10个下级 $model = self::find()->alias('upr') ->where(['like', 'upr.tree', "{$tree},%", false]) ->andWhere(['<>', 'upr.user_id', $user_id]) ->select(['upr.user_id', 'upr.updated_at']); if (!empty($deep)) $model->andWhere(['=', 'upr.deep', $deep + $user_relationship->deep]); //如果有关键字筛选 if ($keyword !== '') { $model->join('left join', User::tableName() . ' as u', 'u.id = upr.user_id'); if ($search_type == 1) $model->andWhere(['=', 'u.id', $keyword]); if ($search_type == 2) $model->andWhere(['=', 'u.nickname', $keyword]); if ($search_type == 3) $model->andWhere(['=', 'u.mobile', $keyword]); if ($search_type == 4) $model->andWhere(['=', 'u.level', $keyword]); } $count = $model->count(); $list = $model->offset(($page - 1) * $limit)->limit($limit)->all(); } else { $model = self::find(); $user_relationship = $model->where(['user_id' => $user_id])->select(['user_id', 'tree'])->all(); if (empty($user_relationship)) return []; $parent_ids = []; switch ($deep){ case 0: foreach ($user_relationship as $value) { $tree = explode(',', $value['tree']); array_pop($tree); $parent_ids = array_merge($parent_ids, array_map([Base64Helper::class, 'Base642dec'], $tree)); } break; case 1: $parent_ids[]=self::getParentIds($user_id,$deep); break; case 2: list($parent_id, $second_parent_id) = self::getParentIds($user_id,$deep); $parent_ids[]=$parent_id; $parent_ids[]=$second_parent_id; break; case 3: $parent_ids = self::getParentIdArr($user_id); break; } if ($keyword) { //var_dump($keyword); if ($search_type == 1) { if (in_array($keyword, $parent_ids)) { $model = User::find()->where(['id' => $keyword]); } else { return ['count' => 0, 'list' => []]; } } else { if ($search_type == 2) $search_keywork = 'nickname'; if ($search_type == 3) $search_keywork = 'mobile'; $model = User::find()->where(["$search_keywork" => $keyword, 'id' => $parent_ids]); } $count = $model->count(); $parent_ids = $model->select('id')->column(); } else { $parent_ids = array_unique($parent_ids); $count = count($parent_ids); } $ids = array_slice($parent_ids, ($page - 1) * $limit, $limit); $list = self::find()->where(['user_id' => $ids])->select(['user_id', 'updated_at'])->all(); } $data = []; foreach ($list as $val) { $data[$val['user_id']] = $val['updated_at']; } return ['count' => $count, 'list' => array_column($list, 'updated_at', 'user_id')]; } /** * @desc:分段查询 * @Author: hua * @Date: 2021/12/4 * @Time: 11:37 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $offset * @param $limit * @param $tree * @param array $params * @return false|mixed */ public static function batchGetTeamData($offset, $limit, $tree, $params = []) { $params['where'][] = ['like', 'tree', "{$tree},%", false]; $params['offset'] = ($offset - 1) * $limit; $params['limit'] = $limit; $params['order'] = 'id desc'; return self::lists($params); } /** * @desc:修改关系链后,统计直推、间推、团队会员数据 * @Author: hua * @Date: 2021/12/6 * @Time: 9:25 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $new_tree * @param $old_tree */ public static function statisticsUserTeamData($new_tree, $old_tree,$mall_id) { $new_ids = explode(',', $new_tree); $old_ids = explode(',', $old_tree); array_pop($new_ids);//把自身去掉 array_pop($old_ids);//把自身去掉 $ids = $new_ids; if (!empty($old_ids)) $ids = array_merge($new_ids, $old_ids); if (!empty($ids)) { $userIds = []; foreach ($ids as $user_id) { $user_id = Base64Helper::Base642dec($user_id); $userIds[]=$user_id; self::userTeamData($user_id,$mall_id); } \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, [ 'user_id'=>$userIds, 'mall_id'=>$mall_id, 'cate_ids'=>[MemberLabelEnum::POPULARIZE,MemberLabelEnum::LEAD] ], MemberLabelLogic::class, 'executeSyncCateId5Or6'); } } /** * @desc:统计直推、间推、团队会员数据 * @Author: hua * @Date: 2021/12/6 * @Time: 10:40 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $user_id * @return int */ public static function userTeamData($user_id,$mall_id) { $team_user_counts = self::getChildCounts($user_id);// 团队 $direct_user_counts = self::getChildCounts($user_id, 1);// 直推 $indirect_user_counts = self::getChildCounts($user_id, 2);// 间推 $userTeamStatistics = UserTeamStatistics::findOne(['user_id'=>$user_id,'mall_id'=>$mall_id,'status'=>StatusEnum::ENABLED]); if(empty($userTeamStatistics)){ $userTeamStatistics = new UserTeamStatistics(); $userTeamStatistics->loadDefaultValues(); $userTeamStatistics->mall_id = $mall_id; $userTeamStatistics->user_id = $user_id; } $userTeamStatistics->user_team_total = $team_user_counts; $userTeamStatistics->user_direct_total = $direct_user_counts; $userTeamStatistics->user_indirect_total = $indirect_user_counts; return $userTeamStatistics->save(); } /** * @notes:分页获取下级,并进行组合 * @param $user_id * @param $deep * @param $limit * @param $offset * @return array[] * @author: lun * @Time: 2022/12/13 16:15 */ public static function getChildIdMake($user_id, $deep = 0, $limit = 10, $offset = 1) { list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); $where[] = ['like', 'tree', "{$tree}%", false]; if (!empty($deep)) $where[] = ['between','deep', $parent_deep, ($deep + $parent_deep)]; $select = "id,part,user_id,tree,deep,created_at"; $order = 'deep asc,id asc'; $params = compact('where','select','order'); $params['offset'] = ($offset - 1) * $limit; $params['limit'] = $limit; $list = self::lists($params); $user_ids = array_column($list, 'user_id'); // 获取这些用户的上级id $parent_arr = User::find()->select('id,nickname,mobile,parent_id')->where(['id' => $user_ids, 'status' => StatusEnum::ENABLED])->indexBy('id')->asArray()->all(); foreach ($list as $key => $item){ $list[$key]['pid'] = $parent_arr[$item['user_id']]['parent_id']; $list[$key]['nickname'] = $parent_arr[$item['user_id']]['nickname']; $list[$key]['mobile'] = $parent_arr[$item['user_id']]['mobile']; } return ['list' => $list]; } /** * @notes:关系链树组合 * @param $list * @param $pid * @return array * @author: lun * @Time: 2022/12/13 16:14 */ public static function listToTree($list, $pid = 0) { $arr = array_filter($list,function ($v) use ($pid){ if($pid == $v['pid']){ return true; } return false; }); $arr = array_values($arr); $res = array_map(function ($v) use ($list){ $v['children'] = self::listToTree($list,$v['user_id']); return $v; },$arr); return $res; } /** * @Description: 获取用户是否需要绑定上级 * @Author: zsan * @DateTime 2023-05-22 17:37:59 * @param integer $mall_id * @param integer $user_id * @return integer */ public static function getIsNeedPopups($mall_id, $user_id = 0) { $is_bind_popups = 0; try{ if ($user_id == 0) throw new \Exception('not need pop-ups 1'); $relation_setting = \Yii::$app->services->setting->mall->get($mall_id, 'user_relation_setting.relation_setting'); $data = []; if (!empty($relation_setting)) $data = json_decode($relation_setting, true); if (empty($data['status'])) throw new \Exception('not need pop-ups 2'); if (empty($data['become_child_way'])) throw new \Exception('not need pop-ups 3'); if (!in_array($data['become_child_way'], [5])) throw new \Exception('not need pop-ups 4'); $user = User::findOne(['id' => $user_id, 'mall_id' => $mall_id]); if ($user->parent_id > 0) throw new \Exception('not need pop-ups 5'); $is_bind_popups = 1; }catch(\Exception $e){ $is_bind_popups = 0; }finally{ return $is_bind_popups; } } /** * @Description: 通过邀请码绑定用户 * @Author: zsan * @DateTime 2023-05-22 17:37:04 * @param integer $mall_id * @param integer $user_id * @param string $code * @return boolean */ public static function bindUserByCode($mall_id, $user_id, $code) { try { $user = User::findOne(['id' => $user_id, 'mall_id' => $mall_id]); if (!$user) throw new \Exception('id参数错误'); if ($user->parent_id > 0) throw new \Exception('该用户已有上级'); $parentCode = UserInviteCode::findOne(['mall_id' => $mall_id, 'code' => $code]); if (!$parentCode) throw new \Exception('邀请码错误'); if ($parentCode->user_id == $user_id) throw new \Exception('不能绑定自己为自己的上级'); if ($parentCode->user->is_inviter <= 0) throw new \Exception('该邀请码用户无推广资格'); // 因为邀请码绑定上级时,会出现两个人互相绑定,所以这里需要判断 $hasUserBind = self::hasReverseRelation($user_id, $parentCode->user_id); if ($hasUserBind) throw new \Exception('该用户已在需要绑定的关系链中,请勿重复操作'); $params['mall_id'] = $mall_id; $params['user_id'] = $user_id; $params['parent_id'] = $parentCode->user_id; $res = self::setData($params); if ($res == false) throw new Exception(self::getStaticError()); list($tree, $parent_deep, $all_tree, $all_tree_arr) = self::getTree($user_id); array_pop($all_tree_arr); //自身 array_pop($all_tree_arr); //直推上级 $second_parent_id = array_pop($all_tree_arr); //间推上级 $third_parent_id = array_pop($all_tree_arr); // $user->parent_id = $params['parent_id']; if ($second_parent_id) { $user->second_parent_id = Base64Helper::Base642dec($second_parent_id); } if ($third_parent_id) { $user->third_parent_id = Base64Helper::Base642dec($third_parent_id); } $user->temp_parent_id > 0 && $user->temp_parent_id = 0; $res = $user->save(); if ($res == false) throw new Exception($user->getErrorMessage()); return $res; } catch (\Exception $e) { self::setStaticError($e->getMessage()); return false; } } /** * 判断当前用户要绑定的上下级是否已绑定过自己 * @param $user_id * @param $parent_id * @return bool */ public static function hasReverseRelation($user_id, $parent_id): bool { // 获取当前需要绑定上级所有上级关系链id $parentIds = self::getParentIdArr($parent_id); // 获取当前需要绑定上级所有下级关系链id $childrenIds = self::getChildIdArr($user_id); $userIds = array_unique(array_merge($parentIds, $childrenIds)); return in_array($user_id, $userIds); } public static function fixDeep(){ $i = 1; $page_size = 1000; while ($list = User::find() ->where(['status'=>1]) ->orderBy('id desc') ->offset(($i - 1) * $page_size)->limit($page_size)->all()) { foreach ($list as $item) { list($tree, $deep, $all_tree, $all_tree_arr) = self::getTree($item['id']); $t_deep = count($all_tree_arr)-1; if($t_deep<0) $t_deep = 0; if($t_deep!= $deep){ $res = UserPartitionRelationship::updateAll(['deep'=>$t_deep],['user_id'=>$item['id']]); var_dump('user_id'.$item['id'].':::'.$res); } } $i++; } } /** * 返回某个用户id是不是当前$userId这个团队的 * * @param int $userId * @param int $targetUserId * * @return bool */ public static function isMyTeam(int $userId, int $targetUserId): bool { // 获取tree $myTree = self::find() ->where(['user_id' => $userId]) ->select('tree') ->scalar(); $myTree = explode(',', $myTree) ?: []; if (in_array(Base64Helper::dec2Base64($targetUserId), $myTree)) { return true; } $targetTree = self::find() ->where(['user_id' => $targetUserId]) ->select('tree') ->scalar(); $targetTree = explode(',', $targetTree) ?: []; return in_array(Base64Helper::dec2Base64($userId), $targetTree); } }