UserMoneyServices.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\services\user;
  13. use app\model\user\UserMoney;
  14. use qiniu\basic\BaseServices;
  15. use qiniu\services\CacheService;
  16. use qiniu\exceptions\AdminException;
  17. use think\db\exception\DbException;
  18. use think\exception\ValidateException;
  19. /**
  20. * 用户余额
  21. * Class UserMoneyServices
  22. * @package app\services\user
  23. * @mixin UserMoney
  24. */
  25. class UserMoneyServices extends BaseServices
  26. {
  27. /**
  28. * 用户记录模板
  29. * @var array[]
  30. */
  31. protected $incomeData = [
  32. 'system_add' => [
  33. 'title' => '系统增加余额',
  34. 'type' => 'system_add',
  35. 'mark' => '系统增加{%number%}余额{%mark%}',
  36. 'status' => 1,
  37. 'pm' => 1
  38. ],
  39. 'system_sub' => [
  40. 'title' => '系统减少余额',
  41. 'type' => 'system_sub',
  42. 'mark' => '系统扣除了{%number%}余额{%mark%}',
  43. 'status' => 1,
  44. 'pm' => 0
  45. ],
  46. 'user_recharge' => [
  47. 'title' => '用户充值余额',
  48. 'type' => 'recharge',
  49. 'mark' => '成功充值余额{%number%}元',
  50. 'status' => 1,
  51. 'pm' => 1
  52. ],
  53. 'trade_in' => [
  54. 'title' => '余额转入',
  55. 'type' => 'trade_in',
  56. 'mark' => '{%mark%}{%number%}元',
  57. 'status' => 1,
  58. 'pm' => 1
  59. ],
  60. 'trade_out' => [
  61. 'title' => '余额转出',
  62. 'type' => 'trade_out',
  63. 'mark' => '{%mark%}{%number%}元',
  64. 'status' => 1,
  65. 'pm' => 0
  66. ],
  67. ];
  68. /**
  69. * UserMoneyServices constructor.
  70. * @param UserMoney $model
  71. */
  72. public function __construct(UserMoney $model)
  73. {
  74. $this->model = $model;
  75. }
  76. /**
  77. * 获取资金列表
  78. * @param array $where
  79. * @param string $field
  80. * @param int $limit
  81. * @return array
  82. * @throws DbException
  83. */
  84. public function getMoneyList(array $where, string $field = '*', int $limit = 0)
  85. {
  86. $where_data = [];
  87. if (isset($where['uid']) && $where['uid'] != '') {
  88. $where_data['uid'] = $where['uid'];
  89. }
  90. if ($where['start_time'] != '' && $where['end_time'] != '') {
  91. $where_data['time'] = str_replace('-', '/', $where['start_time']) . ' - ' . str_replace('-', '/', $where['end_time']);
  92. }
  93. if (isset($where['type']) && $where['type'] != '') {
  94. $where_data['type'] = $where['type'];
  95. }
  96. if (isset($where['nickname']) && $where['nickname'] != '') {
  97. $where_data['like'] = $where['nickname'];
  98. }
  99. if (isset($where['pm']) && $where['pm'] != '') {
  100. $where_data['pm'] = $where['pm'];
  101. }
  102. if ($limit) {
  103. [$page] = $this->getPageValue();
  104. } else {
  105. [$page, $limit] = $this->getPageValue();
  106. }
  107. $data = $this->getList($where_data, $field, $page, $limit, [
  108. 'user' => function ($query) {
  109. $query->field('uid,nickname');
  110. }]);
  111. foreach ($data as &$item) {
  112. $item['nickname'] = $item['user']['nickname'] ?? '';
  113. $item['add_time'] = $item['add_time'] ? date('Y-m-d H:i:s', $item['add_time']) : '';
  114. unset($item['user']);
  115. }
  116. $count = $this->getCount($where_data);
  117. return compact('data', 'count');
  118. }
  119. /**
  120. * 写入用户记录
  121. * @param string $type 写入类型
  122. * @param int $uid
  123. * @param int|string|array $number
  124. * @param int|string $link_id
  125. * @return bool
  126. * @throws DbException
  127. * @throws \think\db\exception\DataNotFoundException
  128. * @throws \think\db\exception\ModelNotFoundException
  129. */
  130. public function income(string $type, int $uid, $number, $link_id = 0)
  131. {
  132. $data = $this->incomeData[$type] ?? null;
  133. if (!$data) {
  134. return true;
  135. }
  136. $data['uid'] = $uid;
  137. $data['link_id'] = $link_id;
  138. if (is_array($number)) {
  139. $key = array_keys($number);
  140. $key = array_map(function ($item) {
  141. return '{%' . $item . '%}';
  142. }, $key);
  143. $value = array_values($number);
  144. $data['number'] = $number['number'] ?? 0;
  145. $data['mark'] = str_replace($key, $value, $data['mark']);
  146. } else {
  147. $data['number'] = $number;
  148. $data['mark'] = str_replace(['{%number%}'], $number, $data['mark']);
  149. }
  150. $data['add_time'] = time();
  151. /** @var UserServices $userService */
  152. $userService = app()->make(UserServices::class);
  153. if ((float)$data['number'] > 0) {
  154. if ($data['status'] == 1) {
  155. $user = $userService->getUserInfo($uid);
  156. if ($data['pm'] == 1) {
  157. $data['balance'] = bcadd($user['now_money'], $data['number'], 2);
  158. $userService->bcInc($uid, 'now_money', $data['number'], 'uid');
  159. } else {
  160. if ($data['number'] > $user['now_money']) {
  161. throw new ValidateException('用户余额不足');
  162. }
  163. $data['balance'] = bcsub($user['now_money'], $data['number'], 2);
  164. $userService->bcDec($uid, 'now_money', $data['number'], 'uid');
  165. }
  166. }
  167. return $this->save($data);
  168. }
  169. return true;
  170. }
  171. /**
  172. * 资金类型
  173. * @return bool|mixed|null
  174. */
  175. public function bill_type()
  176. {
  177. $getMoneyType = function () {
  178. $array = $this->incomeData;
  179. $list = [];
  180. foreach ($array as $v) {
  181. $list[] = ['type' => $v['type'], 'title' => $v['title'], 'pm' => $v['pm']];
  182. }
  183. return compact('list');
  184. };
  185. return CacheService::get('user_money_type_list', $getMoneyType, 600);
  186. }
  187. public function trade(int $uid, int $to_uid, $num)
  188. {
  189. /** @var UserServices $userService */
  190. $userService = app()->make(UserServices::class);
  191. $user = $userService->getUserInfo($uid);
  192. $to_user = $userService->getUserInfo($to_uid);
  193. if (!$user || !$to_user) {
  194. throw new ValidateException('数据不存在');
  195. }
  196. if ($to_uid == $uid) throw new ValidateException('不能自己转给自己');
  197. $extractPrice = $user['now_money'];
  198. if ($num > $extractPrice) {
  199. throw new ValidateException('转账余额不足' . $num);
  200. }
  201. if ($num <= 0) {
  202. throw new ValidateException('转账余额大于0');
  203. }
  204. return $this->transaction(function () use ($num, $user, $to_user, $userService) {
  205. //保存佣金记录
  206. $this->income('trade_out', $user['uid'], ['mark' => '转账给' . $to_user['nickname'] . '(' . $to_user['uid'] . ')', 'number' => $num], $to_user['uid']);
  207. $this->income('trade_in', $to_user['uid'], ['mark' => '转账自' . $user['nickname'] . '(' . $user['uid'] . ')', 'number' => $num], $user['uid']);
  208. return true;
  209. });
  210. }
  211. }