// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\AcceptorModel; use App\Models\AccountLogModel; use App\Models\BalanceLogModel; use App\Models\MemberModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; use App\Services\WalletService; use Illuminate\Support\Facades\DB; /** * 承兑商服务管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Api */ class AcceptorService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * MerchantService constructor. */ public function __construct() { $this->model = new AcceptorModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * 获取缓存列表 * @param $position * @param int $num * @return array|mixed */ public function getDataList($params, $pageSize = 15, $refresh = false, $field = '') { $page = request()->post('page', 1); $cacheKey = "caches:acceptor:page_{$page}_" . md5(json_encode($params) . $pageSize); $datas = RedisService::get($cacheKey); $data = isset($datas['data']) ? $datas['data'] : []; if ($datas && $data && !$refresh) { return [ 'list' => $data, 'total' => isset($datas['total']) ? $datas['total'] : 0, 'pageSize' => $pageSize ]; } $field = $field ? $field : 'lev_a.*,b.nickname,b.username,b.avatar'; $order = 'lev_a.id desc'; $datas = $this->model->from('acceptor as a') ->leftJoin('member as b', 'b.id', '=', 'a.user_id') ->where(['a.mark' => 1, 'b.mark' => 1]) ->whereIn('a.trade_status', [1, 2]) ->where(function ($query) use ($params) { $kw = isset($params['kw']) ? trim($params['kw']) : ''; if ($kw) { $query->where('a.name', 'like', "%{$kw}%")->orWhere('a.business_scope', 'like', "%{$kw}%"); } }) ->where(function ($query) use ($params) { // 状态 $status = isset($params['status']) && $params['status'] >= 0 ? intval($params['status']) : 2; if ($status > 0) { $query->where('a.status', $status); } }) ->selectRaw($field) ->orderByRaw($order) ->paginate($pageSize > 0 ? $pageSize : 9999999); $datas = $datas ? $datas->toArray() : []; if ($datas) { $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); foreach ($datas['data'] as &$item) { $item['logo'] = $item['logo'] ? get_image_url($item['logo']) : ''; $item['xd_price'] = max(10000, moneyFormat($xdPrice + ($xdPrice * $item['price_float'] / 100), 2)); $item['usdt_price'] = moneyFormat(1 / $item['xd_price'], 2); } unset($item); RedisService::set($cacheKey, $datas, rand(3, 5)); } return [ 'list' => isset($datas['data']) ? $datas['data'] : [], 'total' => isset($datas['total']) ? $datas['total'] : 0, 'pageSize' => $pageSize ]; } /** * 获取缓存信息 * @param $where * @param array $field * @param int $expired * @return array|mixed */ public function getCacheInfo($where, $field = [], $expired = 0) { $cacheKey = "caches:acceptor:info:cache_" . md5(json_encode($where, 256) . json_encode($field, 256) . $expired); $info = RedisService::get($cacheKey); if ($info) { return $info; } $defaultField = ['id', 'user_id', 'realname', 'mobile', 'quota', 'usdt', 'status']; $field = $field ? $field : $defaultField; $info = $this->model->where($where)->where('mark', 1)->select($field)->first(); $info = $info ? $info->toArray() : []; if ($info) { RedisService::set($cacheKey, $info, $expired ? $expired : rand(3, 5)); } return $info; } /** * 修改信息 * @param $userId * @param $params * @return array|false|int[] */ public function saveInfo($userId, $params) { // 验证是否入驻过和入驻状态 $info = $this->model->where(['user_id' => $userId])->select('id', 'realname', 'trade_status', 'status', 'mark')->first(); $tradeStatus = isset($info['trade_status']) ? $info['trade_status'] : 0; $mark = isset($info['mark']) ? $info['mark'] : 0; $id = isset($info['id']) ? $info['id'] : 0; if ($userId && empty($info)) { $this->error = 2216; return false; } // 是否被冻结 if ($id && $tradeStatus == 4 && $mark) { $this->error = 2202; return false; } // 验证账户是否正常 $userInfo = MemberService::make()->getCacheInfo(['id' => $userId], ['id', 'status']); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; if (empty($userInfo) || $status != 1) { $this->error = 2017; return false; } // 入驻数据 $data = [ 'realname' => isset($params['realname']) ? $params['realname'] : '', 'user_id' => $userId, 'mobile' => isset($params['mobile']) ? $params['mobile'] : '', 'telegram' => isset($params['telegram']) ? $params['telegram'] : '', 'price_float' => isset($params['price_float']) ? $params['price_float'] : '', 'create_time' => time(), 'update_time' => time(), 'mark' => 1, ]; // 写入数据 if ($id) { if ($this->model->where(['id' => $id])->update($data)) { $this->error = 2228; RedisService::keyDel("caches:acceptor:info:temp_{$userId}*"); return ['id' => $id]; } else { $this->error = 2229; return false; } } else { if ($merchId = $this->model->insertGetId($data)) { $this->error = 2228; RedisService::keyDel("caches:acceptor:info:temp_{$userId}*"); return ['id' => $id]; } else { $this->error = 2229; return false; } } } /** * 申请入驻 * @param $userId * @param $params * @return array|false|int[] */ public function apply($userId, $params) { // 验证是否入驻过和入驻状态 $info = $this->model->where(['user_id' => $userId])->select('id', 'name', 'trade_status', 'status', 'mark')->first(); $status = isset($info['status']) ? $info['status'] : 0; $tradeStatus = isset($info['trade_status']) ? $info['trade_status'] : 0; $mark = isset($info['mark']) ? $info['mark'] : 0; $id = isset($info['id']) ? $info['id'] : 0; if ($id && $status == 2 && $mark) { $this->error = 2201; return false; } // 是否被冻结 if ($id && $tradeStatus == 4 && $mark) { $this->error = 2202; return false; } // 验证账户是否正常 $userInfo = MemberService::make()->getCacheInfo(['id' => $userId], ['id', 'status']); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; if (empty($userInfo) || $status != 1) { $this->error = 2017; return false; } // 入驻数据 // 入驻数据 $data = [ 'realname' => isset($params['realname']) ? $params['realname'] : '', 'user_id' => $userId, 'mobile' => isset($params['mobile']) ? $params['mobile'] : '', 'telegram' => isset($params['telegram']) ? $params['telegram'] : '', 'price_float' => isset($params['price_float']) ? $params['price_float'] : '', 'create_time' => time(), 'update_time' => time(), 'quota' => 0, 'trade_status' => 1, 'status' => 1, 'mark' => 1, ]; // 写入数据 if ($id) { if ($this->model->where(['id' => $id])->update($data)) { $this->error = 2213; return ['id' => $id]; } else { $this->error = 2214; return false; } } else { if ($id = $this->model->insertGetId($data)) { $this->error = 2215; return ['id' => $id]; } else { $this->error = 2214; return false; } } } /** * 获取入驻信息 * @param $userId * @return mixed */ public function getApplyInfo($userId) { $info = $this->model->where(['user_id' => $userId, 'mark' => 1]) ->orderBy('id', 'desc') ->first(); $info = $info ? $info->setHidden(['quota', 'update_time', 'mark'])->toArray() : []; return $info; } /** * 充值交易额度 * @param $userId 用户ID * @param $params * @return array|false */ public function rechargeQuota($userId, $params) { // $acceptId = isset($params['id'])? $params['id'] : 0; $usdt = isset($params['usdt']) ? floatval($params['usdt']) : 0; if ($usdt <= 0) { $this->error = 2031; return false; } $info = $this->model->with(['member'])->where(['user_id' => $userId, 'mark' => 1]) ->select(['id', 'realname', 'mobile', 'usdt', 'quota', 'trade_status', 'status']) ->first(); $quota = isset($info['quota']) ? $info['quota'] : 0; $status = isset($info['status']) ? $info['status'] : 0; $acceptId = isset($info['id']) ? $info['id'] : 0; $userInfo = isset($info['member']) ? $info['member'] : []; if ($userId <= 0 || empty($info) || $status != 2) { $this->error = 2015; return false; } // 充值订单 DB::beginTransaction(); $orderNo = get_order_num('DP'); $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $xdPrice = $xdPrice > 0 && $xdPrice <= 10000 ? $xdPrice : 100; $money = round($xdPrice * $usdt, 2); $data = [ 'order_no' => $orderNo, 'user_id' => $acceptId, 'type' => 1, 'user_type' => 3, 'coin_type' => 6, 'money' => $usdt, 'actual_money' => $money, 'pay_type' => 10, 'pay_status' => 20, 'trc_url' => isset($userInfo['trc_url']) ? $userInfo['trc_url'] : '', 'pay_at' => date('Y-m-d H:i:s'), 'date' => date('Y-m-d'), 'create_time' => time(), 'update_time' => time(), 'status' => 2, 'mark' => 1, ]; if (!$orderId = BalanceLogModel::insertGetId($data)) { $this->error = 2033; DB::rollBack(); return false; } // 扣除usdt余额 $updateData = ['usdt' => DB::raw("usdt - {$usdt}"), 'update_time' => time()]; if (!MemberModel::where(['id' => $userId])->update($updateData)) { $this->error = 2036; DB::rollBack(); return false; } // 用户明细 $userUsdt = isset($userInfo['usdt']) ? $userInfo['usdt'] : 0; $log = [ 'user_id' => $userId, 'source_id' => $acceptId, 'source_order_no' => $data['order_no'], 'user_type' => 1, 'type' => 5, 'coin_type' => 1, 'money' => -$usdt, 'actual_money' => -$usdt, 'balance' => $usdt, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易额度充值扣除', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } // 额度增加 $updateData = ['quota' => DB::raw("quota + {$money}"), 'update_time' => time()]; if (!$this->model->where(['id' => $userId])->update($updateData)) { $this->error = 2036; DB::rollBack(); return false; } // 额度明细 $log = [ 'user_id' => $acceptId, 'source_id' => $userId, 'source_order_no' => $data['order_no'], 'user_type' => 3, 'type' => 5, 'coin_type' => 6, 'money' => $money, 'actual_money' => $money, 'balance' => $quota, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易额度充值', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } // 消息 $dateTime = date('Y-m-d H:i:s'); MessageService::make()->pushMessage($userId, '交易额度充值成功', "您在{$dateTime}(UTC+8)成功支付{$usdt}USDT充值{$money}交易额度", 3); DB::commit(); $this->error = 2037; return ['order_id' => $orderId, 'quota' => moneyFormat($quota + $money, 2), 'usdt' => moneyFormat($userUsdt - $usdt, 2)]; } /** * 交易额度提现处理 * @param $userId 用户 * @param $params * @return bool */ public function withdrawQuota($userId, $params) { $money = isset($params['money']) ? $params['money'] : 0; $coinType = isset($params['coin_type']) ? $params['coin_type'] : 0; if ($money <= 0) { $this->error = 2039; return false; } $info = $this->model->with(['member'])->where(['user_id' => $userId, 'mark' => 1]) ->select(['id', 'user_id', 'realname', 'mobile', 'usdt', 'quota', 'status']) ->first(); $usdt = isset($info['usdt']) ? floatval($info['usdt']) : 0; $quota = isset($info['quota']) ? floatval($info['quota']) : 0; $status = isset($info['status']) ? $info['status'] : 0; $tradeStatus = isset($info['trade_status']) ? $info['trade_status'] : 0; $acceptId = isset($info['accept_id']) ? $info['accept_id'] : 0; $userInfo = isset($info['member']) ? $info['member'] : []; if ($acceptId <= 0 || empty($info) || $status != 2) { $this->error = 2039; return false; } if (in_array($tradeStatus,[2,4])) { $this->error = 2015; return false; } // 提现账户 $trcUrl = isset($userInfo['trc_url']) ? $userInfo['trc_url'] : ''; if (empty($trcUrl)) { $this->error = 2403; return false; } DB::beginTransaction(); // USDT 提现 $payUsdt = 0; $orderNo = get_order_num('DP'); if ($coinType == 1) { $payUsdt = $money; if ($money > $usdt) { $this->error = lang(2040, ['money' => $usdt]); return false; } $updateData = ['usdt' => DB::raw("usdt - {$money}"), 'update_time' => time()]; if (!$this->model->where(['id' => $acceptId])->update($updateData)) { DB::rollBack(); $this->error = 2042; return false; } // 明细 $log = [ 'user_id' => $acceptId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'user_type' => 3, 'type' => 5, 'coin_type' => 1, 'money' => -$usdt, 'actual_money' => -$usdt, 'balance' => $usdt, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易余额提现', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } } // 额度提现 else if ($coinType == 6) { // 时间限制 $limitTime = ConfigService::make()->getConfigByCode('quota_withdraw_time'); $limitTime = $limitTime >= 0 ? $limitTime : 0; $lockQuota = BalanceLogModel::where(['user_id' => $acceptId, 'user_type' => 3, 'coin_type' => 6, 'status' => 1, 'mark' => 1]) ->where('pay_at', '>=', date('Y-m-d H:i:s', time() - $limitTime * 86400)) ->sum('actual_money'); if ($lockQuota > 0 && $money > ($quota - $lockQuota)) { $this->error = lang(2040, ['money' => ($quota - $lockQuota)]); return false; } $xdPrice = ConfigService::make()->getConfigByCode('xd_price', 100); $xdPrice = $xdPrice > 0 && $xdPrice <= 10000 ? $xdPrice : 100; $payUsdt = round($money / $xdPrice, 4); $updateData = ['quota' => DB::raw("quota - {$money}"), 'update_time' => time()]; if (!$this->model->where(['id' => $acceptId])->update($updateData)) { DB::rollBack(); $this->error = 2042; return false; } // 明细 $log = [ 'user_id' => $acceptId, 'source_id' => $userId, 'source_order_no' => $orderNo, 'user_type' => 3, 'type' => 5, 'coin_type' => 6, 'money' => -$money, 'actual_money' => -$money, 'balance' => $quota, 'date' => date('Y-m-d'), 'create_time' => time(), 'remark' => '交易额度提现', 'status' => 1, 'mark' => 1 ]; if (!AccountLogModel::insertGetId($log)) { $this->error = 2029; DB::rollBack(); return false; } } // 提现记录 $data = [ 'order_no' => $orderNo, 'user_id' => $acceptId, 'type' => 2, 'coin_type' => $coinType, 'user_type' => 3, 'money' => $money, 'actual_money' => $payUsdt, 'balance' => $coinType == 1 ? $usdt : $quota, 'date' => date('Y-m-d'), 'trc_url' => $trcUrl, 'create_time' => time(), 'update_time' => time(), 'status' => 1, 'mark' => 1, ]; if (!$id = BalanceLogModel::insertGetId($data)) { DB::rollBack(); $this->error = 2042; return false; } DB::commit(); // 站内消息 $dateTime = date('Y-m-d H:i:s'); $message = $coinType == 1 ? "您在{$dateTime}(UTC+8)申请提现{$money}USDT交易余额成功,请耐心等候审核!!!" : "您在{$dateTime}(UTC+8)申请提现{$money}交易额度成功,请耐心等候审核!!!"; MessageService::make()->pushMessage($userId, $coinType == 1 ? '交易余额提现申请成功' : '交易额度提现申请成功', $message); // 提现自动审核,低于该金额自动审核 $autoCheckUsdt = ConfigService::make()->getConfigByCode('withdraw_auto_money', 300); $autoCheckUsdt = $autoCheckUsdt > 0 ? $autoCheckUsdt : 0; if ($payUsdt <= $autoCheckUsdt) { // 打款处理 $result = WalletService::make()->usdtTrcTransfer($trcUrl, $payUsdt); $txID = isset($result['txId']) ? $result['txId'] : ''; $payAddress = isset($result['address']) ? $result['address'] : ''; if ($txID && $payAddress) { $updateData = ['hash'=> $txID,'wallet_url'=> $payAddress,'audit_remark'=>'自动审核打款','status'=>2,'update_time'=>time()]; if(BalanceLogModel::where(['user_id'=> $acceptId,'order_no'=> $orderNo])->update($updateData)){ $message = $coinType == 1 ? "您在{$dateTime}(UTC+8)申请提现{$money}USDT交易余额审核成功,请耐心等候打款到账!!!" : "您在{$dateTime}(UTC+8)申请提现{$money}交易额度审核成功,请耐心等候打款到账!!!"; MessageService::make()->pushMessage($userId, $coinType == 1 ? '交易余额提现审核成功' : '交易额度提现审核成功', $message); AccountLogModel::where(['source_order_no'=> $orderNo])->update(['hash'=> $txID,'update_time'=>time()]); } } } $this->error = 2043; return true; } }