Statistics.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. <?php
  2. namespace common\logic\statistics;
  3. use addons\Agent\common\logic\reward\TeamAchievement;
  4. use common\enums\EventNameEnum;
  5. use common\enums\PayTypeEnum;
  6. use common\enums\RefundTypeEnum;
  7. use common\events\statistics\StatisticsOrderFinishEvent;
  8. use common\events\statistics\StatisticsOrderPayEvent;
  9. use common\events\statistics\StatisticsUserRegister;
  10. use common\helpers\FormatHelper;
  11. use common\models\base\User;
  12. use common\models\order\Order;
  13. use common\models\order\OrderDetail;
  14. use common\models\order\OrderRefund;
  15. use common\models\statistics\UserStatisticsTotal;
  16. use common\models\statistics\UserTeamStatistics;
  17. use common\models\user\User as UserUser;
  18. use common\models\user\UserActionRecord;
  19. use common\models\user\UserPartitionRelationship;
  20. use common\models\user\UserTeamAchievementOrder;
  21. use common\services\mall\AchievementService;
  22. use common\services\mall\order\UserOrderRelationsService;
  23. use Yii;
  24. use yii\base\Exception;
  25. /**
  26. * 用户数据统计
  27. * @Author lun
  28. * @DateTime 2021-11-16 19:07:32
  29. * @copyright: Copyright (c) 2020 广东七件事集团
  30. */
  31. class Statistics
  32. {
  33. /**
  34. * 订单创建统计
  35. * @Author: lun
  36. * @DateTime: 2021/11/20 0020 15:47
  37. * @Copyright: copyright (c) 2021 广东七件事集团
  38. * @param null $params
  39. */
  40. public function order_create($params = null)
  41. {
  42. $logsMsg = '统计 order_create 进入';
  43. Yii::$app->custom->logs($logsMsg, $params);
  44. // 订单创建统计处理
  45. Yii::$app->db->close();
  46. $t = Yii::$app->db->beginTransaction();
  47. try {
  48. if (empty($params)) throw new Exception('参数为空');
  49. $order_ids = $params['order_ids'];
  50. $orders = Order::lists([
  51. 'where' => [['id' => $order_ids]],
  52. 'with' => ['detail'],
  53. ]);
  54. if (empty($orders)) throw new Exception('订单查询为空');
  55. $goods_price = 0;
  56. $region_statistics = [];
  57. foreach ($orders as $order) {
  58. $goods_price += $order['goods_price'];
  59. $region_statistics[] = ['mall_id' => $order['mall_id'], 'province_id' => 2, 'city_id' => 3, 'order' => $order['pay_money']];
  60. foreach ($order['detail'] as $order_detail) {
  61. $goods_id = $order_detail['goods_id'];
  62. if (isset($goods_statistics[$goods_id])) {
  63. $goods_statistics[$goods_id]['sales_num'] += $order_detail['num'];
  64. } else {
  65. $goods_statistics[$goods_id]['sales_num'] = $order_detail['num'];
  66. $goods_statistics[$goods_id]['goods_id'] = $goods_id;
  67. $goods_statistics[$goods_id]['order_num'] = 1;
  68. }
  69. }
  70. }
  71. $data = ['order_num' => count($orders), 'order_money' => $goods_price];
  72. Yii::$app->services->statistics->user->set($orders[0]['mall_id'], $orders[0]['user_id'], $data); // 每日数据统计
  73. UserStatisticsTotal::setUserStatisticsTotal($orders[0]['mall_id'], $orders[0]['user_id'], $data); // 总数据统计
  74. Yii::$app->services->statistics->goods->set($orders[0]['mall_id'], $goods_statistics); //商品下单数统计
  75. //地区下单金额统计
  76. foreach ($region_statistics as $region) {
  77. if ($region['province_id'] && $region['city_id']) {
  78. Yii::$app->services->statistics->region->set($region);
  79. }
  80. }
  81. // 用户行为操作 - 订单创建
  82. $res = UserActionRecord::setData($orders[0]['mall_id'], $orders[0]['user_id'], ['last_create_order_at' => $orders[0]['created_at']]);
  83. if ($res == false) throw new Exception(UserActionRecord::getStaticError());
  84. $t->commit();
  85. $logsMsg = '统计 order_create 结束';
  86. Yii::$app->custom->logs($logsMsg);
  87. return true;
  88. } catch (\Exception $e) {
  89. $t->rollBack();
  90. $exception = FormatHelper::exception($e, "数据统计-订单创建");
  91. $logsMsg = '统计 order_create 异常';
  92. Yii::$app->custom->logs($logsMsg, $exception);
  93. return false;
  94. }
  95. }
  96. /**
  97. * 订单支付统计
  98. * @Author: lun
  99. * @DateTime: 2021/11/16 0016 10:51
  100. * @Copyright: copyright (c) 2021 广东七件事集团
  101. * @param null $params
  102. */
  103. public function order_pay($params = null)
  104. {
  105. $logsMsg = '统计 order_pay 进入';
  106. Yii::$app->custom->logs($logsMsg, $params);
  107. // 订单支付统计处理
  108. Yii::$app->db->close();
  109. $t = Yii::$app->db->beginTransaction();
  110. try {
  111. if (empty($params)) throw new Exception('参数为空');
  112. $order = Order::getOne([['id' => $params['id']]], true, ['detail']);
  113. if (empty($order)) throw new Exception('订单查询为空');
  114. $payArr = $userAloneArr = [];
  115. $payGoodsNum = 0;
  116. // 循环订单详情
  117. foreach ($order['detail'] as $detail) {
  118. $payGoodsNum += $detail['num'];
  119. $payArr[] = ['goods_id' => $detail['goods_id'], 'pay_money' => $detail['goods_price']];
  120. $userAloneArr[] = ['mall_id' => $detail['mall_id'], 'goods_id' => $detail['goods_id'], 'money' => $detail['goods_price'], 'buy_num' => $detail['num'], 'user_id' => $detail['user_id']];
  121. }
  122. // 初始化数据
  123. $data = [
  124. 'pay_num' => 1,
  125. 'pay_money' => $order['pay_money'] - $order['shipping_money'],
  126. 'original_order_money' => $order['original_goods_price'],
  127. 'pay_goods_num' => $payGoodsNum,
  128. 'balance_pay' => $order['payment_type'] == PayTypeEnum::BALANCE ? $order['pay_money'] : 0,
  129. 'wechat_pay' => $order['payment_type'] == PayTypeEnum::WECHAT ? $order['pay_money'] : 0,
  130. 'ali_pay' => $order['payment_type'] == PayTypeEnum::ALI ? $order['pay_money'] : 0,
  131. ];
  132. // 每日数据统计
  133. Yii::$app->services->statistics->goods->set($order['mall_id'], $payArr);
  134. Yii::$app->services->statistics->user->set($order['mall_id'], $order['user_id'], $data);
  135. Yii::$app->services->statistics->region->set(['mall_id' => $order['mall_id'], 'province_id' => $order['province'], 'city_id' => $order['city'], 'pay' => $order['pay_money']]);
  136. Yii::$app->services->statistics->alone->set($order['mall_id'], $userAloneArr);
  137. // 用户总数据统计
  138. UserStatisticsTotal::setUserStatisticsTotal($order['mall_id'], $order['user_id'], $data);
  139. // 用户行为操作 - 支付
  140. UserActionRecord::setData($order['mall_id'], $order['user_id'], ['last_pay_at' => $order['pay_time']]);
  141. // 添加用户团队订单数据
  142. $this->addUserTeamAchievementOrder($order, 1);
  143. // 用户上级数据维护
  144. $parent_data = ['user_id' => $order['user_id'], 'pay_money' => $data['pay_money'], 'original_order_money' => $data['original_order_money']];
  145. UserTeamStatisticsLogic::incBatchParentDataByUid($parent_data);
  146. // 保存统计数据
  147. $achievementService = new AchievementService([]);
  148. $achievementService->mall_id = $order['mall_id'];
  149. $statisticsBaseData = [
  150. 'user_id' => $order['user_id'],
  151. 'date' => date('Ymd', $order['created_at']),
  152. ];
  153. // 得到上级user_id
  154. $userOrderRelationsService = new UserOrderRelationsService([]);
  155. $userOrderRelationsService->mall_id = $order['mall_id'];
  156. $userOrderRelations = $userOrderRelationsService->getUserOrderRelations($order['id']);
  157. if ($userOrderRelations['is_find']) {
  158. $statisticsBaseData['parents_user_ids'] = $userOrderRelations['user_ids'];
  159. }
  160. $achievementService->saveAchievementStatisticsData(
  161. EventNameEnum::ORDER_PAY,
  162. $statisticsBaseData,
  163. $order
  164. );
  165. $t->commit();
  166. // 触发订单完成事件,事务提交完成后触发
  167. $event = new StatisticsOrderPayEvent($order['mall_id']);
  168. Yii::$app->services->events->dispatch($event, ['mall_id' => $order['mall_id'], 'id' => $order['id']], $event->listeners);
  169. $logsMsg = '统计 order_pay 结束';
  170. Yii::$app->custom->logs($logsMsg);
  171. return true;
  172. } catch (\Exception $e) {
  173. $t->rollBack();
  174. $exception = FormatHelper::exception($e, "数据统计-订单支付");
  175. $logsMsg = '统计 order_pay 异常';
  176. Yii::$app->custom->logs($logsMsg, $exception);
  177. return false;
  178. }
  179. }
  180. /**
  181. * 订单完成相关统计
  182. * @Author: lun
  183. * @DateTime: 2021/12/10 0010 14:31
  184. * @Copyright: copyright (c) 2021 广东七件事集团
  185. * @param null $params
  186. */
  187. public function order_finish($params = null)
  188. {
  189. $logsMsg = '统计 order_finish 进入';
  190. Yii::$app->custom->logs($logsMsg, $params);
  191. // 订单完成统计处理
  192. Yii::$app->db->close();
  193. $t = Yii::$app->db->beginTransaction();
  194. try {
  195. if (empty($params)) throw new Exception('参数为空');
  196. $order = Order::getOne([['id' => $params['id']]], true, ['detail']);
  197. if (empty($order)) throw new Exception('订单查询为空');
  198. $details = $order['detail'];
  199. $num = 0;
  200. $sellingPrice = 0; // 商品售价
  201. foreach ($details as $detail) {
  202. $num += $detail['num'];
  203. $sellingPrice += $detail['original_goods_price'];
  204. }
  205. // 初始化数据
  206. $data = [
  207. 'finish_order_num' => 1,
  208. 'finish_order_money' => $order['pay_money'] - $order['shipping_money'],
  209. 'finish_goods_num' => $num,
  210. 'finish_selling_price' => $sellingPrice,
  211. ];
  212. // 每日数据统计
  213. Yii::$app->services->statistics->user->set($order['mall_id'], $order['user_id'], $data);
  214. // 用户总数据统计
  215. UserStatisticsTotal::setUserStatisticsTotal($order['mall_id'], $order['user_id'], $data);
  216. // 用户上级数据维护
  217. $parent_data = ['user_id' => $order['user_id'], 'pay_money' => $data['finish_order_money'], 'selling_price' => $sellingPrice];
  218. UserTeamStatisticsLogic::incBatchParentFinishOrderByUid($parent_data);
  219. // 添加用户团队订单数据
  220. $this->addUserTeamAchievementOrder($order, 2);
  221. // 保存统计数据
  222. $achievementService = new AchievementService([]);
  223. $achievementService->mall_id = $order['mall_id'];
  224. $statisticsBaseData = [
  225. 'date' => date('Ymd', $order['finish_time']),
  226. 'user_id' => $order['user_id']
  227. ];
  228. // 得到上级user_id
  229. $userOrderRelationsService = new UserOrderRelationsService([]);
  230. $userOrderRelationsService->mall_id = $order['mall_id'];
  231. $userOrderRelations = $userOrderRelationsService->getUserOrderRelations($order['id']);
  232. if ($userOrderRelations['is_find']) {
  233. $statisticsBaseData['parents_user_ids'] = $userOrderRelations['user_ids'];
  234. }
  235. $achievementService->saveAchievementStatisticsData(
  236. EventNameEnum::ORDER_FINISH,
  237. $statisticsBaseData,
  238. $order
  239. );
  240. $t->commit();
  241. // 触发订单完成事件,事务提交完成后触发
  242. $event = new StatisticsOrderFinishEvent($order['mall_id']);
  243. Yii::$app->services->events->dispatch($event, ['mall_id' => $order['mall_id'], 'id' => $order['id']], $event->listeners);
  244. $logsMsg = '统计 order_finish 结束';
  245. Yii::$app->custom->logs($logsMsg);
  246. return true;
  247. } catch (\Exception $e) {
  248. $t->rollBack();
  249. $exception = FormatHelper::exception($e, "数据统计-订单完成");
  250. $logsMsg = '统计 order_finish 异常';
  251. Yii::$app->custom->logs($logsMsg, $exception);
  252. return false;
  253. }
  254. }
  255. /**
  256. * 订单关闭统计
  257. * @Author: lun
  258. * @DateTime: 2021/11/20 0020 16:09
  259. * @Copyright: copyright (c) 2021 广东七件事集团
  260. * @param null $params
  261. */
  262. public function order_close($params = null)
  263. {
  264. $logsMsg = '统计 order_close 进入';
  265. Yii::$app->custom->logs($logsMsg, $params);
  266. // 订单关闭统计处理
  267. Yii::$app->db->close();
  268. $t = Yii::$app->db->beginTransaction();
  269. try {
  270. if (empty($params)) throw new Exception('参数为空');
  271. $order = Order::getOne([['id' => $params['id']]], true, ['detail']);
  272. if (empty($order)) throw new Exception('订单查询为空');
  273. $details = $order['detail'];
  274. $num = 0;
  275. foreach ($details as $detail) {
  276. $num += $detail['num'];
  277. }
  278. // 初始化数据
  279. $data = ['cancel_order_num' => 1, 'cancel_order_money' => $order['pay_money'], 'cancel_goods_num' => $num];
  280. // 每日数据统计
  281. Yii::$app->services->statistics->user->set($order['mall_id'], $order['user_id'], $data);
  282. // 用户总数据统计
  283. UserStatisticsTotal::setUserStatisticsTotal($order['mall_id'], $order['user_id'], $data);
  284. $t->commit();
  285. $logsMsg = '统计 order_close 结束';
  286. Yii::$app->custom->logs($logsMsg);
  287. return true;
  288. } catch (\Exception $e) {
  289. $t->rollBack();
  290. $exception = FormatHelper::exception($e, "数据统计-订单关闭");
  291. $logsMsg = '统计 order_close 异常';
  292. Yii::$app->custom->logs($logsMsg, $exception);
  293. return false;
  294. }
  295. }
  296. /**
  297. * 售后订单数据统计
  298. * @Author: lun
  299. * @DateTime: 2021/11/20 0020 15:50
  300. * @Copyright: copyright (c) 2021 广东七件事集团
  301. * @param $params
  302. */
  303. public function order_refund($params)
  304. {
  305. $logsMsg = '统计 order_refund 进入';
  306. Yii::$app->custom->logs($logsMsg, $params);
  307. // 订单售后统计处理
  308. Yii::$app->db->close();
  309. $t = Yii::$app->db->beginTransaction();
  310. try {
  311. // 查询订单
  312. $refund = OrderRefund::findOne(['id' => $params['id']]);
  313. if (empty($refund)) throw new \yii\db\Exception('售后订单查询失败');
  314. // 数据处理
  315. switch ($params['type']) {
  316. case RefundTypeEnum::EVENT_APPLY:
  317. $statistics = ['refund_order_num' => 1];
  318. break;
  319. case RefundTypeEnum::EVENT_FINISH:
  320. $order_detail_id = $refund['order_detail_id'];
  321. $OrderDetail = OrderDetail::findOne(['id' => $order_detail_id]);
  322. $goods_num = empty($OrderDetail) ? 0 : $OrderDetail->num;
  323. in_array($refund['type'], [RefundTypeEnum::MONEY, RefundTypeEnum::MONEY_AND_PRODUCT]) && $statistics = ['refund_order_money' => $refund['reality_refund_price'], 'refund_goods_num' => $goods_num];
  324. break;
  325. }
  326. if (!empty($statistics)) {
  327. // 用户数据统计
  328. Yii::$app->services->statistics->user->set($refund['mall_id'], $refund['user_id'], $statistics);
  329. // 用户总数据统计
  330. UserStatisticsTotal::setUserStatisticsTotal($refund['mall_id'], $refund['user_id'], $statistics);
  331. }
  332. $t->commit();
  333. $logsMsg = '统计 order_refund 结束';
  334. Yii::$app->custom->logs($logsMsg);
  335. return true;
  336. } catch (\Exception $e) {
  337. $t->rollBack();
  338. $exception = FormatHelper::exception($e, "数据统计-订单创建");
  339. $logsMsg = '统计 order_refund 异常';
  340. Yii::$app->custom->logs($logsMsg, $exception);
  341. return false;
  342. }
  343. }
  344. /**
  345. * 用户注册
  346. * @Author: lun
  347. * @DateTime: 2021/11/25 0025 17:21
  348. * @Copyright: copyright (c) 2021 广东七件事集团
  349. * @param $params
  350. */
  351. public function user_register($params)
  352. {
  353. $logsMsg = '统计 user_register 进入';
  354. Yii::$app->custom->logs($logsMsg, $params);
  355. // 不做统计处理
  356. if (isset($params['is_statistics']) && $params['is_statistics'] === 0) return true;
  357. // 注册事件处理
  358. Yii::$app->db->close();
  359. $user_id = $params['user_id'];
  360. $user = User::findOne(['id' => $user_id]);
  361. if (empty($user)) throw new \Exception('查无此用户');
  362. //初始化新增的用户
  363. UserTeamStatistics::setUserTeamStatistics($user->mall_id, $user_id, []);
  364. $t = Yii::$app->db->beginTransaction();
  365. try {
  366. /** 团队数据处理start **/
  367. // 1、获取该用户的所有上级
  368. // $user_ids = UserRelationship::getParentIdArr($user_id);// 返回的数组是最高层级处于第一位
  369. $user_ids = UserPartitionRelationship::getParentIdArr($user_id);
  370. if (empty($user_ids)) throw new \Exception('该用户无上级');
  371. $user_ids = array_reverse($user_ids); // 数组倒叙
  372. foreach ($user_ids as $deep => $uid) {
  373. $data = [];
  374. // 2、给上级所有user_team_total字段+1
  375. $data['user_team_total'] = 1;
  376. // 3、给间推上级团队人数user_direct_total字段+1
  377. $deep == 0 && $data['user_direct_total'] = 1;
  378. // 4、给间间推上级团队人数user_indirect_total字段+1
  379. $deep == 1 && $data['user_indirect_total'] = 1;
  380. // 5、保存数据
  381. $res = UserTeamStatistics::setUserTeamStatistics($user->mall_id, $uid, $data);
  382. if ($res == false) throw new \Exception(UserTeamStatistics::getStaticError());
  383. }
  384. /** 团队数据处理end **/
  385. $t->commit();
  386. // 触发注册事件,事务提交完成后触发
  387. $event = new StatisticsUserRegister($user->mall_id);
  388. Yii::$app->services->events->dispatch($event, ['mall_id' => $user->mall_id, 'user_id' => $user_id], $event->listeners);
  389. $logsMsg = '统计 user_register 结束';
  390. Yii::$app->custom->logs($logsMsg);
  391. return true;
  392. } catch (\Exception $e) {
  393. $t->rollBack();
  394. $exception = FormatHelper::exception($e, "数据统计-用户注册");
  395. $logsMsg = '统计 user_register 异常';
  396. Yii::$app->custom->logs($logsMsg, $exception);
  397. return false;
  398. }
  399. }
  400. /**
  401. * 添加团队订单
  402. *
  403. * @param array $order
  404. * @param integer $status
  405. * @return void
  406. */
  407. public function addUserTeamAchievementOrder(array $order, int $status)
  408. {
  409. // 下单人
  410. $user_id = $from_user_id = $order['user_id'];
  411. $superior_users = [];
  412. $time = time();
  413. // 查询上级团队
  414. $level = 0;
  415. while ($user_id && !empty($info = UserUser::getUserParents($user_id))) {
  416. $info['parent_id'] && $info['parent_id'] > 0 && $superior_users[] = ['superior_level' => $level + 1, 'superior_user_id' => $info['parent_id']];
  417. $info['second_parent_id'] && $info['second_parent_id'] > 0 && $superior_users[] = ['superior_level' => $level + 2, 'superior_user_id' => $info['second_parent_id']];
  418. $info['third_parent_id'] && $info['third_parent_id'] > 0 && $superior_users[] = ['superior_level' => $level + 3, 'superior_user_id' => $info['third_parent_id']];
  419. $user_id = $info['third_parent_id'];
  420. $level = $level + 3;
  421. }
  422. $team_orders = [];
  423. foreach ($superior_users as $item) {
  424. $team_orders[] = [
  425. 'mall_id' => $order['mall_id'],
  426. 'order_id' => $order['id'],
  427. 'user_id' => $from_user_id,
  428. 'superior_user_id' => $item['superior_user_id'],
  429. 'superior_level' => $item['superior_level'],
  430. 'status' => $status,
  431. 'created_at' => $time,
  432. ];
  433. }
  434. $team_orders && UserTeamAchievementOrder::batchInsertData($team_orders);
  435. }
  436. }