UserClass.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. <?php
  2. namespace bizHd\user\classes;
  3. use biz\sj\classes\MerchantAssetClass;
  4. use biz\sj\classes\MerchantClass;
  5. use biz\sj\services\MerchantService;
  6. use bizHd\message\classes\ChatClass;
  7. use bizHd\user\services\UserIntegralService;
  8. use common\components\business;
  9. use common\components\dict;
  10. use common\components\stringUtil;
  11. use common\components\util;
  12. use common\components\wxUtil;
  13. use common\services\ImageService;
  14. use common\services\xhMerchantExtendService;
  15. use common\services\xhUserCapitalService;
  16. use common\services\xhUserIntegralService;
  17. use common\services\xhUserMergeService;
  18. use Yii;
  19. use bizHd\base\classes\BaseClass;
  20. class UserClass extends BaseClass
  21. {
  22. public static $baseFile = '\bizHd\user\models\User';
  23. //用户和收入的来源
  24. public static $sourceType = [
  25. 2 => '朋友圈',
  26. 1 => '门店',
  27. 0 => '公众号',
  28. 3 => '淘宝',
  29. ];
  30. //用户来源分类
  31. public static $userSource = [
  32. 0 => ['name' => 'official', 'title' => '公众号'],
  33. 1 => ['name' => 'alipay', 'title' => '支付宝'],
  34. 2 => ['name' => 'mini', 'title' => '小程序'],
  35. 3 => ['name' => 'friend', 'title' => '朋友圈'],
  36. 4 => ['name' => 'meituan', 'title' => '美团'],
  37. 5 => ['name' => 'system', 'title' => '系统'],
  38. ];
  39. //用户来源分类ID
  40. public static $userSourceId = [
  41. 'official' => ['id' => 0, 'name' => 'official'],
  42. 'alipay' => ['id' => 1, 'name' => 'alipay'],
  43. 'mini' => ['id' => 2, 'name' => 'mini'],
  44. 'friend' => ['id' => 3, 'name' => 'friend'],
  45. 'meituan' => ['id' => 4, 'name' => 'meituan'],
  46. 'system' => ['id' => 5, 'name' => 'system'],
  47. ];
  48. //组合客户基本和资产信息
  49. public static function groupUserBaseInfo($list)
  50. {
  51. //取客户资产
  52. $ids = array_column($list, 'id');
  53. $ids = array_unique($ids);
  54. $asset = UserAssetClass::getByUserIds($ids, 'userId');
  55. $sjIdList = array_column($list, 'sjId');
  56. $sjIdList = array_filter(array_unique($sjIdList));
  57. $merchantList = MerchantService::getByIds($sjIdList, null, 'id');
  58. foreach ($list as $key => $val) {
  59. $userId = $val['id'];
  60. //访问时间
  61. $visitTime = date("m-d H:i", $val['visitTime']);
  62. if (date("m-d") == date("m-d", $val['visitTime'])) {
  63. $visitTime = '今天 ' . date("H:i", $val['visitTime']);
  64. }
  65. $list[$key]['visitTimeFormat'] = $visitTime;
  66. $list[$key]['userAsset'] = isset($asset[$userId]) ? $asset[$userId] : [];
  67. //客户发来新消息数
  68. $list[$key]['unReadNum'] = ChatClass::getUnreadNum($userId);
  69. $list[$key] = business::formatUserAvatar($list[$key]);
  70. $sjId = $val['sjId'];
  71. $list[$key]['name'] = isset($merchantList[$sjId]['name']) ? $merchantList[$sjId]['name'] : '';
  72. }
  73. return $list;
  74. }
  75. //获取客户基本和资产信息 ssh 2019.11.30
  76. public static function getUserInfo($id)
  77. {
  78. $list = self::getByIds([$id]);
  79. $data = self::groupUserBaseInfo($list);
  80. return current($data);
  81. }
  82. //根据手机号查询客户 ssh 2019.12.1
  83. public static function getByMobile($mobile, $sjId)
  84. {
  85. return self::getByCondition(['sjId' => $sjId, 'mobile' => $mobile]);
  86. }
  87. public static function replaceUser($getUserInfo)
  88. {
  89. $mobile = $getUserInfo['mobile'] ?? '';
  90. if (stringUtil::isMobile($mobile) == false) {
  91. util::fail('请填写正确手机号哦,' . $mobile);
  92. }
  93. $user = self::getByCondition(['mobile' => $mobile], true);
  94. if (!empty($user)) {
  95. return $user;
  96. }
  97. $date = date("Y-m-d H:i:s");
  98. $time = time();
  99. //替换掉微信名称不支持的图片
  100. $userName = isset($getUserInfo['userName']) ? preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $getUserInfo['userName']) : '';
  101. $userName = empty($userName) ? $mobile : $userName;
  102. $getUserInfo['name'] = $userName;
  103. $getUserInfo['sex'] = isset($getUserInfo['sex']) ? $getUserInfo['sex'] : 0;//未知
  104. $getUserInfo['identity'] = 0;
  105. $subscribe = isset($getUserInfo['subscribe']) ? $getUserInfo['subscribe'] : 0;
  106. $getUserInfo['subscribe'] = $subscribe;
  107. $getUserInfo['status'] = 0;
  108. //默认没有完整用户信息
  109. $isFull = isset($getUserInfo['headImgUrl']) && !empty($getUserInfo['headImgUrl']) ? 1 : 0;
  110. $getUserInfo['isFull'] = $isFull;
  111. $getUserInfo['createTime'] = $date;
  112. $getUserInfo['avatar'] = '';
  113. $getUserInfo['password'] = '';
  114. $getUserInfo['payPassword'] = '';
  115. $getUserInfo['mobile'] = isset($getUserInfo['mobile']) ? $getUserInfo['mobile'] : '';
  116. $getUserInfo['addTime'] = $date;
  117. $getUserInfo['visitTime'] = $time;
  118. $getUserInfo['source'] = isset($getUserInfo['source']) ? $getUserInfo['source'] : 0;
  119. $getUserInfo['hasSubscribe'] = 0;
  120. //生成用户基础信息
  121. $user = self::add($getUserInfo, true);
  122. $userId = $user->id ?? 0;
  123. $assetData = ['userId' => $userId, 'createTime' => $date];
  124. UserAssetClass::add($assetData);
  125. //保存头像
  126. if (isset($getUserInfo['headImgUrl']) && !empty($getUserInfo['headImgUrl'])) {
  127. if (empty($preUser) || (isset($preUser['avatar']) && empty($preUser['avatar']))) {
  128. $imgUrl = $getUserInfo['headImgUrl'];
  129. $currentImg = ImageService::generateAvatar(0, $imgUrl);
  130. if (!empty($currentImg)) {
  131. self::updateById($userId, ['avatar' => $currentImg]);
  132. }
  133. }
  134. }
  135. return $user;
  136. }
  137. public static function updateUser($originalUser, $getUserInfo, $sjId)
  138. {
  139. $data = [];
  140. $userId = $originalUser['id'];
  141. //替换掉微信不支持的图片
  142. $userName = isset($getUserInfo['userName']) ? preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $getUserInfo['userName']) : '';
  143. if (!empty($userName)) {
  144. $data['name'] = $userName;
  145. }
  146. if (isset($getUserInfo['openId']) && !empty($getUserInfo['openId'])) {
  147. $openId = $getUserInfo['openId'];
  148. $data['openId'] = $openId;
  149. }
  150. if (isset($getUserInfo['miniOpenId']) && !empty($getUserInfo['miniOpenId'])) {
  151. $data['miniOpenId'] = $getUserInfo['miniOpenId'];
  152. }
  153. if (isset($getUserInfo['ghsMiniOpenId']) && !empty($getUserInfo['ghsMiniOpenId'])) {
  154. $data['ghsMiniOpenId'] = $getUserInfo['ghsMiniOpenId'];
  155. }
  156. if (isset($getUserInfo['unionId']) && !empty($getUserInfo['unionId'])) {
  157. $data['unionId'] = $getUserInfo['unionId'];
  158. }
  159. if (isset($getUserInfo['sex'])) {
  160. $data['sex'] = $getUserInfo['sex'];
  161. }
  162. if (isset($getUserInfo['subscribe'])) {
  163. $data['subscribe'] = $getUserInfo['subscribe'];
  164. }
  165. if (isset($getUserInfo['subscribeTime'])) {
  166. $data['subscribeTime'] = $getUserInfo['subscribeTime'];
  167. }
  168. if (isset($getUserInfo['alipayId']) && !empty($getUserInfo['alipayId'])) {
  169. $data['alipayId'] = $getUserInfo['alipayId'];
  170. }
  171. if (isset($getUserInfo['isFull'])) {
  172. $data['isFull'] = $getUserInfo['isFull'];
  173. }
  174. if (isset($getUserInfo['headImgUrl']) && !empty($getUserInfo['headImgUrl'])) {
  175. $data['isFull'] = 1;
  176. }
  177. //更新头像
  178. if (isset($originalUser['avatar']) == false || empty($originalUser['avatar'])) {
  179. if (isset($getUserInfo['headImgUrl']) && !empty($getUserInfo['headImgUrl'])) {
  180. $imgUrl = $getUserInfo['headImgUrl'];
  181. $name = ImageService::generateAvatar(0, $imgUrl);
  182. if (!empty($name)) {
  183. $data['avatar'] = $name;
  184. }
  185. }
  186. }
  187. self::updateById($userId, $data);
  188. $user = self::getById($userId);
  189. return $user;
  190. }
  191. public static function getByMiniOpenId($miniOpenId)
  192. {
  193. return self::getByCondition(['miniOpenId' => $miniOpenId]);
  194. }
  195. public static function getByOpenId($openId)
  196. {
  197. return self::getByCondition(['openId' => $openId]);
  198. }
  199. public static function getByUnionId($unionId)
  200. {
  201. return self::getByCondition(['unionId' => $unionId]);
  202. }
  203. //合并用户
  204. public static function mergeUser($delUser, $retainUser)
  205. {
  206. $connection = Yii::$app->db;
  207. $transaction = $connection->beginTransaction();
  208. try {
  209. $delUserId = $delUser['id'];
  210. $retainUserId = $retainUser['id'];
  211. $userName = $retainUser['userName'];
  212. $sjId = $retainUser['sjId'];
  213. //合并记录
  214. $return = UserMergeClass::add([
  215. 'delUserId' => $delUserId,
  216. 'sjId' => $sjId,
  217. 'retainUserId' => $retainUserId,
  218. 'addTime' => time(),
  219. 'createTime' => date("Y-m-d H:i:s")
  220. ]);
  221. $targetId = $return['id'];
  222. $capitalType = dict::getDict('capitalType', 'xhMergeUser', 'id');
  223. $now = time();
  224. $date = date("Y-m-d H:i:s");
  225. //数据迁移
  226. $updateData = [];
  227. $updateKey = [
  228. 'mobile',
  229. 'password',
  230. 'payPassword',
  231. 'subscribe',
  232. 'hasSubscribe',
  233. 'subscribeTime',
  234. 'alipayId',
  235. 'openId',
  236. 'miniOpenId',
  237. 'unionId',
  238. ];
  239. foreach ($updateKey as $key) {
  240. if (isset($delUser[$key]) && !empty($delUser[$key])) {
  241. $updateData[$key] = $delUser[$key];
  242. }
  243. }
  244. if (!empty($updateData)) {
  245. $updateData['visitTime'] = time();
  246. self::updateById($retainUserId, $updateData);
  247. }
  248. //资产累加
  249. $addData = [];
  250. $delUserAsset = UserAssetClass::getByUserId($delUserId);
  251. $retainUserAsset = UserAssetClass::getByUserId($retainUserId);
  252. if (!empty($delUserAsset)) {
  253. //累计消费
  254. $delTotalExpend = isset($delUserAsset['totalExpend']) ? $delUserAsset['totalExpend'] : 0;
  255. if (!empty($delTotalExpend)) {
  256. $addData['totalExpend'] = $retainUserAsset['totalExpend'] + $delTotalExpend;
  257. //变化记录要增加
  258. }
  259. //累计收入
  260. $delTotalIncome = isset($delUserAsset['totalIncome']) ? $delUserAsset['totalIncome'] : 0;
  261. if (!empty($delTotalIncome)) {
  262. $addData['totalIncome'] = $retainUserAsset['totalIncome'] + $delTotalIncome;
  263. //变化记录要增加
  264. }
  265. //累计充值
  266. $delTotalRecharge = isset($delUserAsset['totalRecharge']) ? $delUserAsset['totalRecharge'] : 0;
  267. if (!empty($delTotalRecharge)) {
  268. $addData['totalRecharge'] = $retainUserAsset['totalRecharge'] + $delTotalRecharge;
  269. //变化记录要增加
  270. }
  271. //累计购买数量
  272. $delTotalBuyNum = isset($delUserAsset['totalBuyNum']) ? $delUserAsset['totalBuyNum'] : 0;
  273. if (!empty($delTotalBuyNum)) {
  274. $addData['totalBuyNum'] = $retainUserAsset['totalBuyNum'] + $delTotalBuyNum;
  275. //变化记录要增加
  276. }
  277. //余额
  278. $delBalance = isset($delUserAsset['balance']) ? $delUserAsset['balance'] : 0;
  279. if (!empty($delBalance)) {
  280. $addData['balance'] = $retainUserAsset['balance'] + $delBalance;
  281. //变化记录要增加
  282. $userCapitalData = [
  283. 'relateId' => $targetId,
  284. 'balance' => $addData['balance'],
  285. 'totalIncome' => $retainUserAsset['totalIncome'] + $delBalance,
  286. 'totalExpend' => $retainUserAsset['totalExpend'],
  287. 'amount' => $delBalance,
  288. 'io' => 1,
  289. 'payWay' => 0,
  290. 'event' => '帐号合并',
  291. 'sjId' => $sjId,
  292. 'userId' => $retainUserId,
  293. 'alipayId' => '',
  294. 'userName' => $userName,
  295. 'operateId' => 0,
  296. 'createTime' => $date,
  297. 'addTime' => $now,
  298. 'capitalType' => $capitalType,
  299. ];
  300. xhUserCapitalService::add($userCapitalData);//用户资金流水增加
  301. }
  302. //成长值
  303. $delGrowth = isset($delUserAsset['growth']) ? $delUserAsset['growth'] : 0;
  304. if (!empty($delGrowth)) {
  305. $addData['growth'] = $retainUserAsset['growth'] + $delGrowth;
  306. //注意会员等级要进行重新计算!!!!!还有积分变化记录要增加
  307. $growthData = [
  308. 'userId' => $retainUserId,
  309. 'userName' => $userName,
  310. 'sjId' => $sjId,
  311. 'relateId' => $targetId,
  312. 'integral' => $addData['growth'],
  313. 'num' => $delGrowth,
  314. 'io' => 1,
  315. 'payWay' => 0,
  316. 'alipayId' => '',
  317. 'event' => '帐号合并',
  318. 'operatorId' => 0,
  319. 'createTime' => $date,
  320. 'capitalType' => $capitalType,
  321. 'addTime' => $now,
  322. ];
  323. UserGrowthClass::add($growthData);
  324. //成长值增加升级
  325. $preLevel = $retainUserAsset['member'];
  326. $preGrowth = $retainUserAsset['growth'];
  327. $merchantExtend = xhMerchantExtendService::getBySjId($sjId);
  328. UserIntegralService::increaseToUpgrade($preGrowth, $addData['growth'], $preLevel, $retainUserId, $sjId, $merchantExtend);
  329. }
  330. if (!empty($addData)) {
  331. UserAssetClass::updateByUserId($retainUserId, $addData);
  332. }
  333. }
  334. //删除用户
  335. $clearData = ['openId' => '', 'miniOpenId' => '', 'unionId' => '', 'alipayId' => '', 'sjId' => 0, 'mobile' => ''];
  336. self::updateById($delUserId, $clearData);
  337. UserAssetClass::updateByUserId($delUserId, ['sjId' => 0]);
  338. //如果有支付宝信息则清除支付宝用户
  339. UserAlipayClass::updateByUserId($delUserId, ['alipayId' => '', 'alipayAccount' => '', 'sjId' => 0]);
  340. //合并帐号减少客户数 ssh 2020.5.13
  341. MerchantAssetClass::mergeToReduceUser($sjId);
  342. $transaction->commit();
  343. return self::getById($retainUserId);
  344. } catch (Exception $e) {
  345. $transaction->rollBack();
  346. Yii::info("合并userid $delUserId $retainUserId 时事务回滚,原因:" . $e->getMessage());
  347. return [];
  348. }
  349. }
  350. //找出相同unionId的用户
  351. public static function getSameUnionId($unionId)
  352. {
  353. return self::getAllByCondition(['unionId' => $unionId], 'addTime desc', '*', 'id');
  354. }
  355. public static function valid($info, $sjId)
  356. {
  357. if (empty($info)) {
  358. util::fail('找不到客户');
  359. }
  360. if ($info['sjId'] != $sjId) {
  361. util::fail('这个客户您无法操作');
  362. }
  363. }
  364. //根据消费次数和有没领优惠券来判断是不是新人
  365. public static function newUser($userInfo)
  366. {
  367. $asset = isset($userInfo['userAsset']) ? $userInfo['userAsset'] : [];
  368. $totalBuyNum = isset($asset['totalBuyNum']) ? $asset['totalBuyNum'] : 0;
  369. if ($totalBuyNum > 0) {
  370. return false;
  371. }
  372. $getCouponNum = isset($asset['getCouponNum']) ? $asset['getCouponNum'] : 0;
  373. if ($getCouponNum) {
  374. return false;
  375. }
  376. return true;
  377. }
  378. public static function getUserByIds($ids)
  379. {
  380. $info = self::getByIds($ids, null, 'id');
  381. if (empty($info)) {
  382. return [];
  383. }
  384. $data = self::groupUserBaseInfo($info);
  385. return $data;
  386. }
  387. //将微信和小程序获取的用户信息转成可以保存的用户信息
  388. public static function switchUserInfo($info, $source)
  389. {
  390. $openId = '';
  391. if (isset($info['openid']) && !empty($info['openid'])) {
  392. $openId = $info['openid'];
  393. unset($info['openid']);
  394. }
  395. if (isset($info['openId']) && !empty($info['openId'])) {
  396. $openId = $info['openId'];
  397. unset($info['openId']);
  398. }
  399. if (!empty($openId)) {
  400. $userSource = self::$userSourceId;
  401. switch ($source) {
  402. case $userSource['mini']['name']:
  403. $info['miniOpenId'] = $openId;
  404. break;
  405. case $userSource['official']['name']:
  406. $info['openId'] = $openId;
  407. break;
  408. default:
  409. }
  410. }
  411. if (isset($info['miniOpenId'])) {
  412. $info['miniOpenId'] = $info['miniOpenId'];
  413. }
  414. if (isset($info['nickName'])) {
  415. $info['userName'] = $info['nickName'];
  416. $info['nickName'] = $info['nickName'];
  417. }
  418. if (isset($info['unionid'])) {
  419. $info['unionId'] = $info['unionid'];
  420. }
  421. if (isset($info['unionId'])) {
  422. $info['unionId'] = $info['unionId'];
  423. }
  424. if (isset($info['headimgurl'])) {
  425. $info['headImgUrl'] = $info['headimgurl'];
  426. }
  427. if (isset($info['avatarUrl'])) {
  428. $info['headImgUrl'] = $info['avatarUrl'];
  429. }
  430. if (isset($info['subscribe_time'])) {
  431. $info['subscribeTime'] = $info['subscribe_time'];
  432. }
  433. if (isset($info['subscribe'])) {
  434. $info['subscribe'] = $info['subscribe'];
  435. }
  436. return $info;
  437. }
  438. }