Cash.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: leo
  5. * Date: 2018/10/30
  6. * Time: 下午3:19
  7. */
  8. namespace common\helpers\user;
  9. use common\models\UserWallet;
  10. use common\libs\lock\RedisLock;
  11. use common\models\FlowWallet;
  12. use common\models\Period;
  13. use yii\base\Exception;
  14. use yii\db\Expression;
  15. use common\helpers\Date;
  16. class Cash {
  17. const INCR_REDUCE = 0; // 减少
  18. const INCR_ADD = 1; // 增加
  19. const INCR_FREEZE = 2; // 冻结
  20. const INCR_UNFREEZE = 3; // 解冻
  21. const CASH_BALANCE_LOCK_KEY = 'Cash';
  22. /**
  23. * @param $userId
  24. * @return int|mixed
  25. */
  26. public static function getAvailableBalance($userId) {
  27. $oneData = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
  28. if ($oneData) {
  29. return $oneData['CASH'];
  30. } else {
  31. return 0;
  32. }
  33. }
  34. /**
  35. * @param $userId
  36. * @return bool
  37. */
  38. public static function hasCash($userId) {
  39. $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
  40. if (!$userWallet) {
  41. return false;
  42. }
  43. if (isset($userWallet['CASH']) && $userWallet['CASH'] > 0) {
  44. return true;
  45. }
  46. }
  47. /**
  48. * @param $userId
  49. * @return array
  50. */
  51. public static function getLogData($userId){
  52. $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
  53. $userName = Info::getUserNameByUserId($userId);
  54. $data = [];
  55. $data[$userId]['label'] = $userName.'余额';
  56. $data[$userId]['value'] = '奖金'.self::getAvailableBalance($userId).',现金'.$userWallet['CASH'];
  57. return $data;
  58. }
  59. /**
  60. * @param $userId
  61. * @param $type
  62. * @param $amount
  63. * @param array $params
  64. * @param bool $allowMinus
  65. * @return bool
  66. * @throws Exception
  67. * @throws \yii\db\Exception
  68. */
  69. public static function changeUserCash($userId, $type='CASH', $amount, $params = [], $allowMinus = false) {
  70. if ($amount == 0) return true;
  71. $period = Period::instance();
  72. if (!isset($params['PERIOD_NUM'])) {
  73. $periodNum = $period->getNowPeriodNum();
  74. } else {
  75. $periodNum = $params['PERIOD_NUM'];
  76. }
  77. $calcYearMonth = $period->getYearMonth($periodNum);
  78. // redis加锁(防止并发余额数值不准确出错)
  79. switch ($type) {
  80. case 'CASH':
  81. $lockKey = self::CASH_BALANCE_LOCK_KEY . $userId;
  82. break;
  83. default:
  84. throw new Exception('流水类型错误');
  85. }
  86. if (RedisLock::instance()->lock($lockKey)) {
  87. // 改变发奖
  88. $paramData = [];
  89. $oneUserBonusModel = UserWallet::findOne(['USER_ID' => $userId]);
  90. if ($oneUserBonusModel) {
  91. $paramData[$type] = new Expression($type.' + '.$amount);
  92. $oneUserBonusModel->$type += $amount;
  93. if ($oneUserBonusModel->$type < 0) {
  94. RedisLock::instance()->unlock($lockKey);
  95. throw new Exception('金额不足');
  96. }
  97. UserWallet::updateAll($paramData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
  98. } else {
  99. $paramData = [
  100. 'USER_ID'=>$userId,
  101. $type=>$amount,
  102. 'UPDATED_AT'=>Date::nowTime()
  103. ];
  104. UserWallet::insertOne($paramData);
  105. }
  106. unset($oneUserBonusModel,$paramData);
  107. $oneUserBonus = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
  108. // 记录流水
  109. $flowInsertData = [
  110. 'USER_ID' => $userId,
  111. 'CALC_ID' => $params['CALC_ID'] ?? null,
  112. 'AMOUNT' => $amount,
  113. 'TOTAL' => $oneUserBonus[$type],
  114. 'IS_INCR' => $amount > 0 ? FlowWallet::INCR_ADD : FlowWallet::INCR_REDUCE,
  115. 'REMARK' => $params['REMARK'] ?? null,
  116. 'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
  117. 'CALC_MONTH' => $calcYearMonth,
  118. 'P_MONTH' => Date::ociToDate(),
  119. 'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
  120. 'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
  121. 'SORT' => $params['SORT'] ?? 0,
  122. 'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
  123. ];
  124. if (strtolower($type) == 'cash') FlowWallet::insertOne($flowInsertData);
  125. unset($flowInsertData);
  126. RedisLock::instance()->unlock($lockKey);
  127. } else {
  128. throw new Exception('流水产生错误');
  129. }
  130. return true;
  131. }
  132. }