CreditsLogService.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. <?php
  2. namespace services\member;
  3. use Yii;
  4. use yii\web\NotFoundHttpException;
  5. use common\forms\CreditsLogForm;
  6. use common\components\Service;
  7. use common\models\member\CreditsLog;
  8. use common\enums\CreditsLogTypeEnum;
  9. use common\models\member\Account;
  10. use common\enums\StatusEnum;
  11. use common\enums\MemberTypeEnum;
  12. use common\helpers\EchantsHelper;
  13. /**
  14. * Class CreditsLogService
  15. * @package services\member
  16. * @author jianyan74 <751393839@qq.com>
  17. */
  18. class CreditsLogService extends Service
  19. {
  20. /**
  21. * 增加积分
  22. *
  23. * @param CreditsLogForm $creditsLogForm
  24. * @return bool|CreditsLog
  25. * @throws NotFoundHttpException
  26. */
  27. public function incrInt(CreditsLogForm $creditsLogForm)
  28. {
  29. $creditsLogForm->num = abs($creditsLogForm->num);
  30. $creditsLogForm->type = CreditsLogTypeEnum::USER_INTEGRAL;
  31. return $this->userInt($creditsLogForm);
  32. }
  33. /**
  34. * 减少积分
  35. *
  36. * @param CreditsLogForm $creditsLogForm
  37. * @return bool|CreditsLog
  38. * @throws NotFoundHttpException
  39. */
  40. public function decrInt(CreditsLogForm $creditsLogForm)
  41. {
  42. $creditsLogForm->num = -abs($creditsLogForm->num);
  43. $creditsLogForm->type = CreditsLogTypeEnum::USER_INTEGRAL;
  44. return $this->userInt($creditsLogForm);
  45. }
  46. /**
  47. * 增加余额
  48. *
  49. * @param CreditsLogForm $creditsLogForm
  50. * @return bool|CreditsLog
  51. * @throws NotFoundHttpException
  52. */
  53. public function incrMoney(CreditsLogForm $creditsLogForm)
  54. {
  55. $creditsLogForm->num = abs($creditsLogForm->num);
  56. $creditsLogForm->type = CreditsLogTypeEnum::USER_MONEY;
  57. return $this->userMoney($creditsLogForm);
  58. }
  59. /**
  60. * 减少余额
  61. *
  62. * @param CreditsLogForm $creditsLogForm
  63. * @return bool|CreditsLog
  64. * @throws NotFoundHttpException
  65. */
  66. public function decrMoney(CreditsLogForm $creditsLogForm)
  67. {
  68. $creditsLogForm->num = -abs($creditsLogForm->num);
  69. $creditsLogForm->type = CreditsLogTypeEnum::USER_MONEY;
  70. return $this->userMoney($creditsLogForm);
  71. }
  72. /**
  73. * 消费
  74. *
  75. * 一般用于微信/支付宝/银联消费记录使用
  76. *
  77. * @param CreditsLogForm $creditsLogForm
  78. * @return CreditsLog
  79. * @throws NotFoundHttpException
  80. */
  81. public function consumeMoney(CreditsLogForm $creditsLogForm)
  82. {
  83. $creditsLogForm->num = abs($creditsLogForm->num);
  84. $creditsLogForm->type = CreditsLogTypeEnum::CONSUME_MONEY;
  85. /** @var Account $account */
  86. if (empty($account = $creditsLogForm->account)) {
  87. $account = $creditsLogForm->member->account ?? '';
  88. }
  89. if (empty($account)) {
  90. return $this->create($creditsLogForm, 0, 0);
  91. }
  92. // 直接记录日志不修改
  93. if (empty($creditsLogForm->member) || $creditsLogForm->num == 0) {
  94. return $this->create($creditsLogForm, $account->consume_money, $account->consume_money);
  95. }
  96. // 消费
  97. if (!Account::updateAllCounters(['consume_money' => $creditsLogForm->num], ['id' => $account->id])) {
  98. throw new NotFoundHttpException('消费失败');
  99. }
  100. // 变动级别
  101. $creditsLogForm->update_level && $creditsLogForm->updateLevel(
  102. $account->consume_money + $creditsLogForm->num,
  103. $account->accumulate_integral,
  104. $account->accumulate_growth
  105. );
  106. // 记录日志
  107. return $this->create($creditsLogForm, $account->consume_money, $account->consume_money + $creditsLogForm->num);
  108. }
  109. /**
  110. * 提现完成
  111. *
  112. * @param CreditsLogForm $creditsLogForm
  113. * @throws NotFoundHttpException
  114. */
  115. public function withdrawAccomplish(CreditsLogForm $creditsLogForm)
  116. {
  117. $creditsLogForm->num = abs($creditsLogForm->num);
  118. /** @var Account $account */
  119. if (empty($account = $creditsLogForm->account)) {
  120. $account = $creditsLogForm->member->account ?? '';
  121. }
  122. // 增加提现金额
  123. if (!$account->updateAllCounters([
  124. 'accumulate_drawn_money' => $creditsLogForm->num,
  125. ], ['id' => $account->id])) {
  126. throw new NotFoundHttpException('提现失败');
  127. }
  128. }
  129. /**
  130. * 增加成长值
  131. *
  132. * @param CreditsLogForm $creditsLogForm
  133. * @return bool|CreditsLog
  134. * @throws NotFoundHttpException
  135. */
  136. public function incrGrowth(CreditsLogForm $creditsLogForm)
  137. {
  138. $creditsLogForm->num = abs($creditsLogForm->num);
  139. $creditsLogForm->type = CreditsLogTypeEnum::USER_GROWTH;
  140. return $this->userGrowth($creditsLogForm);
  141. }
  142. /**
  143. * 减少成长值
  144. *
  145. * @param CreditsLogForm $creditsLogForm
  146. * @return bool|CreditsLog
  147. * @throws NotFoundHttpException
  148. */
  149. public function decrGrowth(CreditsLogForm $creditsLogForm)
  150. {
  151. $creditsLogForm->num = -abs($creditsLogForm->num);
  152. $creditsLogForm->type = CreditsLogTypeEnum::USER_GROWTH;
  153. return $this->userGrowth($creditsLogForm);
  154. }
  155. /**
  156. * 增加节省
  157. *
  158. * @param CreditsLogForm $creditsLogForm
  159. * @return bool|CreditsLog
  160. * @throws NotFoundHttpException
  161. */
  162. public function incrEconomizeMoney(CreditsLogForm $creditsLogForm)
  163. {
  164. $creditsLogForm->num = abs($creditsLogForm->num);
  165. $creditsLogForm->type = CreditsLogTypeEnum::ECONOMIZE;
  166. return $this->userEconomizeMoney($creditsLogForm);
  167. }
  168. /**
  169. * 减少节省
  170. *
  171. * @param CreditsLogForm $creditsLogForm
  172. * @return bool|CreditsLog
  173. * @throws NotFoundHttpException
  174. */
  175. public function decrEconomizeMoney(CreditsLogForm $creditsLogForm)
  176. {
  177. $creditsLogForm->num = -abs($creditsLogForm->num);
  178. $creditsLogForm->type = CreditsLogTypeEnum::ECONOMIZE;
  179. return $this->userEconomizeMoney($creditsLogForm);
  180. }
  181. /**
  182. * 积分变动
  183. *
  184. * @param CreditsLogForm $creditsLogForm
  185. * @return CreditsLog
  186. * @throws NotFoundHttpException
  187. */
  188. protected function userInt(CreditsLogForm $creditsLogForm)
  189. {
  190. /** @var Account $account */
  191. if (empty($account = $creditsLogForm->account)) {
  192. $account = $creditsLogForm->member->account;
  193. }
  194. // 直接记录日志不修改
  195. if ($creditsLogForm->num == 0) {
  196. return $this->create($creditsLogForm, $account->user_integral, $account->user_integral);
  197. }
  198. if ($creditsLogForm->num > 0) {
  199. // 消费
  200. $counters = [
  201. 'user_integral' => $creditsLogForm->num,
  202. 'accumulate_integral' => $creditsLogForm->num,
  203. ];
  204. // 增加积分赠送
  205. $creditsLogForm->is_give && $counters['give_integral'] = $creditsLogForm->num;
  206. // 减少消费数量
  207. $creditsLogForm->is_consume && $counters['consume_integral'] = -$creditsLogForm->num;
  208. // 增加
  209. $status = Account::updateAllCounters($counters, ['id' => $account->id]);
  210. // 变动级别
  211. $creditsLogForm->update_level && $creditsLogForm->updateLevel(
  212. $account->consume_money,
  213. $account->accumulate_integral + $creditsLogForm->num,
  214. $account->accumulate_growth
  215. );
  216. } else {
  217. // 消费
  218. $counters = ['user_integral' => $creditsLogForm->num];
  219. // 减少积分赠送
  220. $creditsLogForm->is_give && $counters['give_integral'] = $creditsLogForm->num;
  221. // 增加消费数量
  222. $creditsLogForm->is_consume && $counters['consume_integral'] = abs($creditsLogForm->num);
  223. $status = Account::updateAllCounters($counters,
  224. [
  225. 'and',
  226. ['id' => $account->id],
  227. ['>=', 'user_integral', abs($creditsLogForm->num)],
  228. ]);
  229. }
  230. if ($status == false && $creditsLogForm->num < 0) {
  231. throw new NotFoundHttpException('积分不足');
  232. }
  233. if ($status == false && $creditsLogForm->num > 0) {
  234. throw new NotFoundHttpException('增加积分失败');
  235. }
  236. // 记录日志
  237. return $this->create($creditsLogForm, $account->user_integral, $account->user_integral + $creditsLogForm->num);
  238. }
  239. /**
  240. * 余额变动
  241. *
  242. * @param CreditsLogForm $creditsLogForm
  243. * @return CreditsLog
  244. * @throws NotFoundHttpException
  245. */
  246. protected function userMoney(CreditsLogForm $creditsLogForm)
  247. {
  248. /** @var Account $account */
  249. if (empty($account = $creditsLogForm->account)) {
  250. $account = $creditsLogForm->member->account;
  251. }
  252. // 直接记录日志不修改
  253. if ($creditsLogForm->num == 0) {
  254. return $this->create($creditsLogForm, $account->user_money, $account->user_money);
  255. }
  256. if ($creditsLogForm->num > 0) {
  257. $counters = ['user_money' => $creditsLogForm->num];
  258. // 增加累计
  259. $creditsLogForm->is_accumulate && $counters['accumulate_money'] = $creditsLogForm->num;
  260. // 增加金额赠送
  261. $creditsLogForm->is_give && $counters['give_money'] = $creditsLogForm->num;
  262. // 去掉消费
  263. $creditsLogForm->is_consume && $counters['consume_money'] = -abs($creditsLogForm->num);
  264. // 增加
  265. $status = Account::updateAllCounters($counters, ['id' => $account->id]);
  266. } else {
  267. // 消费
  268. $counters = ['user_money' => $creditsLogForm->num];
  269. // 减少积分赠送
  270. $creditsLogForm->is_give && $counters['give_money'] = $creditsLogForm->num;
  271. // 增加消费数量
  272. $creditsLogForm->is_consume && $counters['consume_money'] = abs($creditsLogForm->num);
  273. $status = Account::updateAllCounters(
  274. $counters,
  275. [
  276. 'and',
  277. ['id' => $account->id],
  278. ['>=', 'user_money', abs($creditsLogForm->num)],
  279. ]);
  280. // 变动级别
  281. $creditsLogForm->update_level && $creditsLogForm->updateLevel(
  282. $account->consume_money + abs($creditsLogForm->num),
  283. $account->accumulate_integral,
  284. $account->accumulate_growth
  285. );
  286. }
  287. if ($status == false && $creditsLogForm->num < 0) {
  288. throw new NotFoundHttpException('余额不足');
  289. }
  290. if ($status == false && $creditsLogForm->num > 0) {
  291. throw new NotFoundHttpException('增加余额失败');
  292. }
  293. // 记录日志
  294. return $this->create($creditsLogForm, $account->user_money, $account->user_money + $creditsLogForm->num);
  295. }
  296. /**
  297. * 成长值变动
  298. *
  299. * @param CreditsLogForm $creditsLogForm
  300. * @return CreditsLog
  301. * @throws NotFoundHttpException
  302. */
  303. protected function userGrowth(CreditsLogForm $creditsLogForm)
  304. {
  305. /** @var Account $account */
  306. if (empty($account = $creditsLogForm->account)) {
  307. $account = $creditsLogForm->member->account;
  308. }
  309. // 直接记录日志不修改
  310. if ($creditsLogForm->num == 0) {
  311. return $this->create($creditsLogForm, $account->user_growth, $account->user_growth);
  312. }
  313. if ($creditsLogForm->num > 0) {
  314. // 增加
  315. $status = Account::updateAllCounters([
  316. 'user_growth' => $creditsLogForm->num,
  317. 'accumulate_growth' => $creditsLogForm->num,
  318. ], ['id' => $account->id]);
  319. // 变动级别
  320. $creditsLogForm->update_level && $creditsLogForm->updateLevel(
  321. $account->consume_growth,
  322. $account->accumulate_integral,
  323. $account->accumulate_growth + $creditsLogForm->num
  324. );
  325. } else {
  326. // 消费
  327. $status = Account::updateAllCounters([
  328. 'user_growth' => $creditsLogForm->num,
  329. 'consume_growth' => abs($creditsLogForm->num)
  330. ],
  331. [
  332. 'and',
  333. ['id' => $account->id],
  334. ['>=', 'user_growth', abs($creditsLogForm->num)],
  335. ]);
  336. }
  337. if ($status == false && $creditsLogForm->num < 0) {
  338. throw new NotFoundHttpException('成长值不足');
  339. }
  340. if ($status == false && $creditsLogForm->num > 0) {
  341. throw new NotFoundHttpException('增加成长值失败');
  342. }
  343. // 记录日志
  344. return $this->create($creditsLogForm, $account->user_growth, $account->user_growth + $creditsLogForm->num);
  345. }
  346. /**
  347. * 节省变动
  348. *
  349. * @param CreditsLogForm $creditsLogForm
  350. * @return CreditsLog
  351. * @throws NotFoundHttpException
  352. */
  353. protected function userEconomizeMoney(CreditsLogForm $creditsLogForm)
  354. {
  355. /** @var Account $account */
  356. if (empty($account = $creditsLogForm->account)) {
  357. $account = $creditsLogForm->member->account;
  358. }
  359. // 直接记录日志不修改
  360. if ($creditsLogForm->num == 0) {
  361. return $this->create($creditsLogForm, $account->user_growth, $account->user_growth);
  362. }
  363. if ($creditsLogForm->num > 0) {
  364. // 增加
  365. $status = Account::updateAllCounters(['economize_money' => $creditsLogForm->num], ['id' => $account->id]);
  366. } else {
  367. // 消费
  368. $status = Account::updateAllCounters(['economize_money' => $creditsLogForm->num],
  369. [
  370. 'and',
  371. ['id' => $account->id],
  372. ['>=', 'economize_money', abs($creditsLogForm->num)],
  373. ]);
  374. }
  375. if ($status == false && $creditsLogForm->num < 0) {
  376. throw new NotFoundHttpException('节省不足');
  377. }
  378. if ($status == false && $creditsLogForm->num > 0) {
  379. throw new NotFoundHttpException('增加节省失败');
  380. }
  381. // 记录日志
  382. return $this->create($creditsLogForm, $account->economize_money,
  383. $account->economize_money + $creditsLogForm->num);
  384. }
  385. /**
  386. * @param CreditsLogForm $creditsLogForm
  387. * @param $oldNum
  388. * @param $newNum
  389. * @return CreditsLog
  390. * @throws NotFoundHttpException
  391. */
  392. protected function create(CreditsLogForm $creditsLogForm, $oldNum, $newNum)
  393. {
  394. $model = new CreditsLog();
  395. $model = $model->loadDefaultValues();
  396. $model->ip = Yii::$app->services->base->getUserIp();
  397. $model->pay_type = $creditsLogForm->pay_type;
  398. $model->old_num = $oldNum;
  399. $model->new_num = $newNum;
  400. $model->num = $creditsLogForm->num;
  401. $model->type = $creditsLogForm->type;
  402. $model->group = $creditsLogForm->group;
  403. $model->remark = $creditsLogForm->remark;
  404. $model->map_id = $creditsLogForm->map_id;
  405. if ($creditsLogForm->account) {
  406. $model->merchant_id = $creditsLogForm->account->merchant_id ?? 0;
  407. $model->member_id = $creditsLogForm->account->member_id ?? 0;
  408. $model->member_type = $creditsLogForm->account->member_type ?? 0;
  409. } else {
  410. $model->merchant_id = $creditsLogForm->member->merchant_id ?? 0;
  411. $model->member_id = $creditsLogForm->member->id ?? 0;
  412. }
  413. if (!$model->save()) {
  414. throw new NotFoundHttpException($this->getError($model));
  415. }
  416. return $model;
  417. }
  418. /**
  419. * 获取区间充值
  420. *
  421. * @return array|\yii\db\ActiveRecord|null
  422. */
  423. public function getRechargeStat($type, $title = '充值统计')
  424. {
  425. $fields = [
  426. 'price' => $title,
  427. ];
  428. // 获取时间和格式化
  429. list($time, $format) = EchantsHelper::getFormatTime($type);
  430. // 获取数据
  431. return EchantsHelper::lineOrBarInTime(function ($start_time, $end_time, $formatting) {
  432. $data = CreditsLog::find()
  433. ->select(['sum(num) as price', "from_unixtime(created_at, '$formatting') as time"])
  434. ->where(['type' => CreditsLogTypeEnum::USER_MONEY])
  435. ->andWhere(['member_type' => MemberTypeEnum::MEMBER])
  436. ->andWhere(['in', 'group', ['manager', 'recharge']])
  437. ->andWhere(['>', 'status', StatusEnum::DISABLED])
  438. ->andWhere(['between', 'created_at', $start_time, $end_time])
  439. ->andFilterWhere(['merchant_id' => $this->getMerchantId()])
  440. ->groupBy(['time'])
  441. ->asArray()
  442. ->all();
  443. foreach ($data as &$datum) {
  444. $datum['price'] = abs($datum['price']);
  445. }
  446. return $data;
  447. }, $fields, $time, $format);
  448. }
  449. /**
  450. * 获取区间消费统计
  451. *
  452. * @return array|\yii\db\ActiveRecord|null
  453. */
  454. public function getBetweenCountStat($type, $credit_type = CreditsLogTypeEnum::CONSUME_MONEY, $title = '第三方消费统计')
  455. {
  456. $fields = [
  457. 'price' => $title,
  458. ];
  459. // 获取时间和格式化
  460. list($time, $format) = EchantsHelper::getFormatTime($type);
  461. // 获取数据
  462. return EchantsHelper::lineOrBarInTime(function ($start_time, $end_time, $formatting) use ($credit_type) {
  463. $data = CreditsLog::find()
  464. ->select(['sum(num) as price', "from_unixtime(created_at, '$formatting') as time"])
  465. ->where(['type' => $credit_type])
  466. ->andWhere(['member_type' => MemberTypeEnum::MEMBER])
  467. ->andWhere(['>', 'status', StatusEnum::DISABLED])
  468. ->andWhere(['between', 'created_at', $start_time, $end_time])
  469. ->andFilterWhere(['merchant_id' => $this->getMerchantId()])
  470. ->groupBy(['time'])
  471. ->asArray()
  472. ->all();
  473. foreach ($data as &$datum) {
  474. $datum['price'] = abs($datum['price']);
  475. }
  476. return $data;
  477. }, $fields, $time, $format);
  478. }
  479. }
粤ICP备19079148号