AgentBehaviorLogsService.php 12 KB

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