UserBehaviorLogsService.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. namespace common\services\mall\user;
  3. use common\enums\UserBehaviorLogsEnum;
  4. use common\enums\RabbitMqEnum;
  5. use common\events\user\UserBehaviorLogsEvent;
  6. use common\helpers\ArrayHelper;
  7. use common\helpers\FormatHelper;
  8. use common\models\common\MallSetting;
  9. use common\models\user\User;
  10. use common\models\user\UserBehaviorLogs;
  11. use common\models\user\UserLevel;
  12. use Exception;
  13. use InvalidArgumentException;
  14. use Yii;
  15. class UserBehaviorLogsService
  16. {
  17. /**
  18. * 处理用户行为事件
  19. *
  20. * @param array $data
  21. *
  22. * @return void
  23. */
  24. public static function handleSync(array $data)
  25. {
  26. self::getInsertDataByParams($data);
  27. UserBehaviorLogs::setData($data);
  28. }
  29. /**
  30. * 触发行为记录事件
  31. *
  32. * @param int $mallId
  33. * @param array $data
  34. *
  35. * @return void
  36. */
  37. public static function dispatchUserBehaviorLogsEvent(int $mallId, array $data)
  38. {
  39. if (empty($mallId) && empty($data['mall_id'])) {
  40. $data['method'] = __METHOD__;
  41. Yii::$app->custom->logs('mall_id不存在', compact('data'));
  42. return;
  43. }
  44. if (empty($data['behavior']) || !isset(UserBehaviorLogsEnum::BEHAVIOR_MAP[$data['behavior']])) {
  45. $data['method'] = __METHOD__;
  46. Yii::$app->custom->logs('行为类型不存在', $data);
  47. return;
  48. }
  49. try {
  50. $data['ip'] = !empty($data['ip']) ? $data['ip'] : ArrayHelper::get_client_ip();
  51. $data['operation_time'] = time();
  52. $data['mall_id'] = !empty($data['mall_id']) ? $data['mall_id'] : $mallId;
  53. $event = new UserBehaviorLogsEvent($data['mall_id']);
  54. Yii::$app->services->events->dispatch($event, $data, $event->listeners);
  55. } catch (Exception $e) {
  56. $data['method'] = __METHOD__;
  57. Yii::$app->custom->logs(FormatHelper::exception($e, '触发用户行为事件失败'), compact('data'));
  58. }
  59. }
  60. /**
  61. * 根据传入的数据,完善模型写入时所需的数据
  62. *
  63. * @param array $params
  64. *
  65. * @return void
  66. */
  67. protected static function getInsertDataByParams(array &$params)
  68. {
  69. // 判断是否是系统自动操作(不包含下级退单的情况,因为下级退单认为是下级用户的操作)
  70. if (!empty($params['system_auto'])) {
  71. $params['operator_user_id'] = 0;
  72. $params['operator_user_type'] = UserBehaviorLogsEnum::OPERATOR_USER_TYPE_SYSTEM;
  73. } else {
  74. $params['operator_user_id'] = !empty($params['operator_user_id']) ? $params['operator_user_id'] : $params['user_id'];
  75. $params['operator_user_type'] = !empty($params['is_admin']) ? UserBehaviorLogsEnum::OPERATOR_USER_TYPE_ADMIN : UserBehaviorLogsEnum::OPERATOR_USER_TYPE_USER;
  76. }
  77. $params['operator_target_user_id'] = !empty($params['operator_target_user_id']) ? $params['operator_target_user_id'] : $params['user_id'];
  78. // 存在order_id则存储起来
  79. if (!empty($params['order_id'])) {
  80. $params['extra_info']['order_id'] = $params['order_id'];
  81. }
  82. switch ($params['behavior']) {
  83. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_MOBILE:
  84. if (empty($params['new_mobile'])) {
  85. $params['new_mobile'] = User::getUserMobile($params['mall_id'], $params['operator_target_user_id']);
  86. }
  87. break;
  88. case UserBehaviorLogsEnum::BEHAVIOR_CANCEL:
  89. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_PWD:
  90. if (empty($params['mobile'])) {
  91. $params['mobile'] = User::getUserMobile($params['mall_id'], $params['operator_target_user_id']);
  92. }
  93. break;
  94. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_RELATIONSHIP:
  95. if (empty($params['before_parent_mobile']) && !empty($params['before_parent_id'])) {
  96. $params['before_parent_mobile'] = User::getUserMobile($params['mall_id'], $params['before_parent_id']);
  97. }
  98. if (empty($params['after_parent_mobile']) && !empty($params['after_parent_id'])) {
  99. $params['after_parent_mobile'] = User::getUserMobile($params['mall_id'], $params['after_parent_id']);
  100. }
  101. break;
  102. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_PAY_PWD:
  103. $params['mobile'] = User::getUserMobile($params['mall_id'], $params['operator_target_user_id']);
  104. break;
  105. case UserBehaviorLogsEnum::BEHAVIOR_MANUAL_UPGRADE:
  106. case UserBehaviorLogsEnum::BEHAVIOR_MANUAL_DOWNGRADE:
  107. $params['mobile'] = User::getUserMobile($params['mall_id'], $params['operator_target_user_id']);
  108. $params['extra_info']['after_level'] = self::getValueOrReturnDefault($params, 'after_level', 0);
  109. $params['extra_info']['before_level'] = self::getValueOrReturnDefault($params, 'before_level', 0);
  110. break;
  111. case UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_UPGRADE:
  112. case UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_DOWNGRADE:
  113. // 判断是否是是否是系统操作(不是自己,就是系统)
  114. if (!empty($params['operator_user_id']) && !empty($params['operator_target_user_id'])) {
  115. $params['extra_info']['is_system'] = (int)($params['operator_user_id'] != $params['operator_target_user_id']);
  116. }
  117. if (!empty($params['upgrade_type'])) {
  118. $params['extra_info']['upgrade_type'] = $params['upgrade_type'];
  119. }
  120. $params['mobile'] = User::getUserMobile($params['mall_id'], $params['operator_target_user_id']);
  121. $params['extra_info']['after_level'] = self::getValueOrReturnDefault($params, 'after_level', 0);
  122. $params['extra_info']['before_level'] = self::getValueOrReturnDefault($params, 'before_level', 0);
  123. break;
  124. }
  125. $params['desc'] = self::getBehaviorDesc($params);
  126. }
  127. /**
  128. * 将行为事件写入队列
  129. *
  130. * @param array $data
  131. *
  132. * @return void
  133. */
  134. public static function logsPushQueue(array $data)
  135. {
  136. try {
  137. Yii::$app->services->rabbitMq->push(
  138. RabbitMqEnum::EXCHANGE_TASK,
  139. RabbitMqEnum::TASK_QUEUE,
  140. $data,
  141. self::class,
  142. 'handleSync'
  143. );
  144. } catch (Exception $e) {
  145. $data['method'] = __METHOD__;
  146. Yii::$app->custom->logs(FormatHelper::exception($e, '行为日志发布队列失败'), $data);
  147. }
  148. }
  149. /**
  150. * 根据数据,返回是手动升降级还是系统升降级
  151. *
  152. * @param array $data
  153. *
  154. * @return int
  155. */
  156. public static function getLevelChangeBehavior(array $data): int
  157. {
  158. if (!empty($data['is_admin'])) {
  159. return $data['after_level'] > $data['before_level'] ? UserBehaviorLogsEnum::BEHAVIOR_MANUAL_UPGRADE : UserBehaviorLogsEnum::BEHAVIOR_MANUAL_DOWNGRADE;
  160. }
  161. return $data['after_level'] > $data['before_level'] ? UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_UPGRADE : UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_DOWNGRADE;
  162. }
  163. /**
  164. * 获取行为描述
  165. *
  166. * @param array $params
  167. *
  168. * @return string
  169. */
  170. protected static function getBehaviorDesc(array $params): string
  171. {
  172. switch ($params['behavior']) {
  173. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_MOBILE:
  174. $str = '会员ID:%d, 由旧手机号:%d 更改为 新手机号:%d';
  175. $args = [
  176. self::getValueOrReturnDefault($params, 'user_id'),
  177. self::getValueOrReturnDefault($params, 'old_mobile'),
  178. self::getValueOrReturnDefault($params, 'new_mobile'),
  179. ];
  180. break;
  181. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_RELATIONSHIP:
  182. $afterParentId = self::getValueOrReturnDefault($params, 'after_parent_id');
  183. $beforeParentId = self::getValueOrReturnDefault($params, 'before_parent_id');
  184. if (!empty($afterParentId) && !empty($beforeParentId)) {
  185. $str = '由原来分享人ID=%d,手机号:%d 更改为 现分享人ID=%d,手机号:%d';
  186. $args = [
  187. self::getValueOrReturnDefault($params, 'before_parent_id'),
  188. self::getValueOrReturnDefault($params, 'before_parent_mobile'),
  189. self::getValueOrReturnDefault($params, 'after_parent_id'),
  190. self::getValueOrReturnDefault($params, 'after_parent_mobile'),
  191. ];
  192. } elseif (empty($beforeParentId)) {
  193. $str = '由平台 更改为 分享人ID=%d,手机号:%d';
  194. $args = [
  195. self::getValueOrReturnDefault($params, 'after_parent_id'),
  196. self::getValueOrReturnDefault($params, 'after_parent_mobile'),
  197. ];
  198. } else {
  199. $str = '由原来分享人ID=%d,手机号:%d 更改为 平台';
  200. $args = [
  201. self::getValueOrReturnDefault($params, 'before_parent_id'),
  202. self::getValueOrReturnDefault($params, 'before_parent_mobile'),
  203. ];
  204. }
  205. break;
  206. case UserBehaviorLogsEnum::BEHAVIOR_CANCEL:
  207. $str = '会员ID:%d,会员手机号:%d';
  208. $args = [
  209. self::getValueOrReturnDefault($params, 'user_id'),
  210. self::getValueOrReturnDefault($params, 'mobile')
  211. ];
  212. break;
  213. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_PWD:
  214. case UserBehaviorLogsEnum::BEHAVIOR_MODIFY_PAY_PWD:
  215. $str = '会员ID:%d,会员手机号:%d,更改密码';
  216. $args = [
  217. self::getValueOrReturnDefault($params, 'user_id'),
  218. self::getValueOrReturnDefault($params, 'mobile')
  219. ];
  220. break;
  221. case UserBehaviorLogsEnum::BEHAVIOR_MANUAL_UPGRADE:
  222. case UserBehaviorLogsEnum::BEHAVIOR_MANUAL_DOWNGRADE:
  223. $str = '会员ID:%d,会员手机号:%s,由旧等级:【%s】 更改为:【%s】';
  224. $userLevelArr = UserLevel::getUserLevelArr($params['mall_id']);
  225. $defaultLevelName = MallSetting::getDefaultLevelName($params['mall_id']);
  226. $args = [
  227. self::getValueOrReturnDefault($params, 'user_id'),
  228. self::getValueOrReturnDefault($params, 'mobile'),
  229. $userLevelArr[self::getValueOrReturnDefault($params, 'before_level')] ?? $defaultLevelName,
  230. $userLevelArr[self::getValueOrReturnDefault($params, 'after_level')] ?? $defaultLevelName,
  231. ];
  232. break;
  233. case UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_UPGRADE:
  234. case UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_DOWNGRADE:
  235. $userLevelArr = UserLevel::getUserLevelArr($params['mall_id']);
  236. $defaultLevelName = MallSetting::getDefaultLevelName($params['mall_id']);
  237. $str = '会员ID:%d,会员手机号:%s,由【%s】等级%s级为【%s】等级,%s级方式:%s,订单ID:%d';
  238. $upgradeOrDowngrade = [UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_UPGRADE => '升', UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_DOWNGRADE => '降'];
  239. $args = [
  240. self::getValueOrReturnDefault($params, 'user_id'),
  241. self::getValueOrReturnDefault($params, 'mobile'),
  242. $userLevelArr[self::getValueOrReturnDefault($params, 'before_level')] ?? $defaultLevelName,
  243. $upgradeOrDowngrade[$params['behavior']],
  244. $userLevelArr[self::getValueOrReturnDefault($params, 'after_level')] ?? $defaultLevelName,
  245. $upgradeOrDowngrade[$params['behavior']],
  246. UserBehaviorLogsEnum::BEHAVIOR_SYSTEM_UPGRADE == $params['behavior'] ?
  247. UserBehaviorLogsEnum::getMapValueByKey(3, $params['extra_info']['upgrade_type'] ?? '') :
  248. UserBehaviorLogsEnum::getMapValueByKey(2, $params['system_auto'] ?? '', '售后退单'),
  249. self::getValueOrReturnDefault($params, 'order_id'),
  250. ];
  251. break;
  252. default:
  253. throw new InvalidArgumentException('不存在的类型');
  254. }
  255. return sprintf($str, ...$args);
  256. }
  257. /**
  258. * @param array $data
  259. * @param string $key
  260. * @param string $defaultValue
  261. *
  262. * @return mixed
  263. */
  264. protected static function getValueOrReturnDefault(array $data, string $key, string $defaultValue = '')
  265. {
  266. return $data[$key] ?? $defaultValue;
  267. }
  268. }