// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AccountLogModel; use App\Models\ActionLogModel; use App\Models\BalanceLogModel; use App\Models\MemberBankModel; use App\Models\MemberModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use Illuminate\Support\Facades\DB; /** * 余额管理-服务类 * @author laravel开发员 * @since 2020/11/11 */ class BalanceLogService extends BaseService { public static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * AccountService constructor. */ public function __construct() { $this->model = new BalanceLogModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * @param $params * @param int $pageSize * @return array */ public function getDataList($params, $pageSize = 15) { $query = $this->getQuery($params); $list = $query->select(['a.*']) ->orderBy('a.status', 'asc') ->orderBy('a.create_time', 'desc') ->orderBy('a.id', 'desc') ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list ? $list->toArray() : []; if ($list) { foreach ($list['data'] as &$item) { $item['create_time'] = $item['create_time'] ? datetime($item['create_time'], 'Y-m-d H:i:s') : ''; $item['time_text'] = $item['create_time'] ? datetime($item['create_time'], 'Y年m月d日') : ''; } } return [ 'pageSize' => $pageSize, 'total' => isset($list['total']) ? $list['total'] : 0, 'list' => isset($list['data']) ? $list['data'] : [] ]; } public function getQuery($params) { $where = ['a.mark' => 1]; $status = isset($params['status']) ? $params['status'] : 0; $type = isset($params['type']) ? $params['type'] : 0; if ($status > 0) { $where['a.status'] = $status; } if ($type > 0) { $where['a.type'] = $type; } return $this->model->with(['member'])->from("balance_logs as a") ->leftJoin('member as b', 'b.id', '=', 'a.user_id') ->where($where) ->where(function ($query) use ($params) { $keyword = isset($params['keyword']) ? $params['keyword'] : ''; $userId = isset($params['user_id']) ? $params['user_id'] : 0; if ($userId) { $query->where('a.user_id', $userId); } if ($keyword) { $query->where(function ($query) use ($keyword) { $query->where('b.nickname', 'like', "%{$keyword}%") ->orWhere('b.mobile', 'like', "%{$keyword}%") ->orWhere('b.realname', 'like', "%{$keyword}%"); }); } $orderNo = isset($params['order_no']) ? trim($params['order_no']) : ''; if ($orderNo) { $query->where(function ($query) use ($orderNo) { $query->where('a.order_no', 'like', "%{$orderNo}%"); }); } $account = isset($params['account']) ? trim($params['account']) : ''; if ($account) { $query->where(function ($query) use ($account) { $query->where('a.account', 'like', "%{$account}%"); }); } }) ->where(function ($query) use ($params) { // 日期 $date = isset($params['date']) ? $params['date'] : []; $start = isset($date[0]) ? $date[0] : ''; $end = isset($date[1]) ? $date[1] : ''; $end = $start >= $end ? '' : $end; if ($start) { $query->where('a.create_time', '>=', strtotime($start)); } if ($end) { $query->where('a.create_time', '<=', strtotime($end)); } }); } /** * 收入提现 * @param $userId * @param $params * @return array|false */ public function withdraw($userId, $params) { // 参数验证 $payType = isset($params['pay_type']) && $params['pay_type'] ? intval($params['pay_type']) : 10; $accountType = isset($params['type']) && $params['type'] ? intval($params['type']) : 1; $money = isset($params['money']) ? floatval($params['money']) : 0; $accountId = isset($params['account_id']) ? intval($params['account_id']) : 0; if ($money <= 0) { $this->error = '请输入提现金额'; return false; } if ($payType != 10 && $accountId <= 0) { $this->error = '请选择收款账户'; return false; } $openWithdraw = ConfigService::make()->getConfigByCode("withdraw_{$accountType}_open", 1); if (!$openWithdraw) { $this->error = 2304; return false; } $withdrawMin = ConfigService::make()->getConfigByCode("withdraw_min", 0.1); if ($withdrawMin > 0 && $money < $withdrawMin) { $this->error = lang(2305, ['money' => $withdrawMin]); return false; } // 锁 $cacheLockKey = "caches:members:withdraw:{$userId}"; if (RedisService::get($cacheLockKey)) { $this->error = 1034; return false; } if($accountId){ $accountInfo = MemberBankModel::where(['id' => $accountId, 'user_id' => $userId, 'mark' => 1])->first(); $realname = isset($accountInfo['realname']) ? $accountInfo['realname'] : ''; $account = isset($accountInfo['account']) ? $accountInfo['account'] : ''; $accountName = isset($accountInfo['account_name']) ? $accountInfo['account_name'] : ''; $accountRemark = isset($accountInfo['account_remark']) ? $accountInfo['account_remark'] : ''; if (empty($accountInfo) || empty($realname) || empty($accountName) || empty($account)) { $this->error = '抱歉,当前收款账户错误请更换后重试'; return false; } }else{ $accountName = '微信支付'; $account = '微信零钱'; $accountRemark = ''; } // 判断用户账号状态 $fields = [1=>'balance',2=>'property',4=>'ls_score']; $field = isset($fields[$accountType])? $fields[$accountType]:'balance'; RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(10, 20)); $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1])->select(['id', 'balance','property','bd_score','ls_score', 'status'])->first(); $realname = isset($userInfo['realname']) ? $userInfo['realname'] : ''; $status = isset($userInfo['status']) ? $userInfo['status'] : 0; $balance = isset($userInfo[$field]) ? $userInfo[$field] : 0; if (empty($userInfo) || $status != 1) { $this->error = 2016; RedisService::clear($cacheLockKey); return false; } if ($money > $balance) { $this->error = '该账户可提现余额不足'; RedisService::clear($cacheLockKey); return false; } // 计算实际到账金额 $poolMoney = 0; $ptMoney = 0; $ptRate = 0; $poolRate = 0; $total = $money; $actualMoney = $money; if($accountType==2){ // 提现金额 $price = PriceService::make()->getTodayPrice(1); if($price<=0){ $this->error = '请等候今日资产价格刷新后重试~'; RedisService::clear($cacheLockKey); return false; } $rate = ConfigService::make()->getConfigByCode('withdraw_2_rate',0); $rate = $rate>0 && $rate<=100? $rate : 100; $total = moneyFormat($total * $price,2); $actualMoney = moneyFormat($total * $rate/100, 2); // 结算比例 $rate = ConfigService::make()->getConfigByCode('withdraw_2_rate',0); $rate = $rate>0 && $rate<=100? $rate : 100; $actualMoney = moneyFormat($actualMoney * $rate/100, 2); // 底池比例 $poolRate = ConfigService::make()->getConfigByCode('withdraw_2_back_rate',0); $poolRate = $poolRate>0 && $poolRate<50? $poolRate : 0; $poolMoney = round($total * $poolRate/100, 2); // 运营账户比例 $ptRate = ConfigService::make()->getConfigByCode('withdraw_2_pt_rate',0); $ptRate = $ptRate>0 && $ptRate<=50? $ptRate : 0; $ptMoney = round($total * $ptRate/100, 2); } // 手续费 $feeRate = ConfigService::make()->getConfigByCode("withdraw_{$accountType}_fee",0); $feeRate = $feeRate>0 && $feeRate<=50? $feeRate : 0; $fee = round($actualMoney * $feeRate/100, 2); $actualMoney = moneyFormat($actualMoney - $fee, 2); $accountTypeName = ['账户','收益余额','数字资产','报单积分','绿色积分'][$accountType]; $accountTypeName = $accountTypeName?$accountTypeName:'账户'; // 提现处理 DB::beginTransaction(); $updateData = ["{$field}" => DB::raw("{$field} - {$money}"), 'update_time' => time()]; // 会员账户 if (!MemberModel::where(['id' => $userId])->update($updateData)) { DB::rollBack(); $this->error = '提现处理失败'; RedisService::clear($cacheLockKey); return false; } $orderNo = get_order_num('JW'); $order = [ 'user_id' => $userId, 'order_no' => $orderNo, 'money' => $money, 'total' => $total, 'after_money' => moneyFormat(max(0, $balance - $money), 2), 'actual_money' => $actualMoney, 'fee' => $fee, 'pool_money' => $poolMoney, 'pool_rate' => $poolRate, 'pt_money' => $ptMoney, 'pt_rate' => $ptRate, 'user_type' => 1, 'type' => 2, 'account_type' => $accountType, 'pay_type' => $payType, 'realname' => $realname, 'account_name' => $accountName, 'account' => $account, 'account_remark' => $accountRemark, 'date' => date('Y-m-d'), 'create_time' => time(), 'status' => 1, 'mark' => 1 ]; if (!$orderId = $this->model::insertGetId($order)) { DB::rollBack(); $this->error = '提现处理失败'; RedisService::clear($cacheLockKey); return false; } $log = [ 'user_id' => $userId, 'source_order_no' => $orderNo, 'type' => 4, 'money' => -$money, 'after_money' => moneyFormat(max(0, $balance - $money), 2), 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => "提现到{$account}", 'status' => 1, 'mark' => 1, ]; if (!$accountId = AccountLogModel::insertGetId($log)) { DB::rollBack(); $this->error = '提现处理失败'; RedisService::clear($cacheLockKey); return false; } DB::commit(); // 操作日志 ActionLogModel::setRecord($userId, ['type' => 2, 'title' => "{$accountTypeName}提现", 'content' => "姓名:{$realname},账号:{$accountName}/{$account}/{$accountRemark},提现{$money}元,单号:{$orderNo}", 'module' => 'balanceLog']); ActionLogModel::record(); RedisService::clear($cacheLockKey); $this->error = '提现申请成功,请耐心等候审核~'; return ['id' => $orderId, 'aid' => $accountId, 'money' => $money]; } }