DoubleCopyRelation.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <?php
  2. namespace addons\DoubleCopy\common\models;
  3. use addons\DoubleCopy\common\logic\DoubleCopyLogic;
  4. use common\enums\StatusEnum;
  5. use common\helpers\ArrayHelper;
  6. use common\models\user\User;
  7. use Yii;
  8. use yii\db\Exception;
  9. /**
  10. * This is the model class for table "{{%addons_double_copy_relation}}".
  11. *
  12. * @property int $id 主键
  13. * @property int $mall_id 商城id
  14. * @property int $user_id 用户id
  15. * @property int $pid 用户上级id
  16. * @property int $deep 用户与上级的层级
  17. * @property int $status 状态【1启用 0禁用 -1删除】
  18. * @property int|null $created_at 创建时间
  19. * @property int|null $updated_at 修改时间
  20. */
  21. class DoubleCopyRelation extends \common\models\base\BaseActiveRecord
  22. {
  23. /**
  24. * {@inheritdoc}
  25. */
  26. public static function tableName()
  27. {
  28. return '{{%addons_double_copy_relation}}';
  29. }
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public function rules()
  34. {
  35. return [
  36. [['mall_id', 'user_id', 'pid', 'deep'], 'required'],
  37. [['mall_id', 'user_id', 'pid', 'deep', 'status', 'created_at', 'updated_at'], 'integer'],
  38. ];
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public function attributeLabels()
  44. {
  45. return [
  46. 'id' => '主键',
  47. 'mall_id' => '商城id',
  48. 'user_id' => '用户id',
  49. 'pid' => '用户上级id',
  50. 'deep' => '用户与上级的层级',
  51. 'status' => '状态【1启用 0禁用 -1删除】',
  52. 'created_at' => '创建时间',
  53. 'updated_at' => '修改时间',
  54. ];
  55. }
  56. /**
  57. * 查询数据
  58. * @Author:lun
  59. * @Date:2023-11-28 18:18
  60. * @Copyright:copyright(c)2023 广东七件事集团
  61. * @param $params
  62. * @return bool
  63. */
  64. public static function setData($params)
  65. {
  66. try {
  67. if (empty($params['pid'])) return true;// 没有上级无需保存
  68. $check = self::find()->where(['user_id' => $params['user_id'], 'pid' => $params['pid'], 'status' => StatusEnum::ENABLED])->asArray()->one();
  69. if ($check) return true;// 已存在此关系链
  70. $model = new self();
  71. $model->deep = 1;
  72. $model->loadDefaultValues();
  73. if (!$model->load($params, '') || !$model->save()) throw new Exception($model->getErrorMessage());
  74. // 获取上级关系链
  75. $parent_relation = self::getRelationByUserId($params['pid']);
  76. $rows = [];
  77. $time = time();
  78. foreach ($parent_relation as $relation) {
  79. $rows[] = [
  80. 'mall_id' => $relation['mall_id'],
  81. 'user_id' => $params['user_id'],
  82. 'pid' => $relation['pid'],
  83. 'deep' => $relation['deep'] + 1,
  84. 'created_at' => $time,
  85. 'updated_at' => $time,
  86. ];
  87. }
  88. // 批量增加上级关系链
  89. if (!empty($rows)) {
  90. $field = ['mall_id','user_id','pid','deep','created_at','updated_at'];
  91. $res = Yii::$app->db->createCommand()->batchInsert(self::tableName(), $field, $rows)->execute();
  92. if ($res == false) throw new Exception("批量关系链出错");
  93. }
  94. return true;
  95. } catch (\Exception $e) {
  96. self::setStaticError($e->getMessage());
  97. return false;
  98. }
  99. }
  100. /**
  101. * 根据用户id获取关系链
  102. * @Author:lun
  103. * @Date:2023-11-28 18:21
  104. * @Copyright:copyright(c)2023 广东七件事集团
  105. * @param $user_id
  106. * @param $sort
  107. * @return array|\yii\db\ActiveRecord[]
  108. */
  109. public static function getRelationByUserId($user_id, $sort = 'asc')
  110. {
  111. $select = 'mall_id,user_id,pid,deep,created_at';
  112. return self::find()->select($select)->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->orderBy('deep '.$sort)->asArray()->all();
  113. }
  114. /**
  115. * 根据上级id获取关系链
  116. * @Author:lun
  117. * @Date:2023-11-28 18:21
  118. * @Copyright:copyright(c)2023 广东七件事集团
  119. * @param $pid
  120. * @param $sort
  121. * @return array|\yii\db\ActiveRecord[]
  122. */
  123. public static function getRelationByPid($pid, $sort = 'desc')
  124. {
  125. $select = 'user_id,pid,deep,created_at';
  126. return self::find()->select($select)->where(['pid' => $pid, 'status' => StatusEnum::ENABLED])->orderBy('deep '.$sort)->asArray()->all();
  127. }
  128. /**
  129. * 获取上级关系uids
  130. * @Author:lun
  131. * @Date:2023-11-28 19:00
  132. * @Copyright:copyright(c)2023 广东七件事集团
  133. * @param $user_id
  134. * @param $sort
  135. * @return array
  136. */
  137. public static function getRelationPids($user_id, $sort = 'asc')
  138. {
  139. return self::find()->select('pid')->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->orderBy('deep '.$sort)->column();
  140. }
  141. /**
  142. * 递归获取上级关系链
  143. * @Author:lun
  144. * @Date:2023-11-28 18:39
  145. * @Copyright:copyright(c)2023 广东七件事集团
  146. * @param $user_id
  147. * @param $relation
  148. * @return array|mixed
  149. */
  150. public static function recursionRelation($user_id, &$relations = [])
  151. {
  152. // 获取当前用户信息
  153. $user = DoubleCopyUser::find()->select('mall_id,user_id,pid')->where(['user_id' => $user_id, 'status' => StatusEnum::ENABLED])->asArray()->one();
  154. if (!empty($user['pid'])) {
  155. $relations[] = $user['pid'];
  156. self::recursionRelation($user['pid'], $relations);
  157. }
  158. return $relations;
  159. }
  160. /**
  161. * 断层重置关系链
  162. * @Author:lun
  163. * @Date:2023-11-30 14:50
  164. * @Copyright:copyright(c)2023 广东七件事集团
  165. * @param $mall_id
  166. * @param $pid
  167. * @return void
  168. */
  169. public static function fractureResetRelation($mall_id, $pid)
  170. {
  171. $offset = 1;
  172. $limit = 1000;
  173. while ($list = self::find()->select('user_id')->where(['mall_id' => $mall_id, 'pid' => $pid, 'status' => StatusEnum::ENABLED])->orderBy('id asc')->offset(($offset - 1) * $limit)->limit($limit)->asArray()->all()) {
  174. foreach ($list as $item) {
  175. self::resetRelation($mall_id, $item['user_id']);
  176. // 修改平台补贴用户ID
  177. $user = DoubleCopyUser::findOne(['user_id' => $item['user_id'], 'status' => StatusEnum::ENABLED]);
  178. if (!empty($user)) {
  179. $parent_ids = self::getRelationPids($user->user_id);// 获取用户上级关系链
  180. $user->topid = DoubleCopyLogic::computeTopid($user->pid, $parent_ids);
  181. $user->save();
  182. }
  183. }
  184. $offset++;
  185. }
  186. }
  187. /**
  188. * 重置用户关系链
  189. * @Author:lun
  190. * @Date:2023-11-28 18:49
  191. * @Copyright:copyright(c)2023 广东七件事集团
  192. * @param $user_id
  193. * @return true
  194. */
  195. public static function resetRelation($mall_id, $user_id)
  196. {
  197. $relations[] = $user_id;
  198. self::recursionRelation($user_id, $relations);// 生成新的关系链
  199. // 软删除旧关系链
  200. self::updateAll(['status' => StatusEnum::DELETE], ['user_id' => $user_id, 'status' => StatusEnum::ENABLED]);
  201. if ($relations) {
  202. $rows = [];
  203. $time = time();
  204. foreach ($relations as $deep => $pid) {
  205. if ($pid == $user_id) continue;
  206. $rows[] = [
  207. 'mall_id' => $mall_id,
  208. 'user_id' => $user_id,
  209. 'pid' => $pid,
  210. 'deep' => $deep,
  211. 'created_at' => $time,
  212. 'updated_at' => $time,
  213. ];
  214. }
  215. // 批量增加上级关系链
  216. if (!empty($rows)) {
  217. $field = ['mall_id','user_id','pid','deep','created_at','updated_at'];
  218. $res = Yii::$app->db->createCommand()->batchInsert(self::tableName(), $field, $rows)->execute();
  219. if ($res == false) throw new Exception("用户id={$user_id}重置关系链失败");
  220. }
  221. }
  222. return true;
  223. }
  224. /**
  225. * 重置商城所有用户二二复制关系链
  226. * @Author:lun
  227. * @Date:2023-11-29 18:10
  228. * @Copyright:copyright(c)2023 广东七件事集团
  229. * @param $mall_id
  230. * @return void
  231. */
  232. public static function resetMallUser($mall_id)
  233. {
  234. try {
  235. $offset = 1;
  236. $limit = 1000;
  237. while ($list = DoubleCopyUser::find()->select('user_id')->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED])->orderBy('id asc')->offset(($offset - 1) * $limit)->limit($limit)->asArray()->all()) {
  238. foreach ($list as $item) {
  239. self::resetRelation($mall_id, $item['user_id']);
  240. }
  241. $offset++;
  242. }
  243. } catch (\Exception $e) {
  244. Yii::error($e->getMessage());
  245. }
  246. }
  247. /**
  248. * 获取用户团队关系
  249. * @Author:lun
  250. * @Date:2023-11-29 18:48
  251. * @Copyright:copyright(c)2023 广东七件事集团
  252. * @param $user_id
  253. * @param $deep
  254. * @param $limit
  255. * @return array[]
  256. */
  257. public static function getTeamRelation($user_id, $deep, $limit, $is_unshift_self = true)
  258. {
  259. // 获取用户最高层级
  260. $top_deep = self::find()->select('deep')->where(['pid' => $user_id, 'status' => StatusEnum::ENABLED])->orderBy('deep desc')->scalar();
  261. $select_deep = $deep > $top_deep ? 0 : $top_deep - $deep;
  262. $list = self::find()->where(['pid' => $user_id, 'status' => StatusEnum::ENABLED])
  263. ->andWhere(['>=', 'deep', $select_deep])
  264. ->orderBy('deep desc')->limit($limit)
  265. ->asArray()->all();
  266. $is_unshift_self && array_unshift($list, ['user_id' => $user_id, 'pid' => 0, 'deep' => 0]);
  267. $user_ids = array_column($list, 'user_id');
  268. // 获取这些用户的上级id
  269. $parent_arr = User::find()->select('id,nickname,mobile,parent_id')->where(['id' => $user_ids, 'status' => StatusEnum::ENABLED])->indexBy('id')->asArray()->all();
  270. foreach ($list as $key => $item){
  271. $list[$key]['pid'] = $parent_arr[$item['user_id']]['parent_id'];
  272. $list[$key]['nickname'] = $parent_arr[$item['user_id']]['nickname'];
  273. $list[$key]['mobile'] = $parent_arr[$item['user_id']]['mobile'];
  274. }
  275. return ['list' => $list];
  276. }
  277. /**
  278. * 树状图组合
  279. * @Author:lun
  280. * @Date:2023-12-04 17:38
  281. * @Copyright:copyright(c)2023 广东七件事集团
  282. * @param $list
  283. * @param $pid
  284. * @return array
  285. */
  286. public static function listToTree($list, $pid = 0)
  287. {
  288. $arr = array_filter($list,function ($v) use ($pid){
  289. if($pid == $v['pid']){
  290. return true;
  291. }
  292. return false;
  293. });
  294. $arr = ArrayHelper::arraySort($arr, 'pos_num');
  295. $arr = array_values($arr);
  296. $res = array_map(function ($v) use ($list){
  297. $v['children'] = self::listToTree($list,$v['user_id']);
  298. return $v;
  299. },$arr);
  300. return $res;
  301. }
  302. }