| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335 |
- <?php
- namespace common\models\user;
- use addons\Agent\common\models\Agent;
- use common\enums\AddonsEnum;
- use common\enums\MemberLabelEnum;
- use common\enums\OrderStatusEnum;
- use common\enums\RabbitMqEnum;
- use common\enums\RedisKeyEnum;
- use common\enums\StatusEnum;
- use common\events\user\UserChangeRelationshipEvent;
- use common\helpers\Base64Helper;
- use common\helpers\DateHelper;
- use common\helpers\LockHelper;
- use common\logic\memberLabel\MemberLabelLogic;
- use common\models\base\BaseActiveRecord;
- use common\models\common\MallSetting;
- use common\models\order\Order;
- use common\models\statistics\UserStatisticsTotal;
- use PHPUnit\Util\Exception;
- use Yii;
- use common\helpers\ArrayHelper;
- use function Symfony\Component\String\s;
- /**
- * This is the model class for table "qimall_user_partition_relationship".
- *
- *
- * @property int $id
- * @property int $part 分片,片数
- * @property int $user_id 用户ID
- * @property string $tree 推荐关系树,【注意字符集!!!】
- * @property int $deep 层级
- * @property int $created_at
- * @property int $updated_at
- */
- class UserPartitionRelationship extends BaseActiveRecord
- {
- /**
- * {@inheritdoc}
- */
- public static function tableName()
- {
- return '{{%user_partition_relationship}}';
- }
- /**
- * {@inheritdoc}
- */
- public function rules()
- {
- return [
- [['part', 'user_id', 'deep', 'created_at', 'updated_at'], 'integer'],
- [['tree'], 'string', 'max' => 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);
- }
- }
|