// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Helpers\Jwt; use App\Models\ActionLogModel; use App\Models\MemberModel; use App\Services\BaseService; use App\Services\Common\MemberSettingService; use App\Services\ConfigService; use App\Services\RedisService; use App\Services\UsdtWalletService; use Illuminate\Support\Facades\DB; use phpQrcode\QRcode; /** * 会员-服务类 * Class MemberService * @package App\Services\Api */ class MemberService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @since 2020/11/10 * LoginService constructor. */ public function __construct() { $this->model = new MemberModel(); } /** * 静态入口 * @return static|null */ public static function make() { if (!self::$instance) { self::$instance = (new static()); } return self::$instance; } /** * 获取资料详情 * @param $where * @param array $field */ public function getInfo($where, array $field = []) { $field = $field ? $field : ['id', 'username', 'realname', 'nickname', 'openid', 'idcard', 'trc_address', 'erc_address', 'source', 'idcard_check', 'idcard_front_img', 'idcard_back_img', 'safe_level', 'user_type', 'member_level', 'usdt_num', 'user_type', 'status', 'credit', 'avatar']; if (is_array($where)) { $info = $this->model->where($where)->select($field)->first(); } else { $info = $this->model->where(['id' => (int)$where])->select($field)->first(); } $info = $info ? $info->toArray() : []; if ($info) { $tradePrice = ConfigService::make()->getConfigByCode('usdt_sell_price'); $tradePrice = $tradePrice? $tradePrice : 0; $info['avatar'] = $info['avatar'] ? get_image_url($info['avatar']) : ''; $info['idcard_front_img'] = $info['idcard_front_img'] ? get_image_url($info['idcard_front_img']) : ''; $info['idcard_back_img'] = $info['idcard_back_img'] ? get_image_url($info['idcard_back_img']) : ''; $info['usdt_num'] = isset($info['usdt_num']) ? moneyFormat($info['usdt_num'], 4) : '0.0000'; $info['cny_num'] = $info['usdt_num'] && $tradePrice>0? moneyFormat($info['usdt_num']*$tradePrice, 6) : '0.0000'; $info['is_collection'] = MemberPaymentService::make()->checkHasByUser($info['id']); // 收款二维码 $qrcode = $this->makeQrcode($info['trc_address']); $info['trc_qrcode'] = $qrcode? get_image_url($qrcode) : ''; $ercQrcode = $this->makeQrcode($info['erc_address']); $info['erc_qrcode'] = $ercQrcode? get_image_url($ercQrcode) : ''; } return $info; } /** * 用户注册 * @param $params * @return bool */ public function register($params) { // 检测账号是否存在 if ($this->checkExists('username', $params['username'])) { $this->error = '2005'; return false; } $username = isset($params['username']) ? trim($params['username']) : ''; $password = isset($params['password']) ? trim($params['password']) : '123456'; $avatar = isset($params['avatar']) ? trim($params['avatar']) : ''; $data = [ 'username' => $username, 'password' => get_password($password . $username), 'mobile' => isPhone($username) ? $username : '', 'avatar' => $avatar ? $avatar : '', 'status' => 1, 'mark' => 1, 'create_time' => time(), ]; // 生成trc2.0钱包地址 $trcAddress = UsdtWalletService::make()->getTrxAddress(); if ($trcAddress) { $data['trc_wif'] = isset($trcAddress['wif']) ? $trcAddress['wif'] : ''; $data['trc_hexaddress'] = isset($trcAddress['hexAddress']) ? $trcAddress['hexAddress'] : ''; $data['trc_address'] = isset($trcAddress['address']) ? $trcAddress['address'] : ''; } else { $this->error = 2201; return false; } // 生erc2.0钱包地址 $ercAddress = UsdtWalletService::make()->getErcAddress(); if ($trcAddress) { $data['erc_wif'] = isset($ercAddress['wif']) ? $ercAddress['wif'] : ''; $data['erc_hexaddress'] = isset($ercAddress['hexAddress']) ? $ercAddress['hexAddress'] : ''; $data['erc_address'] = isset($ercAddress['address']) ? $ercAddress['address'] : ''; } else { $this->error = 2202; return false; } if ($id = $this->model->edit($data)) { MemberSettingService::make()->getInfo($id); return true; } $this->error = 2007; return false; } /** * 用户登录 * @param $params * @return array|false */ public function login($params) { $username = isset($params['username']) ? $params['username'] : ''; $password = isset($params['password']) ? $params['password'] : ''; if (empty($username) || empty($password)) { $this->error = 1013; return false; } // 用户验证 $info = $this->model->getOne([['username', '=', $username]]); if (!$info) { $this->error = 2001; return false; } // 密码校验 $password = get_password($password . $username); if ($password != $info['password']) { $this->error = 2002; return false; } // 使用状态校验 if ($info['status'] != 1) { $this->error = 2009; return false; } // 设置日志标题 ActionLogModel::setTitle("会员登录APP"); ActionLogModel::record($info); // JWT生成token $jwt = new Jwt('jwt_app'); $token = $jwt->getToken($info['id']); RedisService::set("stores:auths:info:{$info['id']}", $info, 5, 10); // 登录数据 return [ 'token' => $token, 'user_id' => $info['id'], 'user_type' => $info['user_type'], ]; } /** * 身份认证 * @param $userId * @param $params * @return false */ public function auth($userId, $params) { $data = [ 'idcard' => isset($params['idcard']) ? $params['idcard'] : '', 'realname' => isset($params['realname']) ? $params['realname'] : '', ]; if (isset($params['idcard_front_img']) && strpos($params['idcard_front_img'], 'http') === false) { $data['idcard_front_img'] = $params['idcard_front_img']; } if (isset($params['idcard_back_img']) && strpos($params['idcard_back_img'], 'http') === false) { $data['idcard_back_img'] = $params['idcard_back_img']; } $info = $this->getInfo($userId); $idcardCheck = isset($info['idcard_check']) ? $info['idcard_check'] : 0; if ($idcardCheck == 1) { $this->error = '2011'; return false; } return $this->model->where(['id' => $userId])->update($data); } /** * 获取钱包地址密钥参数 * @param $address * @param string $type 链类型:trc-trc2.0,erc * @return mixed */ public function getWallet($address, $type = 'trc') { return $this->model->where([$type . '_address' => $address])->select(['id', $type . '_address', $type . '_hexaddress', $type . '_wif'])->first(); } /** * 获取待处理用户数据 * @param int $page * @param int $pageSize * @return array|mixed */ public function getCatchMember($page = 1, $pageSize = 500) { $cacheKey = "caches:wallet:members:{$page}_{$pageSize}"; $datas = RedisService::get($cacheKey); if ($datas) { return $datas; } $datas = $this->model->where(['mark' => 1]) ->select(['id', 'trc_address', 'usdt_num']) ->paginate($pageSize > 0 ? $pageSize : 9999999); $datas = $datas ? $datas->toArray() : []; $datas = isset($datas['data']) ? $datas['data'] : []; if ($datas) { RedisService::set($cacheKey, $datas, rand(120, 600)); } return $datas; } /** * 匹配承兑商 * @param $num 交易数量 * @param int $tradeType 交易类型:1-购买,2-出售 */ public function getTradeMember($num, $tradeType = 1, $userId=0) { $data = $this->model->from('member as m') ->leftJoin('member_setting as ms', 'ms.user_id', '=', 'm.id') ->where(['m.status' => 1,'m.user_type'=>2, 'm.mark' => 1]) ->where('m.usdt_num', '>=', $num) ->where(function($query)use($userId){ if($userId){ $query->whereNotIn('m.id', [$userId]); } }) ->where(function ($query) use ($tradeType) { $time = time(); // 买单 if ($tradeType == 1) { $query->whereRaw("(buy_online = 1 and buy_online_time>{$time}) or buy_online is null"); } // 卖单 else { $query->whereRaw("((sell_online = 1 and sell_online_time>{$time}) or sell_online is null) and day_sell_quota > day_sell_total"); } }) ->select(['m.id','m.usdt_num','m.username','m.credit']) ->orderBy("credit",'desc') ->orderBy(DB::raw("rand()")) ->first(); $data = $data? $data->toArray() : []; return $data; } /** * 生成普通参数二维码 * @param $str 参数 * @param bool $refresh 是否重新生成 * @return bool */ public function makeQrcode($str, $refresh = false, $size = 4, $margin=2, $level=2) { $qrFile = '/images/qrcode/'; if (!is_dir('/uploads'.$qrFile)) { @mkdir('./uploads' . $qrFile, 0755, true); } $qrFile = $qrFile . 'C_' . strtoupper(md5($str . '_' . $size.$margin.$level)) . '.png'; $cacheKey = "caches:qrcodes:member_".md5($str); if(RedisService::get($cacheKey) && is_file('/uploads'.$qrFile) && !$refresh){ //return $qrFile; } QRcode::png($str, './uploads' . $qrFile, $level, $size, $margin); if(!file_exists('./uploads'.$qrFile)){ return false; } RedisService::set($cacheKey, ['str'=> $str, 'qrcode'=> $qrFile,'date'=> date('Y-m-d H:i:s')], 7*24 * 3600); return $qrFile; } /** * 获取钱包归集用户列表 * @param float $minUsdt * @param int $page * @param int $pageSize * @return array|mixed */ public function getTriggerAddressList($minUsdt=0.2, $page=1, $pageSize = 200) { $cacheKey = "caches:wallet:triggers:{$page}_{$pageSize}"; $datas = RedisService::get($cacheKey); if ($datas) { return $datas; } $datas = $this->model->where(['mark'=>1]) ->where('trc_usdt','>=', $minUsdt) ->select(['id','trc_usdt','trc_address','trc_wif','trc_hexaddress','erc_address','erc_wif','erc_hexaddress']) ->orderBy('trc_usdt') ->paginate($pageSize > 0 ? $pageSize : 9999999); $datas = $datas ? $datas->toArray() : []; $datas = isset($datas['data']) ? $datas['data'] : []; if ($datas) { RedisService::set($cacheKey, $datas, rand(10, 30)); } return $datas; } }