| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- <?php
- /**
- * Created by PhpStorm.
- * User: leo
- * Date: 2018/10/30
- * Time: 下午3:19
- */
- namespace common\helpers\user;
- use common\helpers\Date;
- use common\helpers\Form;
- use common\libs\lock\RedisLock;
- use common\models\FlowWallet;
- use common\models\Period;
- use common\models\UserWallet;
- use Yii;
- use yii\base\Exception;
- use yii\db\Expression;
- class Cash {
- const INCR_REDUCE = 0; // 减少
- const INCR_ADD = 1; // 增加
- const INCR_FREEZE = 2; // 冻结
- const INCR_UNFREEZE = 3; // 解冻
- const CASH_BALANCE_LOCK_KEY = 'Cash';
- /**
- * 获取当前可用余额
- * @param $userId
- * @return int|mixed
- */
- public static function getAvailableBalance($userId) {
- $oneData = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
- if ($oneData) {
- return $oneData['CASH'];
- } else {
- return 0;
- }
- }
- /**
- * 改变会员的现金余额
- * @param $userId
- * @param $type
- * @param $amount
- * @param array $params
- * @param bool $allowMinus
- * @return bool
- * @throws Exception
- * @throws \yii\db\Exception
- */
- public static function changeUserCash($userId, $type='CASH', $amount, $params = [], $allowMinus = false) {
- if ($amount == 0) return true;
- $period = Period::instance();
- if (!isset($params['PERIOD_NUM'])) {
- $periodNum = $period->getNowPeriodNum();
- } else {
- $periodNum = $params['PERIOD_NUM'];
- }
- $calcYearMonth = $period->getYearMonth($periodNum);
- // redis加锁(防止并发余额数值不准确出错)
- switch ($type) {
- case 'CASH':
- $lockKey = self::CASH_BALANCE_LOCK_KEY . $userId;
- break;
- default:
- throw new Exception(Yii::t('app', 'cashDoesNotAdequate'));
- }
- if (RedisLock::instance()->lock($lockKey)) {
- // 改变发奖
- $paramData = [];
- $oneUserBonusModel = UserWallet::findOne(['USER_ID' => $userId]);
- if ($oneUserBonusModel) {
- $paramData[$type] = new Expression($type.' + '.$amount);
- $oneUserBonusModel->$type += $amount;
- if ($oneUserBonusModel->$type < 0) {
- RedisLock::instance()->unlock($lockKey);
- throw new Exception(Yii::t('app', 'cashDoesNotAdequate'));
- }
- UserWallet::updateAll($paramData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
- } else {
- $paramData = [
- 'USER_ID'=>$userId,
- $type=>$amount,
- 'UPDATED_AT'=>Date::nowTime()
- ];
- UserWallet::insertOne($paramData);
- // $oneUserBonusModel = new UserWallet();
- // $oneUserBonusModel->USER_ID = $userId;
- // $oneUserBonusModel->$type = $amount;
- // $oneUserBonusModel->UPDATED_AT = Date::nowTime();
- // if (!$oneUserBonusModel->save()) {
- // throw new \yii\db\Exception(Form::formatErrorsForApi($oneUserBonusModel->getErrors()));
- // }
- }
- unset($oneUserBonusModel,$paramData);
- // 获取发放完成的奖金信息
- $oneUserBonus = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
- // 记录流水
- $flowInsertData = [
- 'USER_ID' => $userId,
- 'CALC_ID' => $params['CALC_ID'] ?? null,
- 'AMOUNT' => $amount,
- 'TOTAL' => $oneUserBonus[$type],
- 'IS_INCR' => $amount > 0 ? FlowWallet::INCR_ADD : FlowWallet::INCR_REDUCE,
- 'REMARK' => $params['REMARK'] ?? null,
- 'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
- 'CALC_MONTH' => $calcYearMonth,
- 'P_MONTH' => Date::ociToDate(),
- 'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
- 'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
- 'SORT' => $params['SORT'] ?? 0,
- 'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
- 'ORDER_SN' => $params['ORDER_SN'] ?? '',
- ];
- if (strtolower($type) == 'cash') FlowWallet::insertOne($flowInsertData);
- unset($flowInsertData);
- RedisLock::instance()->unlock($lockKey);
- } else {
- throw new Exception(Yii::t('app', 'flowCreateError'));
- }
- return true;
- }
- /**
- * 清空会员现金所有流水
- * @param $userId
- * @param array $params
- * @throws Exception
- * @throws \yii\db\Exception
- */
- public static function clearAllCash($userId, $params = []) {
- // 先查找会员的全部余额
- $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
- // 如果没有会员余额数据,新建余额数据
- if (!$userWallet) {
- UserWallet::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]);
- } else {
- $period = Period::instance();
- $field = 'CASH';
- if ($userWallet[$field]<=0) return;
- $flowInsertData = [
- 'USER_ID' => $userId,
- 'CALC_ID' => $params['CALC_ID'] ?? null,
- 'AMOUNT' => -$userWallet[$field],
- 'TOTAL' => 0,
- 'IS_INCR' => FlowWallet::INCR_REDUCE,
- 'REMARK' => $params['REMARK'] ?? null,
- 'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $period->getNowPeriodNum(),
- 'CALC_MONTH' => $period->getNowYearMonth(),
- 'P_MONTH' => Date::ociToDate(),
- 'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
- 'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
- 'SORT' => $params['SORT'] ?? 0,
- 'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
- ];
- // 流水
- if (strtolower($field) == 'cash') FlowWallet::insertOne($flowInsertData);
- // 清空
- $userWallet->CASH = 0;
- if (!$userWallet->save()) {
- throw new Exception(Form::formatErrorsForApi($userWallet->getErrors()));
- }
- }
- FlowWallet::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
- }
- /**
- * 是否存在现金余额
- * @param $userId
- * @return bool
- */
- public static function hasCash($userId) {
- $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
- if (!$userWallet) {
- return false;
- }
- if (isset($userWallet['CASH']) && $userWallet['CASH'] > 0) {
- return true;
- }
- }
- /**
- * 获取金额用于日志
- * @param $userId
- * @return array
- */
- public static function getLogData($userId){
- $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
- $userName = Info::getUserNameByUserId($userId);
- $data = [];
- $data[$userId]['label'] = $userName.'余额';
- $data[$userId]['value'] = '奖金'.self::getAvailableBalance($userId).',现金'.$userWallet['CASH'];
- return $data;
- }
- }
|